j708の日記 RSSフィード

2006-05-15

おっと

http://b.hatena.ne.jp/miyagawa/20060515#bookmark-1935278

[plagger] これはそう思う、というかどのフェーズでも動けるプラグインは、実行フェーズを指定するオプションがあってもいいのかも

どのフェーズっちゅうことは、update/smartfeed/publishのキャズムをこえなあかんな。

さっきのだけじゃ物足りんわ。

ところでキャズムの使いかたはあってまっか?

たぶんこんなんや

Plagger.pmをこうすればええんや

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,
     );
 }

みんなのプロフィール

ブログ開設おめでとうございます!!

アクセス数を上げるために当コミュニティサイトに登録しませんか?

http://plagger.org/

より多くのひとに貴方のブログを見てもらえます。

参加するにはこちらからが便利です

http://wiki.shibuya.pl/

お問い合わせはコチラから

http://b.hatena.ne.jp/j708/

miyagawamiyagawa 2006/05/15 18:18 >Plaggerはregister_hookで宣言されたhookの先頭のみをruleで見るのでregister_hookの順番には気を使うべき。
ま、それでもいいんですが、
sub rule_hook { ’publish.entry.fixup’ }
とするほうがよりexplicitで正しいです。