GoでTwitterクライアント書いた

最近技術ネタをqiitaに放出しがちでブログ書いてなかったけどまた書き始めることにした。

成果物

https://github.com/k0kubun/thunderbolt

なんで書いたの

yorufukurouが使いづらい状況(お察しください)のとき、earthquakeを使っていた。
割りと頻繁にクラッシュしていて、僕の環境だとネット接続が不安定なときとかにクラッシュする。
そのうち原因を調査しようと思っていたんだけど、めんどくさくてそのままになってて、まぁなんか自分で書き直せるのではという気もしたので書いた。
課題でschemeの処理系を書いてて、思ったより時間がかかってストレスが溜まってきたのでその気晴らしにサクッと一本書きたい気持ちもあった。

特徴

本家と同じく、手で取得しなくてもUserStreamsでリアルタイムにツイートが流れてくる。
とりあえずearthquakeでよくつかっていた機能だけ実装した。
本家と違うのは、複数アカウントを管理できるようになっていて、起動時にアカウントを指定できること。(一応本家にもそういうpull reqは送ってある。)

実装で困った話

GNU readline

earthquakeでも、rubyのビルドにreadline dirを指定しなければいけないしreadlineの依存は面倒くさい。
でも、ツイートの編集中は普通にカーソル移動をしたいので、それと同等の何かは必要だった。
redisで使われてるlinenoiseを使うのもありかなと思ったけど、そもそもunicodeをサポートする気がない設計になっていて、それを直したフォークもあったけど、ちゃんと動かなかった。
linenoiseを自力で全角文字に対応しようとして全部コード読んだりしてた(けどめんどくさくなって諦めた)ので結構大変だった。

linenoiseがダメそうだったので仕方なくreadlineを使うことにした。
自分がツイートするための行の上にタイムラインを挿入して表示するのが結構たいへんというか自分では思いつかなくて結局earthquakeのコードを読んだ。
earthquake風にタイムラインを流すために必要な関数がreadlineのgoのラッパーライブラリに足りなかったのでCRubyのReadline moduleのソースを参考にしていくつか自分で足した。(一部本家にも反映した)

というか、現状もなんかちょっとおかしい。go-readline側を直す必要があるかも。

Streaming API

TCP/IPの理解が浅すぎるのでStreaming APIがどうなっていてどう実装するのかがよくわからなかった。
その辺に転がっているgoのライブラリを使ってもよかったけど、あまり設計が美しいものが見つからなかったので自分で書くことにした。

https://github.com/k0kubun/userstream

Streaming APIのエンドポイントにPOSTしたレスポンスをIOとして入力を待ち続けるとなんか期待の挙動になるっぽい。
結局、REST APIのライブラリも必要なものだけ自分で書いたので、OAuthライブラリとreadline以外はほぼ自分で書くことになった。

ANSI エスケープシーケンス

こないだまでターミナルで表示できる色はblack white red blue green yellow cyan magenta しかないと思っていたけど、もうちょいearthquakeは色あるよなと思って、brightとかでググってたんだけど、
どうやらboldのエスケープシーケンスを使うと色が明るく表示されるということらしかった。

今後

自分が不便を感じた時に開発を続ける予定。
いくつか直したい部分があってissue書いてあるけど、とりあえずschemeの処理系書くのに集中したいので、それが終わってから対応する。