日記/2009-3-1
RSS関連(RSS1.0、RSS2.0、Atom0.3)プラグインの修正
「世紀末キッズのためのSF100冊」で使ってみて、FreeStyleWikiの本家のサイトに投稿されているRSS関連(RSS1.0、RSS2.0、Atom0.3)プラグインの、rss プラグインに、以下のような不具合を見つけました。
- 与えるRSSフィードのURIが長すぎるとエラーになる
- フィードのアイテム数が1つしかないとエラーになる
まず、1.について。
RSS情報をキャッシュする際、RSSフィードのURIをそのままURIエンコードしてファイル名を作り、このファイル名でRSS情報を保存しようとするのですが、当然ながらURIが長いとキャッシュのファイル名もその分長くなり、それがあんまり長い(ファイルシステムによるようですが、だいたい255バイトまで)と File name too long と怒られてしまいます。
これを避けるため、MD5でとったURIのハッシュをファイル名に使うようにしました(下記のdiffの出力の50行目あたりからの変更に対応)。
次に2.について。
RSSフィードのアイテム数というんでしょうか、例えばRSS2.0の場合だと、フィードの構造は以下のような感じですが、
<?xml version="1.0" encoding="UTF-8" ?> <rss version="2.0"> <channel> <title> TITLE </title> <link> LINK </link> <description> DESCRIPTION </description> <language>ja</language> <ttl>120</ttl> <copyright>Copyright (C) 2009 XXXXXX</copyright> <lastBuildDate>Sun, 01 Mar 2009 11:31:05 +0900</lastBuildDate> <item> <title> TITLE </title> <link> LINK </link> <description> DESCRIPTION </description> <pubDate>Wed, 26 Dec 2007 01:38:40 +0900</pubDate> </item> <item> <title> TITLE </title> <link> LINK </link> <description> DESCRIPTION </description> <pubDate>Wed, 15 Aug 2007 00:40:23 +0900</pubDate> </item> </channel> </rss>
上記の例だと2つある<item>のタグでくくられている要素が1つしかないと、Not an ARRAY reference at plugin/rss2/Aggregater.pm line 136 と怒られてしまいます。
これを避けるために、XML::TreePPのforce_arrayプロパティを指定して、<item>、および、<entry>というタグでくくられた要素は必ず配列としてパースされるようにしました(下記のdiffの出力の95行目あたりからの変更に対応)。
以下が、FreeStyleWikiの本家のサイトのRSS関連(RSS1.0、RSS2.0、Atom0.3)プラグインのページに添付された、rss2_20061224.zip に含まれるファイル Aggregater.pm と、今回の修正を施したファイルとの差分です。
--- Aggregater.pm.org 2006-10-16 13:22:00.000000000 +0900 +++ Aggregater.pm 2009-03-01 10:03:20.799000000 +0900 @@ -50,7 +50,8 @@ return &Util::paragraph_error("RSSのURLが指定されていません。"); } my $filename = $url; - my $cache = $wiki->config('log_dir')."/".&Util::url_encode($filename).".rss"; + my $cache = &Util::url_encode($filename); + $cache = $wiki->config('log_dir')."/".&Util::md5($cache).".rss"; my $readflag = 0; if(-e $cache){ @@ -95,6 +96,7 @@ EOM my $tpp = XML::TreePP->new(); + $tpp->set(force_array => [ "item","entry" ]); my $tree = $tpp->parse( $content ); my $ver = "RSS1.0";
参考
- BugTrack-plugin/325 RSS関連(RSS1.0、RSS2.0、Atom0.3)プラグイン
- これが元のプラグイン。便利に使っています。ありがとうございます。
- [Perl] XML::TreePP/Pure Perl実装によるXMLファイル展開モジュール
- XML::TreePPの作者のページ。XML::TreePPについて日本語でわかりやすく解説されています。ありがとうございます。
追記
- 本家のページにもコメントしておきました。