風柳メモ

ソフトウェア・プログラミング関連の覚書が中心

TwitterアイコンURL取得API

「TwitterアイコンURL取得API」は、Twitter APIの有料化に伴い、2023/02/03に提供を終了致しました。

いらすとやさんの画像をお借りしております



2013/07/30より、APIのエンドポイントが変わっています。
詳細はこちら↓で。

TwitterアイコンURL取得APIのエンドポイントが変わりました - 風柳メモ


Twitterの個別ページでアイコン等を前に持ってくるスクリプトをバージョンアップ - 風柳メモの際に…

AutoPageirze for SeaHorseの現状のSITEINFOでは、Twitterの個別ページで継ぎ足されるのは本文の部分(div.hentry)のみで、ユーザ情報部分(div.user-info)が無く、アイコンのURLが含まれていません。
ですが、吹き出しにアイコンを表示するにあたり、どうにかして継ぎ足されたツイートのユーザのアイコンURLを(screen_name辺りから)を引っ張ってくる必要が有りました。


一応、

要はhttp://api.dan.co.jp/twicon/screen_name/sizeが、常に最新のアイコンを指し示すURIとして使えるというわけです。

404 Blog Not Found : #perl - twitterのアイコンURLを固定するAPI

の存在は知ってはいましたが、事情により*1、TwitterのAPI(/users/show)を使用する、ほぼ同様のAPIを例によってGAE/Pythonで自作しました。

API仕様

  1. ノーマルアイコン取得(48px×48px)
    http://gadgtwit.appspot.com/twicon/<screen_name>
    http://gadgtwit.appspot.com/twicon/<screen_name>/normal
    例:http://gadgtwit.appspot.com/twicon/furyutei
  2. 小さいアイコン取得(24px×24px)
    http://gadgtwit.appspot.com/twicon/<screen_name>/mini
    例:http://gadgtwit.appspot.com/twicon/furyutei/mini
  3. 大きいアイコン取得(73px×73px)
    http://gadgtwit.appspot.com/twicon/<screen_name>/bigger
    例:http://gadgtwit.appspot.com/twicon/furyutei/bigger
  4. オリジナルアイコン取得(大きさ不定・アップロードしたサイズ?)
    http://gadgtwit.appspot.com/twicon/<screen_name>/original
    例:http://gadgtwit.appspot.com/twicon/furyutei/original
  5. 背景画像
    http://gadgtwit.appspot.com/twbg/<screen_name>
    例:http://gadgtwit.appspot.com/twbg/furyutei (サンプルは50%の大きさに縮めてあります)

オリジナルとの主要な違いは、

  • デフォルト(サイズ指定しない場合)は、normalと同じ(オリジナルのほうはbiggerと同じ)。
  • キャッシュ時間は1時間(3600秒)約3時間。
  • おまけで、背景画像取得用のAPIもつけてみた。
  • Google App EngineのFree Quota範囲を越える程に高負荷な利用があった場合は、提供中止予定。

気付いた点等

はてな記法で

