2007-03-31
■ [Subscription] Subscription::WWWC

WWWCのデータディレクトリを読み込み,アイテムごとにフィード化する。
WWWCバージョン1.0.4にて動作確認。それ以前のバージョンについては動作未確認。
Plagger/Plugin/Subscription/WWWC.pm
package Plagger::Plugin::Subscription::WWWC; use strict; use base qw( Plagger::Plugin ); use Clone qw( clone ); use Config::Simple; use Encode; use File::Spec; use IO::File; sub register { my ($self, $context) = @_; $context->register_hook( $self, 'subscription.load' => \&load, ); } sub load { my ($self, $context) = @_; return unless $self->conf->{dir}; my @leaves = $self->leaves($self->branch($context, $self->conf->{dir})); for my $leaf (@leaves) { my $feed = Plagger::Feed->new; $feed->url($leaf->{check_url}); $feed->title($leaf->{title}); $feed->link($leaf->{view_url} || $leaf->{check_url}); $feed->meta($leaf->{meta}); $context->subscription->add($feed); } } sub branch { my ($self, $context, $dir) = @_; # meta my $ini = Config::Simple->new(File::Spec->catfile($dir, 'Folder.ini')); my $meta = { wwwc_check_st => $ini->param('CHECK.CheckSt'), }; undef $ini; # dirs opendir DIR, $dir or $context->error("can't open directory: $dir"); my @dirs = map { $self->branch($context, $_) } grep { -d $_ } map { File::Spec->catfile($dir, $_) } grep { $_ ne '.' and $_ ne '..' } readdir DIR; closedir DIR; # items my $io = IO::File->new(File::Spec->catfile($dir, 'Item.dat')); my @items = map { $self->item($_) } $io->getlines; $io->close; undef $io; return { meta => $meta, dirs => \@dirs, items => \@items, }; } sub item { my ($self, $record) = @_; chomp $record; my @fields = split /\t/, $record; return { title => Encode::decode('cp932', $fields[0]), check_url => $fields[1], view_url => $fields[8], meta => { wwwc_check_st => $fields[12], }, }; } sub leaves { my ($self, $branch) = @_; my @leaves = (); push @leaves, $self->leaves($_) for @{$branch->{dirs}}; push @leaves, map { my $leaf = clone($_); $leaf->{meta}->{wwwc_check_st} ||= $branch->{meta}->{wwwc_check_st}; $leaf; } @{$branch->{items}}; @leaves; } 1;
WWWCにおける階層構造は無視される。
各フィードにはメタ情報 wwwc_check_st がセットされる。対応するアイテムがWWWCにおいてチェックされる場合(アイテムそれ自身,およびそれが含まれるディレクトリが,ともに「チェックする」状態の場合)は0が,そうでない場合は1がセットされる。0と1,それぞれが表す状態が直感と異なるのは,WWWCの実装に合わせた結果である。
config.wwwc.yaml
plugins: - module: Subscription::WWWC config: dir: C:\Program Files\WWWC\username\newssite - module: Filter::Rule rule: # expression: !$args->{feed}->meta->{wwwc_check_st} expression: $args->{feed}->meta->{wwwc_check_st} == 0
dir にはWWWCのデータディレクトリへのパスを指定する。dir 以下(サブディレクトリも)に含まれる全てのアイテムがフィード化される。
dir には必ずしもルートに相当するデータディレクトリ(上記例では C:\Program Files\WWWC\username がルート)を指定しなくてもよい。
dir に日本語を含むパスを指定する場合のテストは不十分である。自分の環境(Win2k,ActivePerl 5.8.8 Build 819,Plagger 0.7.16)では,configファイルをUTF-8ではなくシフトJISで保存するとうまくいくようである。
WWWCにおいてはチェックされないアイテムに対応するフィード(のエントリ)を除外したい場合は,Filter::Ruleを上記のように使用する。
expressionがうまく動かなかったので書き替えた。
TODO
WWWCのデータディレクトリ解析部だけ別モジュールにして再利用できそう。WWWC2XBELも作りたいなあ。
あとWWWC関連だと,WWWCのフィルタを読み込んでPlaggerで利用するモジュールもあるといいかも。Filter::WWWCかな。
さらにFilter::Diffも合わせれば,既存のデータを移行することなく,しかもWWWCのフィルタ機能を利用した似非はてなアンテナが作れそう。うわー夢が広がるわー。