Terminal上で動作するTwitter閲覧ツール「Twiterm」を作った

TerminalでTwitterと言えばTermtterという有名なものが既にありますが、
自分好みの操作性とUIで使いたいという願望があり、またPerlで何か練習がてらに作りたいというのもあり、
こんなものを作ってみました。
GitHub - sugyan/Twiterm: Twitter on Terminal
「ついたーむ」っていう名前でいいかな?


こんな画面で動きます。


"j", "k"のキーでカーソルを上下させるイメージで発言を選択。returnキーで詳細モードに切り替え。"q"で終了。
現時点ではここまで。


実は以前にもterminalでtwitterとかは試みていたのだけど、今回はそれとは別に作り直した。

Twitermの中身

AnyEventを使ってイベント駆動な動作をするように作った。

  • キー入力による表示の変更
  • タイマーによるタイムラインの自動更新
  • API使用によるタイムライン更新

この3つをそれぞれAnyEventを使って行うことによって、それぞれの処理待ちによって他の処理がブロッキングされないようにした。
AnyEvent->io, AnyEvent->timer, そしてAnyEvent::Twitterを使用。
・タイマー部分

# 一定時間毎にupdateする
my $cv_timer = AnyEvent->condvar;
my $timer; $timer = AnyEvent->timer(
    after    => 0,
    interval => 60,
    cb       => sub {
        update();
        $cv_timer->send;
    },
);
$cv_timer->recv;

・キー入力部分

    my $cv = AnyEvent->condvar;
    my $io; $io = AnyEvent->io(
        fh   => \*STDIN,
        poll => 'r',
        cb   => sub {
            my $char = $screen->noecho()->getch();
            $cv->send($char);
        },
    );
    # キー入力待ち
    my $char = $cv->recv;

・タイムラインの取得

    my $w; $w = $self->{twitter}->reg_cb(
        error => sub {
            my ($twitter, $error) = @_;
            #TODO エラー時の処理はどうする?
            undef $w;
        },
        statuses_friends => sub {
            my ($twitter, @statuses) = @_;

            $self->add(map { $_->[1] } @statuses);
            &$callback();
        },
    );
    $self->{twitter}->receive_statuses_friends;
    $self->{twitter}->start;

だいたいこんな書き方でいいのかな?少しずつAnyEventを使った書き方が分かってきた。ような気がする。


あとはMouseを使ってタイムラインの情報を整理するようにし、メインのスクリプトではうまいこと表示できるようにゴニョゴニョとめんどくさい処理をやっている。
キレイにリスト表示されるようにターミナル幅にあわせて1行に区切るために、id:myfinderさんに教えていただいたUnicode::EastAsianWidthを使用している。

今後

まだfriends_timelineを閲覧することしかできないので、repliesも見られるようにしたいのでIRCクライアントでのchannel切り替えのようにページを切り替える処理を追加したい。実装方法考え中。
あとpostもできないのでコマンド入力的なカンジでupdateやreply, retweetを行うことができるようにしたい。
当然のことながらWassrも同様に使えるようにしたい。しかしAnyEvent::Wassrが必要だ…!!
テストも全然書いてない。ちゃんと書かなきゃ。