#!/usr/bin/perl # Wassrの自分の投稿から写真付きのものだけを抜き出してWordPressのエントリを生成する # 08/07/07版 use strict; use encoding 'utf8'; use lib qw(./lib); use LWP::UserAgent; use XML::Simple; use Time::Local; use IO::File; use Encode; use XMLRPC::Lite; use Data::Dumper; use CGI qw/:standard/; # 使い方: # 1. このスクリプトを適当な名前に変えて適当なディレクトリに設置 # 2. 「WordPressの設定」「wassrの設定」を書き換える # 3. スクリプトを設置したディレクトリに cache ディレクトリを作成 # 4. CRONで定期的に実行するか、反映したい時に手作業で実行 # (現在はCGIとして動作する作りになっています) # このスクリプトの実行には、 # LWP::UserAgent, XML::Simple, XMLRPC::Lite のモジュールが必要です。 # 出力をいじりたい時は、116~128行あたりをいじって下さい。 # このスクリプトはAPI取得時にWassrにログインしていないので、 # Wassrの公開範囲を「友達のみ」に指定しているとメッセージを取得できません。 # --------------------------------------------------------------------- # WordPressの設定 my $RPCURL = 'http://WorPressサイトのURL/xmlrpc.php'; my $APPKEY = 'WordPress'; my $BLOGID = '0'; my $USERNAME = 'WodPressのユーザー名'; my $PASSWORD = 'WodPressのパスワード'; my $CATEGOTY_ID = ポストしたいカテゴリ番号; # wassrの設定 my $ID = 'wassrのID'; # キャッシュ用ファイル my $CACHEDIR = "./cache"; # 一時ファイルを置くディレクトリ my $ENTRY_POINT = "$CACHEDIR/wassr.dat"; my $ITEM_DUMP = "$CACHEDIR/wassr.dmp"; # エントリ保存用 my @items = (); # 今回 my @last_items = (); # 前回 my $last_rid = ''; # --------------------------------------------------------------------- print header(-type => 'text/html'), start_html(title => 'Wassr To WordPress'); # 前回処理した日付を取得 my $last_entry_date = '1970/01/01'; my $last_entry_id = '0'; my $fh = IO::File->new(); if ($fh->open($ENTRY_POINT, 'r')) { $last_entry_date = $fh->getline; chomp($last_entry_date); $last_entry_id = $fh->getline; chomp($last_entry_id); $fh->close; } # 取得する範囲:本日の午前6時以降 my ($sec, $min, $hour, $mday, $mon, $year) = localtime(time); my $from_time = timelocal(0, 0, 6, $mday, $mon, $year); if ($from_time > time) { # もし今が午前6時以前の場合、昨日の午前6時以降とする $from_time -= (60 * 60 * 24); ($sec, $min, $hour, $mday, $mon, $year) = localtime($from_time); } # エントリを作成する日付を保存 my $entry_date = sprintf("%04d/%02d/%02d", $year + 1900, $mon + 1, $mday); # もし前回起動時と日付が一緒であれば、前回作成したエントリリストを復元 if ($last_entry_date eq $entry_date) { if ($fh->open($ITEM_DUMP, 'r')) { my $data = join('', $fh->getlines()); $fh->close; my $VAR1; # Data::Dumperで生成した変数名の定義 @last_items = @{eval($data)}; $last_rid = $last_items[0]->{rid} if (@last_items); # 一番新しいエントリのid } } unlink $ITEM_DUMP if (-e $ITEM_DUMP); # キャッシュを削除する # wassrで自分の発言をXMLで取得 my $ua = LWP::UserAgent->new; my $res = $ua->get('http://api.wassr.jp/statuses/user_timeline.xml?id=' . $ID); if (!$res->is_success) { print $res->status_line, end_html; exit; } # XMLを解析 my $parser = XML::Simple->new; my $xml; eval { $xml = $parser->XMLin($res->content); }; if ($@) { print $@, end_html; exit; } # 新しい記事順に並べ替える my @sorted_key = sort {$b <=> $a} (keys %{$xml->{status}}); # 今日の写真入りステータスを拾う foreach my $key (@sorted_key) { my $status = ${$xml->{status}}{$key}; # 既に前に読み込んだデータであれば、そこで終了 last if ($status->{rid} eq $last_rid); # 今日のデータでなければ無視 my $epoch = $status->{epoch} || 0; next if ($epoch < $from_time); # 写真が入っている投稿を拾う push @items, $status if (ref($status->{photo_thumbnail_url}) ne 'HASH'); } push @items, @last_items; # 前回結果と合体 # 写真があればエントリを生成 if (@items) { @items = reverse(@items); # 生成された順に並べ替える my $content = '
'; foreach my $item (@items) { my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime($item->{epoch}); my $posted = sprintf("%02d/%02d %02d:%02d", $mon + 1, $mday, $hour, $min); $content .=<
$item->{text}
CONTENT } $content .=<
Powered by Wassr
FOOTER # タイトルの生成 my $title = $entry_date . ' の写真'; # WordPressに投稿 my $entry_id; if ($last_entry_date ne $entry_date) { $entry_id = newEntry($title, $content); # 新規 } else { $entry_id = $last_entry_id; editEntry($entry_id, $title, $content); # 編集 } # 日付とIDとエントリを保存して終了 if ($fh->open($ENTRY_POINT, 'w')) { $fh->print("$entry_date\n$entry_id\n"); $fh->close; } if ($fh->open($ITEM_DUMP, 'w')) { @items = reverse(@items); # 並び方を元に戻す $fh->print(Dumper(\@items)); $fh->close; } } print h1("DONE."), end_html; # --------------------------------------------------------------------- # blogger.newPost で書き込む sub newEntry($$) { my ($title, $body) = @_; $body = encode('utf-8', "$CATEGOTY_ID$title$body"); my $ret = 0; eval { $ret = XMLRPC::Lite->proxy($RPCURL)->call('blogger.newPost', $APPKEY, $BLOGID, $USERNAME, $PASSWORD, $body, 1)->result; }; warn $@ if ($@); return $ret; } # --------------------------------------------------------------------- # blogger.newPost で書き込む sub editEntry($$$) { my ($id, $title, $body) = @_; $body = encode('utf-8', "$CATEGOTY_ID$title$body"); my $ret = 0; eval { $ret = XMLRPC::Lite->proxy($RPCURL)->call('blogger.editPost', $APPKEY, $id, $USERNAME, $PASSWORD, $body, 1)->result; }; warn $@ if ($@); return $ret; }