読者です 読者をやめる 読者になる 読者になる

いろいろ雑記

半端なVimmerのぼくが、とあるlisperの力を借りて、tw-modeでTogetterしたお話し

special thanks @cvmatさん!

eXtreme HAGO3(みーち)のつぶやきをTogetterにまとめようとしてハマりました。


イベントから一日開けて、Togeterにまとめようと作業にとりかかりました*1
Togetter開いて、キーワード検索でつぶやきを拾ってきて追加していくという、まぁ普通のトゥギャり作業ですね。


しかし、ここで問題が・・・TwitterAPIの仕様か、Togetterの仕様かはわからないけれど、
ある数以上のつぶやきを検索することができなくなりました。*2

xhago3はトレンドの5位にはいるぐらいの勢いがありました。
超盛り上がった&楽しかったのに、このままでは最後の方しかまとめとして残すことができない・・・ナンテコッタ

ここにツイートサルベージ作戦が開始されました。

おk、まずは落ち着いて状況を確認するんだと涙目でTogetterの画面をよーく見てみるとこんなオプションを発見
f:id:nefo_mi:20120320221910p:image

ん、URLから読み込めるっぽい、早速押してみる。

f:id:nefo_mi:20120320221911p:image

うーんよくわからないけれど*3
つぶやきのidがあればトゥギャれるっぽい。
どうにかidを抜き出してここにはっつければ・・・・!

どうやって抜き出そう? そうだ、twittering-modeだ

コーディングはVimを使うのですが、twitteremacsで見るという半端なVimmerのぼくです*4
emacstwitterを見るためのプラグインがtwitter-mode*5です。

ちなみにVimにもTwitVimというプラグインがあるみたいです。

さくらVPSのサーバに常時emacsが起動していて、tw-modeのバッファに当時のタイムラインがすべて保存されているはず!


どうにかしてid抜き出せないかなーとつぶやいていたら@cvmatさんからこんなリプをいただきました。
f:id:nefo_mi:20120320230443p:image

elispなにこれすごい!


画面に表示している以外の情報もオブジェクト?のように保持しているtw-modeすごい
ワンライナーですごく簡潔にやりたいことができるelispすごい

だが読めない。

とても残念なことにlisp読めない。orz
ぼやかしたら第六感で何かわかるかもしれないと目を細くして細目で見てみたけれど

読めないものは読めない。


この一行を前にして悶絶

