Net::Twissrを使ってターミナルでTwitter&Wassr - すぎゃーんメモ から機能追加。
リスト表示<->詳細表示を切り替えられるように。
投稿もできるようになった。…はず。
自分の環境でしか試してないけど。
#!/usr/bin/perl use strict; use warnings; use Config::Pit; use HTTP::Date; use Jcode; use Net::Twissr; use Switch; 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 ($rows, $cols); my $screen = new Term::Screen; $rows = $screen->rows(); $cols = $screen->cols(); my @friends_timeline; &refresh_friends_timeline(\@friends_timeline); # --- usage --- # k: up # j: down # h: detail # l: list # r: refresh # q: quit # p: post my $mode = 0; my $index = 0; my $offset = 0; &draw(\@friends_timeline, $mode, $index, $offset); MAIN: while (1) { while (1) { my $ch = undef; my $getch = new Term::Screen; $ch = $getch->noecho()->at($rows, $cols)->getch(); last MAIN unless (defined $ch); last MAIN if ($ch eq 'q'); if ($ch eq 'k') { $index-- if ($index > 0); $offset-- if ($index - $offset < 0); } if ($ch eq 'j') { $index++ if ($index < $#friends_timeline); $offset++ if ($index - $offset > $rows - 1); } if ($ch eq 'h') { $mode = 1; } if ($ch eq 'l') { $mode = 0; } if ($ch eq 'r') { &refresh_friends_timeline(\@friends_timeline); } if ($ch eq 'p') { $screen->clrscr()->at(0, 0)->puts('Message:')->at(1, 0); last; } &draw(\@friends_timeline, $mode, $index, $offset); } my $status = <>; if (defined $status) { chomp($status); &update($status); } &draw(\@friends_timeline, $mode, $index, $offset); } # 終了処理 $screen->normal()->clrscr(); # Terminalへの描画 sub draw { my ($timeline, $mode, $index, $offset) = @_; $screen->clrscr(); switch ($mode) { case 0 { for (0..$rows - 1) { last if ($_ > @$timeline - 1); # 選択している行を反転表示 $screen->reverse() if ($_ + $offset == $index); my $status = $timeline->[$_ + $offset]; $screen->at($_, 0)->puts($status->{line})->clreol()->normal(); } }; case 1 { my $row = 0; my $status = $timeline->[$index]; $screen->at($row++, 0)->puts($status->{service})->clreol(); return if ($row > $rows - 1); $screen->at($row++, 0)->puts(scalar(localtime($status->{time})))->clreol(); return if ($row > $rows - 1); my $user = (Jcode->new($status->{user_id} . ' / ' . $status->{user_name})->jfold($cols))[0]; $screen->at($row++, 0)->puts($user)->clreol(); return if ($row > $rows - 1); my @text = Jcode->new($status->{text})->jfold($cols - 1); for (0..$#text) { $screen->at($row++, 0)->puts($text[$_])->clreol(); return if ($row > $rows - 1); } }; } $screen->at($rows, 0); } # friends_timelineの更新 sub refresh_friends_timeline { my $timeline = shift; my $friends_timeline = $twissr->friends_timeline(); TIMELINE: for (@$friends_timeline) { for my $status (@$timeline) { if ($_->{service} eq $status->{service} && $_->{id} eq $status->{id}) { next TIMELINE; } } my $time = HTTP::Date::time2iso($_->{time}); my $service = substr($_->{service}, 0, 1); my $line = qq/[$time] ($service) $_->{user_id} : $_->{text}/; # 1行分の長さに切る $line = (Jcode->new($line)->jfold($cols))[0]; $_->{line} = $line; push @$timeline, $_; } @$timeline = sort { $b->{time} <=> $a->{time} } @$timeline; } # statusの更新 sub update { my $status = shift; $twissr->update($status); }
Term::Screenでgetchを呼び出した後でreadlineさせようとするとおかしくなってしまったので、getchするところだけは別のインスタンスで処理。
readlineのときに途中でCtrl-Dを2回押すと、STDINからの読み込みがundefで繰り返されてしまってプログラムが続行不能になってしまう…どうすればいいんだろう
/lang/perl/Net-Twissr/trunk/example/terminal.pl – CodeRepos::Share – Trac