[http://gadgtwit.appspot.com/twicon/furyutei:image]

だけだと、http://gadgtwit.appspot.com/twicon/furyutei(No Image)となる。
302 Foundで本来のURLに飛ばしているだけなんだけれど、対応していない?

[http://gadgtwit.appspot.com/twicon/furyutei:image=http://gadgtwit.appspot.com/twicon/furyutei]

なら、http://gadgtwit.appspot.com/twicon/furyuteiのように表示されるみたい。

補足

今になって気がついたけれど、

UserIcons
Inicio | Tweetimag.es

http://b.hatena.ne.jp/rikuo/20091203#bookmark-17710184

なんてものがあるのか〜。最初からこっち使えば良かったかな……。
まぁ、少なくともUserIconsの方はざっとソースを読むかぎりスクレイピングしているみたいだけれども。

*1:TwitterのAPIを使わずにHTMLをパースしているというのが、Twitterの利用規約の“Twitterの事前の承諾なくして本サービスのスクレーピングを行うことは明示的に禁じられています”に引っかかりかねないため。知らなかった当時はともかく、規約を読んだ後だと躊躇われますので……。

RSSをiCal形式に変換してGoogleカレンダーに読み込ませる実験(挫折中)

Twistory is now historyに興味があったのを思い出したので

TwitterのツイートをGoogleカレンダーに登録する、というtwistory、以前試してみたらうまくいかなかった*1のですが、でも面白い試みと感じたのを思い出しました。


それで、ちょっとだけ汎用性を高め、一般的なRSSをiCalendar形式に変換して、Googleカレンダーに登録する、というのはどうか、と思ったのですが*2、頓挫しつつあります。
下記のように登録できたりできなかったり。まさか、今日のTwitterの不調が影響しているとも思えないし。心当たりがある方、何かご教示いただければ幸いです。

一応、ブックマークレット等

問答無用で現ページ先頭のtype="application/rss+xml"のlink要素を登録しようとするタイプ
javascript:(function(w,d,h,ls,l,i){ls=d.getElementsByTagName('link');for(i=0;i<ls.length;i++){l=ls[i];if(l.type=='application/rss+xml'){w.location.href='http://www.google.com/calendar/render?cid='+encodeURIComponent('http://gadgtwit.appspot.com/rss2ical/'+l.href);return}}})(window,document)
プロンプトを出して、登録するかを確認するタイプ(最大、type="application/rss+xml"のlink要素数分尋ねてくる)
javascript:(function(w,d,h,ls,l,i,h,r,t){ls=d.getElementsByTagName('link');for(i=0;i<ls.length;i++){l=ls[i];if(l.type=='application/rss+xml'){h='http://gadgtwit.appspot.com/rss2ical/'+l.href;t=l.title;r=prompt((t?t:'下記URL')+'をGoogleカレンダーに登録します。よろしいですか?',h);if(r){w.location.href='http://www.google.com/calendar/render?cid='+encodeURIComponent(h);return}}}})(window,document)

たとえばTwitterの個人ページとか、はてなブックマークの個別ページに行って、ブックマークレットを実行すれば(必要に応じてプロンプトに応答すれば)、Googleカレンダーのページへと移動し、本当にそのカレンダーを追加するかURLを出して(URLは、「http://gadgtwit.appspot.com/rss2ical/<RSSのURL>」の形式)確認してくるので、[はい、このカレンダーを追加します]を押せば、うまくいけば登録できます。

うまく登録できたら、こんな感じで


独り言とか

  • 何故か、全く同じRSS(を変換したもの)にも関らず、登録できるときと、できないときがある。
  • 続けて何度やってもだめな場合や、一度でうまくいく場合もある。
  • プロンプトで確認されるURLをコピーしておいて、直接ダウンロードしても、一応正常に出力されているように見える。
  • ちなみに、RSS→Pythonのdict()への変換は独自にやっているので、かなり手抜き。Atomとかも未対応。
  • iCalendar形式への変換は、たまたま見つけたPythonのライブラリであるicalendar-2.1を使用させていただいている。が、ちょっとバグが有るみたい(日本語を変換したときにゴミが入ることがある)なので、parser.pyにパッチを当てて使っている(下記参照)。
parser.pyのパッチ箇所

元ソースの440行目辺り。2010.06.15の日付が入っている部分がパッチ。

            if m is not None and m.end()!=l_line:
                new_lines.append(self[start:start+m.start()])
                start += m.end()
                continue

            # 2010.06.15: start =>
            _end = end
            # 2010.06.15: <= end
            
            if end >= l_line:
                end = l_line
            else:
                # Check that we don't fold in the middle of a UTF-8 character:
                # http://lists.osafoundation.org/pipermail/ietf-calsify/2006-August/001126.html
                while True:
                    char_value = ord(self[end])
                    if char_value < 128 or char_value >= 192:
                        # This is not in the middle of a UTF-8 character, so we
                        # can fold here:
                        break
                    else:
                        end -= 1
            
            # 2010.06.15: start =>
            if _end != end:
              slice = self[start:end]
            # 2010.06.15: <= end
            
            new_lines.append(slice)

2006/8の日付で、最終文字がUTF-8の真ん中だった場合には改行位置を前にずらす処理(end -= 1)を入れてあるのだけれど、endを減らしているのに、sliceがそのまま(前のend位置で切り出したまま)になっていたので、これを修正しただけ。自信はない。ゴミは消えたみたいなので、多分、あっていると思うのだけれど。

*1:『→Google Calendar』リンクではうまく登録出来ず、『→Any other application supporting iCalendar』のリンクを直接登録してもやっぱりだめだった記憶が有る。で、新規にカレンダーを作って、そこにインポートすることは出来たのだった、確か。

*2:多分、検索すれば同じような発想の試みは沢山有るに違いないとは思いますが。