最近は Plagger いじりの記録と化してるこのブログですが、今日もまた Plagger ネタですよ。
ちょっとやりたいことがあって、Filter::Rule の改造と、Filter::CloneFeed というものを作ってみました。やりたいことが何かというのは長くなるので、後回しにして、まずは Filter::Rule の修正内容と、Filter::CloneFeed の説明を。
Filter::Rule の修正内容はこんな感じです。
Index: plagger/trunk/lib/Plagger/Plugin/Filter/Rule.pm =================================================================== --- plagger/trunk/lib/Plagger/Plugin/Filter/Rule.pm (revision 258) +++ plagger/trunk/lib/Plagger/Plugin/Filter/Rule.pm (revision 259) @@ -19,4 +19,12 @@ sub feed { my($self, $context, $args) = @_; + + if ( defined ( my $expression = $self->conf->{expression} ) ){ + my $status = eval $expression; + if ($@) { + Plagger->context->log(error => "Expression error: $@ with '$expression'"); + } + return unless $status; + } for my $entry ($args->{feed}->entries) {
これにより何ができるかというと、以下のような yaml を書くことで、フィルタを適用するためのルールを設定することができます。
- module: Filter::Rule rule: module: Fresh duration: 60 config: expression: $args->{feed}->type eq 'AmazonWebService'
この例だと、feed type が AmazonWebService であるフィードには Rule::Fresh を適用する、それ以外のフィードには何もフィルタをかけずにそのままにする、という動作になります。
次に Filter::CloneFeed ですが、名前の通りフィードの複製をつくります。で、複製されたフィードは type が clone となります。ソースはこれだけです。
package Plagger::Plugin::Filter::CloneFeed; use strict; use base qw( Plagger::Plugin ); sub register { my($self, $context) = @_; $context->register_hook( $self, 'update.feed.fixup' => \&clone, ); } sub clone { my($self, $context, $args) = @_; my $feed = $args->{feed}->clone; $feed->type('clone'); $context->update->add($feed); } 1;
で、これで何がやりたかったかというと、以下のようなことがやりたかったんです。
- module: CustomFeed::AmazonWebService config: title: Amazon - New Books developer_token: XXXXXXXXXXXXXXXXXXXX associate_id: xxxxxx-22 keywords: - 川原正敏 - module: Filter::CloneFeed - module: Filter::Rule rule: module: Ahead config: expression: $args->{feed}->type eq 'clone' - module: Publish::iCal config: dir: /home/miya/ical filename: %t.ics rule: module: FeedType type: AmazonWebService - module: Publish::Gmail config: mailto: xxx@gmail.com mailfrom: xxx@mizzy.org mailroute: via: smtp host: localhost rule: module: FeedType type: clone
言葉で説明すると、こんな感じです。
要するに、同じフィードでも、Publish プラグイン毎に異なる内容で Publish したかった、というわです。
最初は以下のような yaml で、Publish::iCal では Rule を指定せずに全部吐き出す、Publish::Gmail では Rule::Ahead を適用して、1日以内に発売される商品情報だけ送信、とできるんじゃないかな、と思ったのですが、Publish::Gmail は publish.feed フックで動作していて、Rule でエントリレベルのフィルタリングができないんですよね。
- module: CustomFeed::AmazonWebService config: title: Amazon - New Books developer_token: XXXXXXXXXXXXXXXXXXXX associate_id: xxxxxx-22 keywords: - 川原正敏 - module: Publish::iCal config: dir: /home/miya/ical filename: %t.ics - module: Publish::Gmail config: mailto: xxx@gmail.com mailfrom: xxx@mizzy.org mailroute: via: smtp host: localhost rule: module: Ahead
こういった事情で、Filter::Rule を改造し Filter::CloneFeed をつくってみました。もっとエレガントな方法があれば教えてください。
追記
もっとエレガントな方法教えてもらいました。というか、上でやったことは全くの無駄でした。なので参考にしないでください。