▼ 2008/09/19(金) ono_matope 氏の Twitter_reply_notifier が動かなくなっていたのを修正してあるので公開。
2008/9/19 Twitter デザインに変更に対応して更新
2008/10/16 Twitter デザインに変更に対応して更新
Twitter_reply_notifier
小野マトペ氏が作った Twitter_reply_notifier が随分前の 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\">([\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
});
}) ();
動かないよー!ってなってる人は是非。▼ コメント(0件)
- TB-URL http://worstman.net/blog/0127/tb/


