Kentaro Kuribayashi's blog

Software Engineering, Management, Books, and Daily Journal.

はてなアンテナの RSS を OPML に変換して、livedoor Reader に移行する

わりとどうでもいいネタ。ってか、昔「はてなアンテナの lirs ファイルを OPML に変換する(パクリ注意!)」とかゆって、既に書いてたりするけど。んでもってさらに、「はてなアンテナからの移行 - livedoor Reader まとめサイト - livedoor Wiki(ウィキ)」に書かれてるやり方の方が簡単だし!!!
ともあれ、サイトの更新チェックにはもっぱらはてなアンテナを使っている id:eureka さんが、僕が「livedoor Reader 最高過ぎる!!!」とゆってるので気になったらしく、「はてなアンテナから LDR にデータを移行できないの?」との質問。あー、んじゃちと待てば、はてなアンテナRSS から OPML に変換するスクリプト書くよー、ってんでスクリプトを書き始めた。
途中、そういえば昔「critical angle: Bloglinesスクリプト」なんつって、はてなアンテナの lirs を OPML に変換するサービスがあったなーってのを思い出して試したところ、OPML の outline 要素の xmlurl 属性の url ってのが、LDR 的には Url と最初が大文字じゃないとマズいらし。生成された OPML をエディタで開き、一括置換して対応。インポートしてみると、どうもうまくいったんだかどうなのかよくわかんない状況になってしまった。
まぁいいやってんで、スクリプト書き続行。上記サービスはフィードの URI をサービスごとの URI 規則から類推して生成してるのだけど、作られたのがもう 2 年も前のものなのでその後事情も変わってるだろうってんで、Feed::Find を使って Auto-Discovery ってみることに。
そんなこんなでできたのが以下のスクリプト。生成される OPML はなんかショボい感じだけど、LDR へのインポート自体はうまくいったのでまぁいいやってな感じ。

#!/usr/bin/perl

use strict;
use warnings;
use Readonly;
use XML::OPML;
use Feed::Find;
use LWP::Simple ();
use XML::RSS::LibXML;
use Unicode::RecursiveDowngrade;

Readonly my $rss_uri   => 'http://a.hatena.ne.jp/eureka/rss';
Readonly my $opml_file => 'my_subscriptions.opml';

my $opml = XML::OPML->new(version => '1.1');
$opml->head(
    title => 'my subscriptions',
    ownerName => 'foo bar',
    ownerEmail => 'baz@example.com',
);

my $data = LWP::Simple::get($rss_uri);
my $rss  = XML::RSS::LibXML->new;
$rss->parse($data);

for my $item (@{$rss->{items}}) {
    if (my @feeds = Feed::Find->find($item->{link})) {
        $opml->add_outline(
                 title   => $item->{title},
                 type    => 'rss',
                 htmlUrl => $item->{link},
                 xmlUrl  => $feeds[0],
        );
        print "add outline for ".$item->{link}."\n";
    }
}

$opml = Unicode::RecursiveDowngrade->new->downgrade($opml);
$opml->save($opml_file);

exit;