さて、Perlによる超手抜き家計簿のソースをそろそろ公開しよう。
まず、Twitterのタイムラインを取得してファイルに保存するところまで。

※今回ヌルいプログラムを動かすだけの内容です。スミマセン

まずPerlが動作し、CPANモジュールをインストールできるコンピューターを用意する。


ぼくはiPhoneで出先で見ることを考えていたので、かねてから借りていたレンタルサーバーを使うことにした。
「さくらのレンタルサーバ」で、月500円払ってスタンダードコースにすると、SSHでログインできるからなにかと便利だ。

もっとも、今日作る分(コマンドを入力して手元にツイートを取得するだけ)だったら、ローカルのパソコン(UNIXじゃなくてWindowsでもMacでも)で可能だと思う。
ていうか、ローカルのパソコンを使ったほうが明らかにラクだと思う。
あるいは、自宅でサーバーを立てて世界に公開している人も手間なしだ。
問題なのはぼくのようにレンタルサーバーを、root(管理者)以外で使う場合で、CPANモジュールを入れる手間が大変掛かる。
ありがちな作業だが、何回やっても結構苦労する。
今回はNet::Twitterモジュールを導入したのだが、なかなか大変だった。

結局「CPAN Net::Twitter さくら インストール」などと検索して先達の力を借りた。

最終的に参考にしたサイトは以下の通り。
ポイントとしては、Net::Twitterが依存しているモジュール(先に入れておくべきモジュール)があって、勝手に入るときもあるが、入らないときもあって、後者の場合は単体でインストールしてやる必要があることだ。
いくつか問題を自力で解決したのだが、詳しくジャーナルを書いておかなかった。スミマセン。

さて、プログラムを作る。
#!/usr/bin/perl

# twitGet -- コマンドラインでツイートを取得してファイルに保存

use strict;
use warnings;

use lib '/home/?????/local/lib';
use lib '/home/?????/local/lib/perl5';
use lib '/home/?????/local/lib/perl5/site_perl';

use utf8;
use Net::Twitter;
use DateTime::Format::Strptime;

my $handle = Net::Twitter->new({
traits => [qw/OAuth API::REST API::Search/],
consumer_key => "????????",
consumer_secret => "????????",
access_token => "????????",
access_token_secret => "????????",
});

my $dt = DateTime->now( time_zone => 'Asia/Tokyo' );
$dt->subtract( days => 5 );

my $statuses = $handle->user_timeline({
id => '????????',
count => 200,
since => $dt,
});

my $out = "out.txt";
open my $ofh, ">:utf8", $out or die "cannot open $out as output because $!";

for my $status (@$statuses) {
print $ofh $status->{text}, "\n";
}
close $ofh;
ではプログラムを一行一行説明していく。
#!/usr/bin/perl
これはshebang行と言って、実行している環境のPerlエンジンの絶対パスを書く。レンタルサーバーの使用説明書に書いてある。
use strict;
use warnings;
これはプログラムを作るときに一番厳しい姿勢でPerlにダメ出しをしてもらう指定である。
use lib '/home/?????/local/lib';
use lib '/home/?????/local/lib/perl5';
use lib '/home/?????/local/lib/perl5/site_perl';
これは、Net::Twitterをインストールした/home以下のディレクトリの指定である。
これがなくても、自分で(CPANモジュールを入れたユーザーIDで)コマンドライン実行する場合は.cshrcなどにPATHを指定しておけば実行できるけど、CGIでWeb経由で起動したり、.forwardや.Mailfilterを使ってメールベースで起動する場合は、use libがないとダメである。
use utf8;
これはPerlのスクリプトをUTF-8で保存して、日本語の文字列リテラルをUTF-8で書いたり、lengthやsubstr関数をバイト単位でなく文字単位(日本語の場合も日本語1文字単位)で効かせるときに指定する。
use Net::Twitter;
これがさっき苦労して導入したモジュールである。
逆に、お使いのレンタルサーバーについて、これをいきなり書いても使える場合はインストールする必要はない。
とりあえず2012年2月現在「さくらのレンタルサーバー」には入っていなかった。
use DateTime::Format::Strptime;
これは下の方で日付の計算をやらせている。
これもCPANでインストールした。

