複数のfeedをマージするには
plugins: - module: Subscription::Config config: feed: - http://www.ibm.com/news/jp/ja/index.rss - http://h50205.www5.hp.com/rss/w_new.xml - http://wdirect.apple.com/jp/home/2008/ticker.rss - module: SmartFeed::All - module: Publish::Feed config: format: RSS dir: /tmp filename: merged_rss.xml
で、これだと指定した3フィードが時刻の新しい順に並ぶ。
これをたとえば、IBM、HP、Appleの各最新記事、IBM、HP、Appleの各2番目の最新記事、以下同様、という順番にしたいときはどうするか?
Plagger::Feedを読んだら、エントリのソート方法をカスタマイズする手段はまだないようなので、Plagger::Plugin::SmartFeed::Allのサブクラスを作成することにした。
plugins: - module: Subscription::Config config: feed: - http://www.ibm.com/news/jp/ja/index.rss - http://h50205.www5.hp.com/rss/w_new.xml - http://wdirect.apple.com/jp/home/2008/ticker.rss - module: SmartFeed::Rotate - module: Publish::Feed config: format: RSS dir: /tmp filename: rotate_merged_rss.xml
All.pmのサブクラスRotate.pmは以下の通り。
package Plagger::Plugin::SmartFeed::Rotate; use strict; use base qw( Plagger::Plugin::SmartFeed::All ); sub feed_finalize { my($self, $context, $args) = @_; $self->{feed} = rotate_sort($self->{feed}); $context->update->add($self->{feed}) if $self->{feed}->count; } # # 各ホストを巡回するかたちでソート # sub rotate_sort { my $feed = shift; my @entries = map { $_->[2] } sort { $a->[0] <=> $b->[0] || $b->[1] <=> $a->[1] } map { [ _seq_by_host($_), $_ ] } $feed->entries; $feed->{entries} = \@entries; $feed; } # # エントリのホスト別連番とホスト名を返す # sub _seq_by_host { my $entry = shift; our %seq; my $u = URI->new($entry->source->url); my $host = lc($u->host); $seq{$host}++; my @a = ($seq{$host}, $host); } 1;