2006-05-15
■おっと
http://b.hatena.ne.jp/miyagawa/20060515#bookmark-1935278
[plagger] これはそう思う、というかどのフェーズでも動けるプラグインは、実行フェーズを指定するオプションがあってもいいのかも
どのフェーズっちゅうことは、update/smartfeed/publishのキャズムをこえなあかんな。
さっきのだけじゃ物足りんわ。
ところでキャズムの使いかたはあってまっか?
■たぶんこんなんや
sub run_hook {
my($self, $hook, $args, $once) = @_;
$hook =~ s/\.(pre|post)$//;
my $hatena = $1;
for my $action (@{ $self->{hooks}->{$hook} }) {
my $plugin = $action->{plugin};
if ($hatena && $hook =~ /(feed|entry)/) {
my $jitensya = $plugin->conf->{jitensya};
$jitensya = $1 eq 'entry' ? 'pre' : 'post' unless $jitensya;
next unless $jitensya eq $hatena;
}
if ( $plugin->rule->dispatch($plugin, $hook, $args) ) {
my $done = $action->{callback}->($plugin, $self, $args);
return 1 if $once && $done;
}
}
# if $once is set, here means not executed = fail
return if $once;
}
そうすればPluginは書き変えなくてすむしワシの大好きな自転車も残る。しかもはてなまで出て来る。
ようは自転車とはてなの意見が食い違ったら動かなくなるわけや。
■よう考えたら
for my $feed ($self->update->feeds) {
for my $entry ($feed->entries) {
$self->run_hook('update.entry.fixup.pre', { feed => $feed, entry => $entry });
}
$self->run_hook('update.feed.fixup.pre', { feed => $feed });
for my $entry ($feed->entries) {
$self->run_hook('update.entry.fixup.post', { feed => $feed, entry => $entry });
}
$self->run_hook('update.feed.fixup.post', { feed => $feed });
}
こんな実装にしといてユーザがconfig.yamlでこのフィルターはpreでーこのフィルターはpostのタイミングで動いてくれやー
と指定できた方がええんちゃう?
smartfeedとpublishでもおなしかんじでもええやな。
そなればOnAggregatorFinalizeがなくなって万々歳やわ。
jitensya入れられなくなって淋しいのは内緒や。
■Filter::HatenaBookmarkUsersCountOnAggregatorFinalize
よう考えたら6usersのエントリだけ欲しいんやからHatenaBookmarkUsersCountの実行フェーズを先にほかせばよいんやった。
ほなら
- module: Filter::HatenaKeywordTag
rule:
expression: $args->{entry}->{meta}->{hatenabookmark_users} eq 6
とか書けて、はてなも万々歳ちゃうやろか?
しかしけったいな名前やなぁ
package Plagger::Plugin::Filter::HatenaBookmarkUsersCountOnAggregatorFinalize;
use strict;
use base qw( Plagger::Plugin );
use XMLRPC::Lite;
sub register {
my($self, $context) = @_;
$context->register_hook(
$self,
'aggregator.finalize' => \&jitensya,
);
}
sub jitensya {
my($self, $context, $args) = @_;
for my $feed ($context->update->feeds) {
$self->update($context, { feed => $feed });
}
}
sub update {
my($self, $context, $args) = @_;
my @permalink = map $_->permalink, $args->{feed}->entries;
$context->log(info => 'Requesting XMLRPC call to Hatena Bookmark with ' . scalar(@permalink) . ' link(s)');
my $map = XMLRPC::Lite
->proxy('http://b.hatena.ne.jp/xmlrpc')
->call('bookmark.getCount', @permalink)
->result;
unless ($map) {
$context->log(warn => 'Hatena Bookmark XMLRPC failed');
return;
}
$context->log(info => 'XMLRPC request success.');
for my $entry ($args->{feed}->entries) {
if (defined(my $count = $map->{$entry->permalink})) {
$entry->meta->{hatenabookmark_users} = $count;
}
}
}
1;
■CacheOnAggregatorFinalize
Cacheだとなんか知らへんけどEntryFullTextが全部動きよるし。
package Plagger::Plugin::CacheOnAggregatorFinalize;
use strict;
use base qw( Plagger::Plugin );
use DB_File;
use Digest::MD5;
sub register {
my($self, $context) = @_;
$context->register_hook(
$self,
'aggregator.finalize' => \&strip,
);
unless ($self->conf->{file}) {
$context->error("please file config");
return;
}
my %cache;
my $a = tie %cache, 'DB_File', $self->conf->{file};
$self->{__cache} = \%cache;
}
sub strip {
my($self, $context, $args) = @_;
for my $feed ($context->update->feeds) {
$self->update($context, { feed => $feed });
}
$self->fixup($context);
}
sub update {
my($self, $context, $args) = @_;
return unless $self->{__cache};
my @entries;
my $feed = $args->{feed};
for my $entry ($feed->entries) {
my $key = $feed->id . '-' . $entry->id_safe;
$key .= $self->check_key('author', $entry->author);
$key .= $self->check_key('title', $entry->title);
my $text = $entry->text;
utf8::encode($text) if utf8::is_utf8($text);
my $value = !$self->conf->{diff_mode} || Digest::MD5::md5_hex($text);
if ($self->{__cache}->{$key}) {
next unless $self->conf->{diff_mode};
next if $self->{__cache}->{$key} eq $value;
}
print "cache: $key $value\n";
$self->{__cache}->{$key} = $value;
push(@entries, $entry);
}
$feed->{entries} = \@entries;
}
sub check_key {
my($self, $flag, $str) = @_;
utf8::encode($str) if utf8::is_utf8($str);
return '-' . Digest::MD5::md5_hex($str) if $self->conf->{$flag} && $str;
return '';
}
sub fixup {
my($self, $context, $args) = @_;
return unless $self->{__cache};
untie %{ $self->{__cache} };
my $update = $context->update;
$context->update( Plagger::Update->new );
for my $feed ($update->feeds) {
$context->update->add($feed) if @{ $feed->entries };
}
}
1;
■hook
# miyagawa 『>Plaggerはregister_hookで宣言されたhookの先頭のみをruleで見るのでregister_hookの順番には気を使うべき。
ま、それでもいいんですが、
sub rule_hook { ’publish.entry.fixup’ }
とするほうがよりexplicitで正しいです。』
そんなグレイトな方法が!
■Filter::StripTags
一度tagsをクリアーしてしまおう!
package Plagger::Plugin::Filter::StripTags;
use strict;
use base qw( Plagger::Plugin );
sub register {
my($self, $context) = @_;
$context->register_hook(
$self,
'update.entry.fixup' => \&update,
);
}
sub update {
my($self, $context, $args) = @_;
$args->{entry}->tags([]);
}
1;
__END__
=head1 NAME
Plagger::Plugin::Filter::StripRSSAd - Strip Tags to Entry
=head1 SYNOPSIS
- module: Filter::StripTags
=head1 DESCRIPTION
=head1 AUTHOR
id:j708
=head1 SEE ALSO
L<Plagger>
=cut
■Plagger Hacks
Filter::HatenaKeywordTagは$bodyが無いとエラるから、実用的じゃないからtitleも追加。
むしろtitleとbody両方でextractしたほうがよさげ。
Publish::HatenaBookmarkは今のままだとentryごとにrule適用できなくて嫌な感じなのでregister_hookの順番をいれかえ。
Plaggerはregister_hookで宣言されたhookの先頭のみをruleで見るのでregister_hookの順番には気を使うべき。ただし、ごにょごにょするとこの条件は正しくない。
Index: Filter/HatenaKeywordTag.pm
===================================================================
--- Filter/HatenaKeywordTag.pm (revision 744)
+++ Filter/HatenaKeywordTag.pm (working copy)
@@ -16,7 +16,7 @@
my $title = $args->{entry}->title;
my $body = $args->{entry}->body;
Encode::_utf8_off($body); # Hatena::Keyword's Bug?
- my $keywords = Hatena::Keyword->extract($body);
+ my $keywords = Hatena::Keyword->extract("$title$body");
my @terms = sort { $a->refcount <=> $b->refcount } @$keywords;
for my $term (@terms) {
Index: Publish/HatenaBookmark.pm
===================================================================
--- Publish/HatenaBookmark.pm (revision 744)
+++ Publish/HatenaBookmark.pm (working copy)
@@ -11,8 +11,8 @@
my($self, $context) = @_;
$context->register_hook(
$self,
+ 'publish.entry.fixup' => \&add_entry,
'publish.init' => \&initialize,
- 'publish.entry.fixup' => \&add_entry,
);
}
■みんなのプロフィール
ブログ開設おめでとうございます!!
アクセス数を上げるために当コミュニティサイトに登録しませんか?
より多くのひとに貴方のブログを見てもらえます。
参加するにはこちらからが便利です
お問い合わせはコチラから


ま、それでもいいんですが、
sub rule_hook { ’publish.entry.fixup’ }
とするほうがよりexplicitで正しいです。