TwitterのRSSからはてなダイアリーに投稿してしまうPla!

毎度おなじみ,Plagger ですが,今回はとりあえずできた程度のモジュール. Twitter の RSS を取得して,はてなダイアリーの見出しとして投稿してしまいます. こうすることで,はてダのキーワードと検索が使えるので何かと便利かも. 言及したキーワード一覧なんかは,自分がよくどんなことをしゃべってるのか 見ることができておもしろいと思います.というわけでできあがりのはてダは こちら.

riywoのつぶやき riywo のつぶやき

Plagger::Plugin::Publish::Twitter2HatenaDiary

本当は,Filter と Publish に分離すべきものなのですが,デフォルトの Publish::HatenaDiary だとテンプレート使ってるのでちょっと嫌な感じです. なので,テンプレート使わずにそのまま投稿するだけの Publish::HatenaDiarySimple を作ればいいのですが,面倒だったので 一緒に Filter の役目もくっつけてしまいました.余力があればあとでちゃんと 分離したいと思います.

要点は,はてダへの投稿に関しては Publish::HatenaDiary のマルパクリですが, どうやら title というものを見出しにしてくれるようなので,ここに以下の フォーマットで Twitter のポストを書き込みます.

[http://twitter.com/riywo/statuses/*********:title=12:32] てすとてすとー

これははてダ記法で,投稿時間にステータスへのリンクを貼ってくれます. ただ,問題だったのが投稿時間です.Twitter の設定で GMT+9:00 を指定しているのに なぜか反映されていません.英語にしてるからかな?ともかくそれが 嫌なので,DateTime モジュールなどを使いながら,ソースの中で無理矢理+9:00 して しまっています.この辺も要変更ですが,自分用なのでまぁ動けばいいや w

あと,Twitter の RSS だと改行の含まれるポストがそのまま流れてくるので, 改行を消してやらないといけません.これは以前作った Filter::TwitterQuote でも 起こりうるので,そっちも修正しました.正規表現べんりー.

あとはいつも通りこれを cron で回してやれば終わり.やたー! ソースはいつも通り github に上げていますので,git 使う人はそちらからどうぞ.

lib/Plagger/Plugin/Publish/Twitter2HatenaDiary.pm

package Plagger::Plugin::Publish::Twitter2HatenaDiary;
use strict;
use base qw( Plagger::Plugin );

use Encode;
use WWW::HatenaDiary;

use DateTime;
use DateTime::Format::HTTP;
use DateTime::TimeZone;

sub register {
    my($self, $context) = @_;
    $context->register_hook(
        $self,
        'plugin.init' => \&initialize,
        'publish.init' => \&publish_init,
        'publish.entry' => \&publish_entry,
        'publish.finalize' => \&publish_finalize,
    );
}

sub initialize {
    my($self, $context) = @_;
    my $config = {
        username => $self->conf->{username},
        password => $self->conf->{password},
        group => $self->conf->{group},
        mech_opt => {
            agent => Plagger::UserAgent->new,
        },
    };
    $self->{diary} = WWW::HatenaDiary->new($config);
}

sub publish_init {
    my($self, $context, $args) = @_;
    local $@;
    eval { $self->{diary}->login };
    if ($@) {
        $context->log(error => $@);
        delete $self->{diary};
    }
}

sub publish_entry {
    my($self, $context, $args) = @_;
    return unless $self->{diary};

    my $entry_title = $args->{entry}->title_text;
    $entry_title =~ s/\r|\n//g;
    $entry_title =~ s/^.+?: //o;
# $entry_title =~ /^(.+?): (.+)$/o;
    my $post = $entry_title;

    my $date = $args->{entry}->date;
    my $zone = DateTime::TimeZone->new( name => 'GMT' );
    my $dt = DateTime::Format::HTTP->parse_datetime($date, $zone);
    $dt->set_time_zone('Asia/Tokyo');
    my $hh = sprintf("%02d", $dt->hour);
    my $mm = sprintf("%02d", $dt->minute);

    my $time = $hh . ":" . $mm;
    my $link = $args->{entry}->link;

    my $title = "[" . $link . ":title=" . $time . "] " . $post;
    $context->log(debug => "$title \n");

# my $body = $self->templatize('template.tt', $args);
    my $uri = $self->{diary}->create({
        title => encode_utf8( $title ),
# title => encode_utf8( $args->{entry}->title_text ),
# body => encode_utf8( $args->{entry}->body_text ),
    });
    $context->log(debug => "Post entry success: $uri");

    my $sleeping_time = $self->conf->{interval} || 3;
    $context->log(info => "sleep $sleeping_time.");
    sleep( $sleeping_time );
}

sub publish_finalize {
    my($self, $context, $args) = @_;
    return unless $self->{diary};
    $self->{diary}->{login}->logout;
}

1;

twitter2hateda.yaml

include:
  - /home/user/yaml/base.yaml

plugins:
  - module: Subscription::Config
    config:
      feed:
        - http://twitter.com/statuses/user_timeline/riywo.rss

  - module: Filter::Reverse

  - module: Filter::Rule
    rule:
      module: Deduped
      path: /home/user/cache/plagger-twitter2hateda.db

  - module: Publish::Twitter2HatenaDiary
    config:
      username: hatena-id
      password: **********

ふと気づいた CustomFeed::Twitter の問題点

あと途中で一度 CustomFeed::Twitter を入力につかおうと思ったのですが, Fav 用に作っていたので,ID が取れていなかった部分を修正.しかし, WEB での表示は実はポストを省略されたりしているので,ちょっとまずいですねー. この辺は CustomFeed::Twitter の中でポストの URL にアクセスして 全文取得しないといけません.EntryFullText とか使ってもいいのかもしれません. 最近は Twitter も安定してるので RSS でもいいんですけどねー.Filter::Rule の 重複を調べるモジュールの挙動を調べないと Subscription::Config と CustomFeed が 共存できないな.この辺は要調査.

Perl も Plagger もすげーよ!

いやー,それはともかく,Perl 簡単だわー.例えば時刻取り扱いたいと思ったら 「cpan 時刻」とかで検索すればわさわさ出てくる.はてダの API も CPAN があるから 僕は何もしなくてもできる.便利すぎる.Plagger も適当にいい感じで RSS を 処理してくれるので,勘でアクセスするとちゃんとデータ入ってたりするし.

Plagger と CPAN がある以上,Perl 以外をバリバリやる気はしないなー.ただ Catalyst はドキュメント不足な気がしたので,フレームワークなら Ruby on Rails かな. RoR と Perl を連携とかするのは,無駄なことかしら w?