m2O

2007/02/05 (月)

Auto Commit del.icio.us

|  Auto Commit del.icio.us - m2O を含むブックマーク

これは何?

del.icio.us で「あとで読む」タグをつけてブックマークしたい時に、確認画面以降を自動化する bookmarklet & user.js です。

注意

user.js 内では記事タイトルが設定されていない場合、"はてなブックマークエントリー情報取得API"からタイトルを取得しています。これは http://b.hatena.ne.jp/ からダウンロードした任意の JavaScriptdel.icio.us ドメイン内で実行しているということです。このことを理解した上でご利用ください。(該当部分を削除すればこのリスクはありません)

先に方法

  1. user_id は自分のIDに置き換えます
  2. location.hash の部分は他者が知り得ない任意の値にします
    リクエストパラメータ ackey は他者が知り得ない任意の値にします利用の際は必ず変更してください。

[bookmarklet]

javascript:window.open('http://del.icio.us/user_id?ackey=qawsedrftgyhujiko&url='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title)+'&tags='+encodeURIComponent('あとで読む')+'&v=4&jump=close','delicious','width=700,height=400').blur()

[user.js]

// ==UserScript==
// @name del.icio.us - Auto Commit del.icio.us
// @namespace http://orera.g.hatena.ne.jp/miya2000/20070205/p0
// @version 1.0.3
// @include http://del.icio.us/user_id?ackey=qawsedrftgyhujiko&url
// ==/UserScript==
(function(){
    window.focus=new Function(); // kill focus.
    window.addEventListener('load', function(){
        var d = document;
        var url   = d.getElementById('url').value;
        var title = d.getElementById('description').value;
        // <はてなからタイトル取得>
        if ( ! title ) {
            opera.tmpcallback = function (data) {
                delete opera.tmpcallback;
                d.getElementById('description').value = (data) ? data.title : url;
                d.getElementById('delForm').submit();
            };
            var s = d.createElement('script');
            s.type = 'text/javascript';
            s.src = 'http://b.hatena.ne.jp/entry/json/?callback=opera.tmpcallback&url=' + 
                    encodeURIComponent(url);
            d.body.appendChild(s);
            return;
        }
        // </はてなからタイトル取得>
        if ( ! title ) d.getElementById('description').value = url;
        d.getElementById('delForm').submit();
    }, false);
})()

[menu.ini]

[Link Popup Menu]
Item, "リンクをdeliciousに追加"=Go to page, "javascript:(function(){var url='http://del.icio.us/user_id?ackey=qawsedrftgyhujiko&url='+encodeURIComponent('%l')+'&title='+encodeURIComponent('%t')+'&tags='+encodeURIComponent('あとで読む')+'&v=4&jump=close';if(/^javascript:/.test(location.href)){location.href=url;window.blur();}else{window.open(url,'','width=700,height=400').blur();}})()"
[Document Popup Menu]
Item, "deliciousに追加"=Go to page, "javascript:(function(){var url='http://del.icio.us/user_id?ackey=qawsedrftgyhujiko&url='+encodeURIComponent('%u')+'&title='+encodeURIComponent('%t')+'&tags='+encodeURIComponent('あとで読む')+'&v=4&jump=close';window.open(url,'','width=700,height=400').blur();})()"
[Hotclick Popup Menu]
Item, "リンクをdeliciousに追加"=Go to page, "javascript:(function(){if('%l'){var url='http://del.icio.us/user_id?ackey=qawsedrftgyhujiko&url='+encodeURIComponent('%l')+'&title='+encodeURIComponent('%t')+'&tags='+encodeURIComponent('あとで読む')+'&v=4&jump=close';if(/^javascript:/.test(location.href)){location.href=url;window.blur();}else{window.open(url,'','width=700,height=400').blur();}}else{alert('リンク無し')}})()"

以下、ここまでの流れ

特にタグを入力したいわけじゃない場合は確認画面以降を自動化したい。→ただ単に user.js で submit() するだけじゃ CSRF できちゃう。 →とりあえず一番簡単な固定キーで bookmarklet からのリクエストかどうかを判定して自動 submit。

TODO

  1. Link Popup Menu 対応。このあいだのは title にも url を入れてたけど、今度は"はてなブックマークエントリー情報取得API"からタイトル取ってこよう。実装済み
  2. location.hash よりクエリの方が見栄えがいいと思う。実装済み
  3. 毎回同じパスワードを使っているようで気持ち悪い。例えばワンタイムパスワード現在時刻を別の user.js に出力しておいて上の user.jsリクエストパラメータと比較する(古いのは無効)、ってのを思いついた。ほかにあるかな?

思ったこと

UserJavaScript からしかアクセスできない共有メモリ(ドメインを超えて保持)なんかがあると便利そう。

ライセンス

好きに使っていいけど責任取らないやつ。

更新履歴

1.0.1
固定キーを保持する場所を location.hash から リクエストパラメータ(ackey)に変更。このパラメータは「http://del.icio.us/post」から「http://del.icio.us/user_id」にリダイレクトされる時に削除されるので、ユーザーIDと固定キー双方を知らないと CSRF できない。*1
1.0.2
タイトルが無い場合に"はてなブックマークエントリー情報取得API"からタイトルを取得するように変更。
menu.ini をカスタマイズしてコンテキストメニューから使えるようにしました。
menu.ini
M2のリンクから実行した時に余計なウィンドウが出ていたので出ないようにしました。
1.0.3
はてなからタイトルを取得する部分を削除しやすいようにしました。削除する場合は<はてなからタイトル取得>から</はてなからタイトル取得>までを削除してください。

*1:ユーザーIDを指定したCSRFなんて、相当な恨みを買っているとしか思えませんね