Subscribed unsubscribe Subscribe Subscribe

Net::Twissrを使ってターミナルでTwitter&Wassr

せっかくNet::Twissrというモジュールを作ったので、それを使ってスクリプトを書いてみた。
Term::Screenを使ってTerminal.app上でfriends_timelineを一覧表示する。
ボタン一つで更新ができて、過去に取得したtimelineと並べて表示。

#!/usr/bin/perl
use strict;
use warnings;

use Config::Pit;
use Encode;
use HTTP::Date;
use Net::Twissr;
use Term::Screen;

my $config = Config::Pit::get('twissr', require => {
    'twitter_username' => 'your username on twitter.com',
    'twitter_password' => 'your password on twitter.com',
    'wassr_username' => 'your username on wassr.jp',
    'wassr_password' => 'your password on wassr.jp',
});
my $twissr = Net::Twissr->new($config);

my @array;
&refresh();

my $usage = q/usage -- j:down k:up r:refresh q:quit/;

my $index = 0;
my $offset = 0;
my $screen = new Term::Screen;
$screen->clrscr()->noecho();

while (1) {
    $screen->clrscr();
    for (0..$screen->rows()-2) {
        # 選択している行を反転表示
        $screen->reverse() if ($_ + $offset == $index);

        my $status = $array[$_ + $offset];
        my $time = HTTP::Date::time2iso($status->{time});
        my $text = encode_utf8($status->{text});
        my $line = qq/[$time] $status->{user_id} : $text/;
        # 長過ぎる行があると改行でレイアウトが乱れるので適当に切る
        $line = substr($line, 0, $screen->cols * 2);
        $screen->at($_, 0)->puts($line)->clreol()->normal();
    }
    $screen->reverse()->at($screen->rows()-1, 0)->puts($usage)->clreol()->normal();
    my $ch = $screen->getch();
    last if ($ch eq 'q');
    if ($ch eq 'k') {
        if ($index > 0) {
            $index--;
            $offset-- if ($index - $offset < 0);
        }
    }
    if ($ch eq 'j') {
        if ($index < $#array) {
            $index++;
            $offset++ if ($index - $offset > $screen->rows - 2);
        }
    }
    if ($ch eq 'r') {
        &refresh();
    }
}
$screen->normal()->clrscr();

sub refresh {
    my $timeline = $twissr->friends_timeline();
    TIMELINE: for (@$timeline) {
        for my $status (@array) {
            if ($_->{service} eq $status->{service} && $_->{id} eq $status->{id}) {
                next TIMELINE;
            }
        }
        push @array, $_;
    }
    @array = reverse sort { $a->{time} <=> $b->{time} } @array;
}

自分のMacのTerminal.appでしか動作確認していないので、他の環境でどうなるかわからないけど…。
せっかくなのでCodeReposにも上げておきました。
/lang/perl/Net-Twissr/trunk/example/terminal.pl – CodeRepos::Share – Trac
もうちょい改良したらかなり使えるモノになりそう。自分的に。

追記

ていうか reverse sort って何だよ…$aと$bを逆にすればいいだけじゃねぇか orz