理系学生日記

おまえはいつまで学生気分なのか

Read It Later から直接はてブ登録する

この間、iPhone 上の Read It Later アプリから Twitter にツイートする運用を行い、そのツイートを捕捉の上ではてブするというスクリプトを書いたのですが、よく考えなくても、Read It Later から直接はてブすれば良いではないかということに気付きました。
つまり、API 経由で Read It Later の「後で読む」リストからエントリを抽出し、はてブ API ではてブに登録してしまうスクリプトさえあれば良いのです!!

Read It Later アプリの UI を確認しましょう

iPhone の Read It Later アプリでは、「後で読む」リストの一覧画面をフリックすることで、(Read It Later 上の)タグ編集を行う画面に遷移できます。

下の画面がフリック直後。ここで、背景色が黒くなっている行の左側にある鉛筆のアイコンをクリックします。

すると、以下のようなタグ入力画面に以降します。頻出のタグは、ボタンから選ぶことができますし、そうでないタグは自分で入力することになります。タグの区切りは、スペースではなく、カンマになります。

つくりましょう

Read It Later には、リスト取得用の API が用意されているため、容易に「あとで読む」リストから自分の欲しいエントリの情報を取得することができます。
実際に使用するのは get API ですが、それなりに取得条件を指定することが可能です。

key 備考
state 既読、未読、全ての三択
myAppOnly 特定 App で保存されたエントリのみを取得
since 指定したエポック秒以降に追加/更新されたエントリのみを取得
count 取得するエントリ数を指定
tags タグ情報も一緒に取得するかどうかを指定

ここでは、「bookmark」タグを持つ「未読」エントリを抜き出せば良さそうです。従って、

  • state
  • tags

を API パラメータとして送れば良さそうですね。
しかし、実際に取得する際は「bookmark タグを持つエントリだけ取得する」という条件を API で指定することはできないため、since で「更新が 1 時間以内」という条件を加えておき、取得後にタグでフィルタリングをかけることにします。

自分の「後で読む」リストを取得するときは、一旦以下のようにします。エラー処理がぬけています。

sub run {
    my ($self) = @_;

    my $now = localtime;                # gets Time::Piece object 
    my $one_hour_ago = $now - ONE_HOUR; # ONE_HOUR is defined in Time::Seconds

    # $self->{ril} is WebService::RIL object.  ref: https://github.com/kiririmode/WebService-RIL
    my $response = $self->{ril}->get_list( 
	since => $one_hour_ago, 
	tags => 1, 
	state => 'unread'
    );
    my $list = $response->list();

    $self->_add_bookmarks(@$list);
}

タグによるフィルタリングとはてブ登録は、_add_bookmarks メソッドで実施することにしました。

sub _add_bookmarks {
    my ($self, @list) = @_;

    # extract entries which contains a 'bookmark' tag.
    my @candidates = grep { 
	any { $_ eq 'bookmark' } @{ $_->{tags} }
    } @list;

    foreach my $item (@candidates) {
        # exclude 'bookmark' tag
	my $tags = [ grep { $_ ne 'bookmark' } @{$item->tags} ];

	try {
            # $self->{hb} is WebService::Hatena::Bookmark::Lite object
	    $self->{hb}->add(
		url => $item->url,
		tag => $tags,
	    );
	    $self->{ril}->read_pages($item->url);
	}
	catch {
	    warnf( "error in bookmarking %s: %s", $item->url, $_ );
	};

    }
}

このようなものを App::RIL2HB モジュールとして切り出し、それを呼ぶスクリプトを作成しています。

#!/usr/bin/env perl
use strict;
use warnings;
use App::RIL2HB;
use Config::Pit;

my $app = App::RIL2HB->new({ 
    ril => pit_get('ril'),
    hb  => pit_get('www.hatena.ne.jp'),
});
$app->run();

これを cron 化しておけばよさそうですね。