ではプログラムの本体に入る。
my $handle = Net::Twitter->new({
traits => [qw/OAuth API::REST API::Search/],
consumer_key => "????????",
consumer_secret => "????????",
access_token => "????????",
access_token_secret => "????????",
});
まずNet::Twitterオブジェクトをnewメソッド(コンストラクタ)で生成する。
戻り値$handleにはNet::Twitterオブジェクトへのリファレンスが入る。

ここで、????????と書いているのはクエスチョンマークを8個書けと言っているわけではなく、OAuth認証というものの認証情報を入れる。
これは、Twitter社の開発者サイトhttps://dev.twitter.com/に言って、自分のアカウントを入れて認証情報というものを生成してもらい(特に資格審査などはなく、即時で発行される)それを使う必要がある。

以前はこんなものは必要なく、ユーザーIDとパスワードを白文で入れれば使えた。
今回いろんなブログを参考させてもらったが、昔の記事はユーザーIDとパスワードを使ったものが多かった。

最終的には以下のサイトを参考にした。
これ、自分のアカウントに自分で投稿すればいい時と、世間にアプリサービスを公開する時では手間が段違いであろう。
ここでは自分のアカウントしか使わないので、自分のアカウントについて取得した認証情報をそのまま使っている。

ポイントとしては

1) https://dev.twitter.com/というサイトを使うこと

2) 「Read Only」、「Read and Write」、「Read, Write, and Direct Message」という3つの権限タイプがあるということ。

ここではそのうち何をしたくなるかわからないので「Read, Write, and Direct Message」で登録してみた。
my $dt = DateTime->now( time_zone => 'Asia/Tokyo' );
ここでは今日という日付のDateTimeオブジェクトを作って$dtに入れている。
コンストラクターメソッドがnewじゃなくてnowなのねw

これは以下のサイトを参考にした。
$dt->subtract( days => 5 );
これで、DateTime::subtractメソッドを使って5日前の日付を取得している。
subtractは引き算という意味の英語だ。
この単純なメソッド呼び出しで、月またぎにも、年またぎにも対応できてラクチンである。
my $statuses = $handle->user_timeline({
id => '????????',
count => 200,
since => $dt,
});
?????????は疑問符を8つ書くわけではなく、Twitterのスクリーン名を入れる。
ぼくは上でOAuth認証を取得したアカウントのスクリーン名をそのまま入れている。
要はツイッターをメモ帳代わりにし、自分でツイートして自分でブラウズするだけのシステムなので、この辺は手間なしだ。

countは取得するツイートの数だ。
デフォルトでは20になるが、最大200まで指定できる。

sinceは先ほど指定した開始日(5日前以降)を指定している。
my $out = "?????/out.txt";
open my $ofh, ">:utf8", $out or die "cannot open $out as output because $!";
これは出力するファイルをオープンしている。
実際には?????/の部分には書き込み権限のあるディレクトリを絶対パスで書く。
for my $status (@$statuses) {
print $ofh $status->{text}, "\n";
}
さっきの$statusesは配列へのリファレンスを返すので、これを@$statusesでデリファレンスして配列を得て、個々の要素についてforeachループで回している。

1個1個の発言情報(これをTwitter APIの言葉でステータスという)は$statusに入ってくるが、これはハッシュリファレンスになる。
$status->{text}には発言の内容がテキストで入る。
他にもハッシュキーがある。
最も詳しくはTwitter API仕様書に書いてある。
最後はファイルハンドルをcloseして終わりである。
close $ofh;
このプログラムを起動するには、コマンドラインから実行する必要がある。つまり、
% ./twitGet
などと実行すると、out.txtにツイートがたまる。

たったこれだけのことをやるのに、長々と説明してしまった。
来週はHTML::Templateを使って結果を美しく表組みで表示してみる。

Subscribe with livedoor Reader
Add to Google
RSS