(let((l(twittering-current-timeline-data)))(with-temp-file"~/a.txt"(mapc(lambda(tw)(insert(cdr(assq'id tw))"\n"))l)))


lispのことはlisperに聞けということで
org-export-html5presentationorg-impress-js.elの作者であり、先輩であり、なによりはごんちゅである@libkinjoさんに助けを求めるため、
教えてもらったlispを細い目で修正してgistを作成。

(let((l(twittering-current-timeline-data)))(with-temp-file"~/a.txt"(mapc(lambda(tw)(insert"http://twitter.com/#!/"(cdr(assq'user-screen-name tw))"/status/"(cdr(assq'id tw))"\n"))l)))

で現在表示してるtimelineからデータを抜き出してtwitterのurlっぽいなにをファイルに保存する。

フィルタかけたい。

するとふたたび@cvmatさんからこんなリプが!

f:id:nefo_mi:20120320230444p:image

(defun my-save-urls (file)
  (interactive "Ffilename: ")
  (let ((l (twittering-current-timeline-data))
        (regexp "xhago"))
    (with-temp-file file
      (mapc (lambda (tw)
              (let ((text (cdr (assq 'text tw))))
                (when (string-match regexp text)
                  (insert (twittering-get-status-url-from-alist tw) "\n"))))
            l))))

綺麗に書いていただいただけではなく"xhago"でフィルタかけたいんでしょ?と前後関係まで考慮していただいた模様
lisperカックイイ


さっそく.emacsに張り付けてM-x eval-regionして実行するとエラー
twittering-get-status-url-from-alistがないとのこと・・・たぶんバージョンが違うのかなーと
ChangeLogを覗いてみるとtwittering-get-status-url-from-alistが追加されたのはつい最近*6


さっそくgit pullしてっと・・・ここで疑問が
tw-modeのバッファを開いたままtw-modeを更新したらどうなるのっと
もしもバッファが消えてしまったら・・・と考えると恐ろしくてできないので・・・
urlを生成するヤツとマージして実行・・・url抜き出せたー!

(defun my-save-urls2 (file)
  (interactive "Ffilename: ")
  (let ((l (twittering-current-timeline-data))
        (regexp "xhago"))
    (with-temp-file file
      (mapc (lambda (tw)
              (let ((text (cdr (assq 'text tw))))
                (when (string-match regexp text)
			      (insert "http://twitter.com/#!/"(cdr(assq'user-screen-name tw))"/status/"(cdr(assq'id tw))"\n"))))
            l))))

イヤッホゥ! 4000件のデータをサルベージすることができたぜ!
さっそくTogetterに取り込んで・・・と思ったのだけれどここで新たな謎が

f:id:nefo_mi:20120320221911p:image

  • (複数可)って書いてあるけど一回でいったい何件まで読み込めるの?
  • Twilog/ふぁぼったーなどいろいろなTwitterサービスって書いてあるけど、どんな構造のwebサイトから読み込めるの?

たぶんWEBサイトからtwitterのurlをスクレイピングして取得してんのかなーと予想して
とりあえず、テストで2、3件のつぶやきのURL一覧を書いたテキストファイルをWEBサーバにおいて、そのURLを読み込ませるという方法で行くことにしました。

テストは無事成功したので
tw-modeから抜き出した4000件のテキストをWebサーバに置いて読み込んでみたらいつまでたっても終わらないorz

よーく見てみるとAPIの残り件数300と書いてあることに気が付く。
一気に読み込めるのは最大100件ぐらいかなーと予想

f:id:nefo_mi:20120320230445p:image

4000件のデータを100件づつに分解して*7

分割したテキストファイルをひとつづつ読み込ませたらなんとか読み込めました! やったね!と思ったのだけれど

3回ぐらい連続でテキストを読み込んだらAPIの残り件数が0になって読み込めなくなりました・・・ドユコトー

どうやら一定時間内のAPIの回数っぽいので、APIが回復するのを10分ぐらい待ってからもう一度読み込んだらいけました。
ときどきAPI休憩をはさまないとできないっぽいです・・・

そんなこんなでなんとかトゥギャることができました。
最大件数とかAPIの回復条件とかの制約はちゃんと書いてて欲しいなー。

そんなこんなでまとめたトゥギャりはこちらになります! -> eXtream HAGO 3


教訓: イベントをやるときはリアルタイムでトゥギャらないと後で大変ですよ。
または、自動的にトゥギャってくれるなにかを仕込むとかしないと・・・


トゥギャるのとても大変でした。トゥギャり職人の人たちは毎回この作業をしているのかな、尊敬するわー*8
#もしくはぼくがしらないだけで便利なサービスやツールがあるとか・・・?

散文的にまとめると

  • ツイートのidがあれば後からでもトゥギャることは可能
  • 今回はidを抜き出すのにemacsとtw-modeとelispを使いました
  • URLから読み込む場合一度に読み込めるついーとの数はだいたい100件ぐらい*9
  • 連続して大量のツイートを読み込むとAPIが枯渇するのでちょっと時間を置くと良い。

括弧を恐れずlispも勉強しないとなー

@libkinjoさんに教えてもらいながら、my-save-urlsでxhago意外の文字もフィルタ出きるように改良してみました。

(defun my-save-urls3 (file)
  (interactive "Ffilename: ")
  (let ((l (twittering-current-timeline-data))
        (regexp (read-from-minibuffer "pattern:")))
    (with-temp-file file
      (mapc (lambda (tw)
              (let ((text (cdr (assq 'text tw))))
                (when (string-match regexp text)
                  (insert (twittering-get-status-url-from-alist tw) "\n"))))
            l))))

括弧閉じの数とかで迷子にならないのかなといつも不安になるんですがw
慣れると直感で分かるようになるのかな。

文字だけじゃなくて時間の範囲でフィルタかけられるようにすればもっと便利になると思うので勉強しながら改良してみよう。

*1:イベントは土曜で、作業を始めたのは日曜日、僕のTLはニチアサの実況ですごい流れる・・・w

*2:15ページ以降取得できなかったのでおそらく1500ツイートぐらいが限界なのかな

*3:ヘルプ探したのだけれど、見つからなかったのですよ

*4:Vimmerと名乗るのもおこがましいのですがw

*5:tw-mode

*6:ChacngeLogによると02/28

*7:テキストをVimで開いて"100dd:ehoge.txtP:w"繰り返しやりましたw もっといい方法があるだろうに・・・

*8:@uhyorinさんがまとめてくださいました! ありがとうございます! [http://togetter.com/li/268679:title=eXtreme HAGO 3 LT 大会 ツイートまとめ見出し]

*9:100件以上は試していないです