ようこそお客さん

worstman.net/Blog


次の記事   前の記事

2008/09/19(金) ono_matope 氏の Twitter_reply_notifier が動かなくなっていたのを修正してあるので公開。

Twitter::戯言 最低人間 はてなブックマーク数
2008/11/22 Twitter デザインに変更に対応して更新
2008/9/19 Twitter デザインに変更に対応して更新
2008/10/16 Twitter デザインに変更に対応して更新

Twitter_reply_notifier

小野マトペ氏が作った Twitter_reply_notifier が随分前の Twitter デザイン変更により動かなくなったのですが、自前で対応。んで今日ふと小野マトペ氏のサイトを見たら未だに更新されていない状態なので、勝手ながら公開しておくことにします。
// ==UserScript==
// @name           twitter_reply_notifier
// @namespace      d.hatena.ne.jp/ono_matope/
// @include        http://twitter.com/home
//version 2.0.1
// ==/UserScript==


( function(){
	function Message(){
		this.id;
		this.name;
		this.desc;
		this.time;
		this.fromReplies=false;
		this.fromTwitterSearch=false;
	}
	var messageArray=new Array();
	var progress = 0;
	
	function getElementByClassName(par,class,number){
			var nodes = par.childNodes;
			var nodeCount=0;
			var target = null;
			for(var i in nodes){
				if(nodes[i].className==class){
					nodeCount++;
					if(nodeCount==number){
						target=nodes[i];
						break;
					}
				}
			}
			return target;
	}
	
		
	function build(){
		var nextNode= getElementByClassName(side,'section',1);
		var feedReader=document.createElement('div');
		var more=document.createElement('P');
		messageArray.sort(function(a,b){return parseInt(b.time.getTime())-parseInt(a.time.getTime());});

		feedReader.className='section';
		feedReader.id='twitter_reply_notifier';

		var html="";
		html+='<div class="section-header"><a class="section-links" href="http://twitter.1x1.jp/search/?keyword=%40'+username+'&lang=&text=1">Twitter \u691C\u7D22</a><h1>Replies to you</h1></div>';
		html+='<span id="replies"><DL>';
		
		for(i=0;i<Math.min(messageArray.length,5);i++){
				var m=messageArray[i];
				m.desc=m.desc.substr(username.length+1);
				if(m.desc.length>13)
					m.desc=m.desc.substr(0,13)+'...';
				var isNew=new Array();
				
				if(hStatus[username+'-'+m.id]==undefined){
					isNew[i]=true;
					hStatus[username+'-'+m.id]=1;
				}else{
					isNew[i]=false;
					hStatus[username+'-'+m.id]=2;
				}
				
				html+='<DT><a href="http://twitter.com/'+m.name+'/statuses/'+m.id+'">@'+m.name+'</a></DT>';
				if(isNew[i]){
					if(m.fromTwitterSearch && !m.fromReplies)
						html+='<DD><span style="color:orange;font-weight:bold;">'+m.desc+'</span></DD>';
					else
						html+='<DD><span style="color:red;font-weight:bold;">'+m.desc+'</span></DD>';
				}else
					html+='<DD>'+m.desc+'</DD>';
				//html+='<DD>'+m.time.toString()+'</DD>';
			}
		html+='</DL>';
		html+= '</span>';
		feedReader.innerHTML+=html;
		side.insertBefore(feedReader,nextNode);
		
		for(i in hStatus){
			if(hStatus[i]==0 && i.indexOf(username)==0){
				delete hStatus[i];}
			}
		//save hash
		GM_setValue("hStatus", hStatus.toSource());
	}
	
	
	
	
	
	function addMessageArray(mes){
		var alreadyID=null;
		for(var i in messageArray){
			if(messageArray[i].id==mes.id){alreadyID=i;break;}
		}
		if(alreadyID==null){
			messageArray.push(mes);
		}else{
			if(mes.fromTwitterSearch==true)
				messageArray[alreadyID].fromTwitterSearch=true;
			if(mes.fromReplies==true)
				messageArray[alreadyID].fromReplies=true;
		}
	}
	
	
	
	function fromReplies(responseDetails){
		var html=responseDetails.responseText;
		var reg=/<tr\sid=\"status_(.*)\"\sclass=\"hentry\sstatus\s.*?\">([\n\r]|.)*?<strong><a.*?>(.*?)<([\n\r]|.)*?<span\sclass=\"entry-content\">[\n\r\s]*(([\n\r]|.)*?)<\/span>([\n\r]|.)*?<span\sclass=\"published\"\stitle=\"(.*?)\">([\n\r]|.)*?<\/tr>/gi;
		var regTime=/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})/;
		
		
		for(var i=0;i<10;i++){
			tr=reg.exec(html);
			if(!tr)break;
			al="status_id:"+tr[1]+"\nname:"+tr[3]+"\ndesc:"+tr[5]+"\ntime:"+tr[8];
			time=regTime(tr[8]);
			var pubTime=new Date(time[1], time[2]-1, time[3], time[4], time[5], time[6]);
			
			//add  to arrayMessage
			var mes = new Message();
			mes.id=tr[1];
			mes.name=tr[3];
			mes.desc=tr[5].replace(/<.*?>/g,'');
			
			mes.time=pubTime;
			mes.fromReplies=true;
			
			
			//alert(mes.id+"\n"+mes.desc+"\n"+pubTime.toString());
			addMessageArray(mes);
		}
		progress++;
		if(progress==2){build();}
	}
	
	
	function fromTwitterSearch(responseDetails){
			
			var html=responseDetails.responseText;
			var regItems=/<item>([\n\r]|.)*<\/item>/g;
			var regTitle=/<title>@(.*?)\s.*?<\/title>/g;
			var regDesc=/<description>(([\n\r]|.)*?)<\/description>/g;
			var regID=/<link>http:\/\/twitter\.1x1\.jp\/search\/\?id=(.*)<\/link>/g;
			var regPubDate=/<pubDate>(.*)<\/pubDate>/g;
			
			var items=regItems(html);
			for(var i=0;i<10;i++){
				var mes = new Message();
				mes.id = regID.exec(items)[1];
				mes.name = regTitle.exec(items)[1];
				mes.desc = regDesc.exec(items)[1];
				mes.time = new Date(regPubDate.exec(items)[1]);
				mes.time.setTime(mes.time.getTime()-9*60*60*1000);
				mes.fromTwitterSearch=true;
				
				addMessageArray(mes);
			}
			progress++;
			if(progress==2)
				build();
	}
	
	
	
	
	
	
	//start
	var side = document.getElementById("side");
	var navigation = document.getElementById("navigation");
	if(!side){return 0;}
	if(!navigation){return 0;}
	var links = navigation.getElementsByTagName("a");
	var username ='';
	for(var a in links){
		if(links[a].text=="Profile"){
			username=links[a].href.substr(19);
			//alert(username);
			break;
		}
	}
	
	//get hash
	var hStatus = eval("("+GM_getValue("hStatus")+")") || {};
	
	for(i in hStatus){//flag already read.
		if(hStatus[i]==2)hStatus[i]=0;
		//alert("set 0 "+i);
	}
	
	GM_xmlhttpRequest({
		method:"get",
		url:"http://twitter.com/replies",
		onload:fromReplies
	});
	
	GM_xmlhttpRequest({
		method:"get",
		url:"http://twitter.1x1.jp/rss/search/?keyword=%40"+username+"&text=1",
		onload:fromTwitterSearch
	});
}) ();
動かないよー!ってなってる人は是非。


#  非公開コメント   

  • TB-URL  http://worstman.net/blog/0127/tb/

次の記事   前の記事