最近は 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 をつくってみました。もっとエレガントな方法があれば教えてください。
追記
もっとエレガントな方法教えてもらいました。というか、上でやったことは全くの無駄でした。なので参考にしないでください。