XML::FeedモジュールでRSS

たぬき'ライブラリーは、私のiMacの中で動いているCGIのデータベースのうち、著作権に抵触しないと思われる内容について公開するというもので、perlで作ってます。
AtomxmlファイルもPerlで吐き出しているのですが、perlスクリプトの中身はこんな感じです。

use XML::Feed;

local @memo_file = glob("./data/memo*\.txt"); 
local $memo_file_length = @memo_file;
if($memo_file_length){
 local $rss = XML::Feed->new('Atom',encode_output => 0);
 $rss->title("たぬき\'ライブラリー");
 $rss->link("http://www.eonet.ne.jp/~ta-nuki/lib/index.html");
 $rss->description("今日まで特に 気にもとめないでいた そんなことが確かになる");
 $rss->language("ja");
 local %memos;
 for(local $i = 0;$i < $memo_file_length;$i++){
  local @file_stat = stat $memo_file[$i];
  $memos{$memo_file[$i]} = $file_stat[9];
 }
 local @sorted_memo = sort { $memos{$b} cmp $memos{$a} } keys %memos;
 $rss->modified(DateTime->from_epoch(time_zone =>'Asia/Tokyo',epoch =>$memos{$sorted_memo[0]} ));
 for(local $i = 0;$i < 20;$i++){
  local @print_memo = ("title","memo");
  local ($print_memo_url) = $sorted_memo[$i] =~ /^(memo.*?)\.txt$/;
  $print_memo_url = "http://www.eonet.ne.jp/~ta-nuki/lib/" .$print_memo_url .".html";
  local $rss_entry = XML::Feed::Entry->new("Atom");
  $rss_entry->title($print_memo[0]);
  $rss_entry->summary($print_memo[1]);
  $rss_entry->link($print_memo_url);
  $rss_entry->modified(DateTime->from_epoch(time_zone =>'Asia/Tokyo',epoch =>$memos{$sorted_memo[$i]} ));
  $rss->add_entry($rss_entry);
 }
 open(RSS_FILE,">","memo.xml") or die("Cannot Open memo.xml");
 print RSS_FILE $rss->as_xml; 
 close(RSS_FILE); 
}
exit;

最初にglobでメモのファイルの一覧を取得し、次の行でメモのファイルの数を確認しています。

XML::Feed->newのパラメーターに"encode_output => 0"を入れないと、日本語の文字が実体参照に置き換えられてしまうのがハマりどころ。

その後、forループ内でstatを使ってファイルの情報を取得してます。stat で得られたファイル情報のうち、[9]が最終更新時刻なので、今回はこれだけを使います。

forループを抜けたらsortで、ファイルの最終更新時刻でファイル名を並べ替えています。

次の行で、一番新しいファイルの更新時刻をフィードの最終更新時刻(modified)に設定しています。
この時、時刻の指定はDateTimeのオブジェクト形式で指定しないといけないので、注意。

@print_memoは、本当はファイルをopenして読み込んでいますが、その処理は割愛。
次の行の$print_memo_urlの宣言は、宣言と同時に、ファイル名からURLにするための文字列を抽出しています。そして、次の行で、ちゃんとしたURLにするために文字列と連結。文字列の連結は"+"ではなく"."を使います。

XML::Feed::Entry->newで、新しい項目を作成。
$rss->add_entry($rss_entry);
で、作成中のRSSの本体に、この項目を追加します。

最後に作ったRSSを、memo.xmlファイルに出力してます。

と、ハマりどころが、たくさんあって、思っていた以上に手間取りました。。。