Entry: ついったーのTLを60件に保つグリモンを作った
ついったーのTLを60件に保つグリモンを作った
ついったーのタイムラインが放っておくと超長くなってブラウザが重くなるので、タイムラインのサイズを一定に保つグリモンスクリプトを作った。60件より古いtweetをjQueryでremoveしている。内部的にデータがどうなってるのか分からないので効果は不明だけどDOMが減るので軽くなるだろうという憶測。
// ==UserScript== // @name tweetReduce // @namespace http://jamadam.com/ // @description Avoid Twitter Timeline size get too long // @include http://twitter.com/* // ==/UserScript== (function() { var $; var jversion = '1.2.6'; var jexist = (typeof unsafeWindow.jQuery != 'undefined'); var conflict = (jexist && unsafeWindow.jQuery.fn.jquery != jversion); // Add jQuery if not loaded if (! jexist || conflict) { var GM_JQ = document.createElement('script'); GM_JQ.src = 'http://ajax.googleapis.com/ajax/libs/jquery/' + jversion + '/jquery.js'; GM_JQ.type = 'text/javascript'; document.getElementsByTagName('body')[0].appendChild(GM_JQ); } GM_wait(); // Check if jQuery's loaded function GM_wait() { if (typeof unsafeWindow.jQuery == 'undefined' || unsafeWindow.jQuery.fn.jquery != jversion) { window.setTimeout(GM_wait,100); } else { if (conflict) { $ = unsafeWindow.jQuery.noConflict(true); } else { $ = unsafeWindow.jQuery; } letsJQuery(); } } // All your GM code must be inside this function function letsJQuery() { var topid = $('#timeline li').eq(0).attr('id'); window.setInterval(reduce, 5000); function reduce() { var newid = $('#timeline li').eq(0).attr('id'); if (topid != newid) { topid = newid; console.log($('#timeline li').length); while ($('#timeline li').length > 60) { $('#timeline li').eq(60).remove(); } } } } })();
Entry: グリモンでjQuery使ったらTwitterがバグった件が解決した
グリモンでjQuery使ったらTwitterがバグった件が解決した
Twitterの公式ページに適用するためのGreasemonkeyスクリプトにjQueryを使おうと思ったら、しばらくうまく行かなかった。原因は、TwitterページがすでにjQueryの旧バージョンをロードしていたというだけ。今回はたまたま自分のスクリプトがバージョンに依存しない内容だったので、if文でjQueryの存在確認をしてからロードすることで解決した。
(function() { // Add jQuery if not loaded if (typeof unsafeWindow.jQuery == 'undefined') { var GM_JQ = document.createElement('script'); GM_JQ.src = 'http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js'; GM_JQ.type = 'text/javascript'; document.getElementsByTagName('body')[0].appendChild(GM_JQ); } // Check if jQuery's loaded function GM_wait() { if (typeof unsafeWindow.jQuery == 'undefined') { window.setTimeout(GM_wait,100); } else { jQuery = unsafeWindow.jQuery; letsJQuery(); } } GM_wait(); // All your GM code must be inside this function function letsJQuery() { } })();
Entry: ついったらータグs API(仮)
ついったらータグs API(仮)
「ついったらータグs API(仮)」は、ついったらータグs(仮)のデータベースへの問い合わせをアプリケーションから利用するためのインターフェースを提供します。ついったらータグs(仮)のデータベースにはTwitterの各ユーザーページに対する、はてなブックマークタグの情報を格納しています。本APIを利用することで、任意のユーザーに対するタグ付けの情報はもちろんのこと、任意のタグがどのユーザーに適用されているかという情報を取得することができます。また、対象となるデータベースとして、独自のルールでタグ文字列の正規化を行ったテーブルを対象にすることもできます(任意)。
全てのAPIは下記のURLで提供されます。
http://jamadam.com/th/
現在サポートされている操作は、タグ-ユーザー検索(パラメータt=api/tag.json)とユーザー-タグ検索(パラメータt=api/user.json)です。いずれもレスポンスとしてJSONを返します。また、クエリーとしてcallbackを渡すことでJSONPを受け取ることもできます。
タグ-ユーザー検索
任意のタグ文字列を指定することで、このタグがつけられたユーザーのスクリーンネームのリストを得ます。
パラメータ
- t (必須)
"api/tag.json"を指定します。 - str (必須)
任意のタグを指定します。 - nn (オプション)
正規化されたテーブルを使用しないためのパラメータです。1を指定すると、はてなブックマークに登録された通りのタグ文字列が対象となります。デフォルトは0です。
リクエスト例
/th/?t=api/tag.json&str=it
レスポンス例
{"result":[
{"user":"takapon_jp","occurance":"2"},
{"user":"m_kumagai","occurance":"1"},
{"user":"huehara88","occurance":"1"}
]}
※実際はレスポンスに改行は含まれません。
ユーザー-タグ検索
任意のスクリーンネームを指定することで、このユーザーに付与されたタグの一覧を得ます。
パラメータ
- t (必須)
"api/user.json"を指定します。 - str (必須)
任意のスクリーンネームを指定します。 - nn (オプション)
正規化されたテーブルを使用しないためのパラメータです。1を指定すると、はてなブックマークに登録された通りのタグ文字列が対象となります。デフォルトは0です。
リクエスト例
/th/?t=api/user.json&str=jamadam
レスポンス例
{"result":[
{"tag":"twitter","occurance":"38"},
{"tag":"音楽","occurance":"9"},
{"tag":"有名人","occurance":"4"},
{"tag":"webサービス","occurance":"4"}
]}
※実際はレスポンスに改行は含まれません。
実装例
ユーザー-タグ検索を利用してタグ一覧を取得するPerlコードは以下のようになります。
use LWP::UserAgent; use JSON::XS; my $tags = _twitterer_tags('jamadam'); foreach my $entry (@$tags) { print($entry->{tag}); print(":"); print($entry->{occurance}."回"); print("¥n"); } sub _twitterer_tags { my $user = shift; my $ua = LWP::UserAgent->new; my $res = $ua->get('http://jamadam.com/th/?t=api/user.json&str='. $user); my $obj = decode_json $res->content(); return $obj->{result}; }
Entry: 先日のグリモンから先日のサイトに飛べるようにした
Entry: Twitterとはてなブックマークでマッシュアップしてみた
Entry: 誤ってエンコードされたIDNを直すGreasemonkeyスクリプトを作った
誤ってエンコードされたIDNを直すGreasemonkeyスクリプトを作った
開発ネタがぜんぜん思いつかないのでGreasemonkeyスクリプトでもやってみようと思った。
世の中のWEBシステムの多くは国際化ドメイン名(IDN)に対応していないと最近気づいた。例えばTwitter検索の結果とかにhttp://日本語.jp/とあっても飛び先がエラーになるのはサーバープログラムが「日本語」を誤ってパーセントエンコードしているため。このリンクを正しく動作させるためにドメイン名をデコードするGreasemonkeyスクリプトを作りました。
// ==UserScript== // @name idn_fixer // @namespace http://jamadam.com/blog/ // @description This fixes wrongly percent encoded domains in hrefs. // @include * // ==/UserScript== (function() { var links = document.getElementsByTagName('a'); for (var i = 0; i < links.length; i++) { var pos1 = links[i].href.indexOf('//', 0) + 2; var pos2 = links[i].href.indexOf('/', pos1); var domain = links[i].href.substr(pos1, pos2 - pos1); if (domain.indexOf('%') != -1) { links[i].href = decodeURI(links[i].href); } } })();
初めてのGreasemonkeyスクリプトなので作法とか間違ってるかも知れません。
Entry: 縮.jpに待望の「縮AGAIN」ボタンを搭載
縮.jpに待望の「縮AGAIN」ボタンを搭載
縮.jp。7月に作って放置してたら10月になって話題になった。人生で一番集客した。そんな訳で、ネタを必要以上に膨らませるべく、システムを改修しました。見た目的にはあまり変化ありませんが、中身はほぼ丸々変わってます。特筆すべき変化は。。
待望の「縮AGAIN」ボタンを搭載
生成された短縮URLが気に入らなかった場合、このボタンを押すと別のURLを生成してくれます。なお、縮AGAINした場合、古いURLはしばらくして解放されます。
既設の短縮URLがあれば、短い順にご提案
今までは湯水のように新規作成してましたが、縮ボタンを押した際、まずは既設の短縮URLを提示するようになりました。縮AGEINすると短い順に既設URLが表示され、なくなれば新規作成されます。
転送時、末尾のゴミを可能な限り取り除く
Twitterでhttp://縮.jp/上これすげーみたいなつぶやきが多発していたので、こういう場合はhttp://縮.jp/上を検知して転送します。Perlでいうと、
$id =~ s/¥P{Han}.*//;
となっています。漢字を表す正規表現なんて初めて知りました。
ちなみに、ファイルベースからPostgresqlに移行
パフォーマンスいいかなと思って、1件1ファイルなどというデータ管理をしてたんですが、IDがシーケンシャルに固定されるとか、逆引きできないとか、色々問題あったのでPostgresqlにしました。なお、ファイルベースのキャッシュの仕組みを導入したので転送時のパフォーマンスは以前と変わらない。はず。
APIにも変更あり
offsetというパラメータが新設されました。これは前述の既設URLの再利用と関連するもので、任意の既設URLを取り出すためのパラメータです。offsetを十分に大きくすると自動的に新規作成されます。通常は指定しないでください。
既知の問題
- 元URLがbit.ly等ですでに短縮済みだった場合、iPhoneで転送されない。確かソフトバンクの仕様でiPhoneで多段リダイレクトできない。
- Twitter用のいくつかのGreaseMonkeyスクリプトやアドオンで縮.jpへ飛べない。FirefoxのJavascriptのバグっぽい挙動が原因と思われる。対処法はこちら
- Twitter周辺サービスで日本語ドメインが誤ってパーセントエンコードされているケースも見かけます。サーバサイドでの処理に問題があるのではないか(憶測)。
- iPhoneの多くのアプリで開けない。おそらくアプリからwebkitだかのAPI的なものに渡すURLをpunycode変換してないのではないか(憶測)。対処法はこちらの12月15日の記事くらいしか見当たらなかった。
今後の予定
任意のIDを指定可能に- 不人気文字を避ける仕組み
- 元URLがすでに短縮URLだった場合に展開してから短縮
- スパム対策
Entry: GreaseMonkey用pbtweetでIDNを正常動作させる
GreaseMonkey用pbtweetでIDNを正常動作させる
縮.jpがFirefoxのGreaseMonkyスクリプト「pbtweet」のv1.4.10 GreaseMonkey 005810で動作しなかったので、pbtweet側を直してみた。
[2009.10.12追記] 本家に取り込んで頂いたのでこちらから最新版をDLするといいと思います。ちなみに、同様の現象はTwitter本家の検索結果でも起きていて、pbtweetの最新版を使うとこれを回避できます。
231-236行に下記を追加。
//jamadam added below var links = entry[i] .getElementsByClassName('entry-content')[0] .getElementsByTagName('a'); for (var cnt = 0; cnt < links.length; cnt++) { links[cnt].href=decodeURI(links[cnt].href); } // jamadam added above
うちだけの問題かもしれないけど、Mac版Firefox3.5.3のJavascriptでinnerHTMLを取得した場合、子要素のaタグのhref属性が、パーセントエンコードされてしまっている。上記ではこの現象をキャンセルしている。
HTML
<body id="main"> <a title="縮" href="http://縮.jp/">http://縮.jp/</a> </body>
Javascript
var hoge1 = document.getElementById('main').innerHTML; var hoge2 = document.getElementById('main').getElementByTagName('a')[0].href; alert(hoge1); alert(hoge2);
Firefoxの場合
<a title="縮" href="http://%E7%B8%AE.jp/">http://縮.jp/</a> http://縮.jp/
Safariの場合
<a title="縮" href="http://縮.jp/">http://縮.jp/</a> http://縮.jp/
Subscribe to my RSS feed