Seacolor Labs. このページをアンテナに追加 RSSフィード

2006-08-08

[] CustomFeed::Config対応に 22:34  CustomFeed::Config対応に - Seacolor Labs. を含むブックマーク はてなブックマーク -  CustomFeed::Config対応に - Seacolor Labs.  CustomFeed::Config対応に - Seacolor Labs. のブックマークコメント

 Subscription::SoftAntennaとSubscription::VersionUpInfoをworemacxの日記 - yaml で簡単なレシピを書ける CustomFeed プラグインレシピにしてみました。

 after_hookとencodeの設定ができなかったのでついでにCustomFeed::ConfigをHack。

Plagger::Plugin::CustomFeed::Config

package Plagger::Plugin::CustomFeed::Config;
use strict;
use base qw( Plagger::Plugin );

use DirHandle;
use YAML;
use Encode;
use HTML::TokeParser;
use Plagger::UserAgent;
use Plagger::Util qw( decode_content extract_title );
use URI;
use URI::QueryParam;

sub init {
    my $self = shift;
    $self->SUPER::init(@_);
    $self->load_plugins;
}

sub load_plugins {
    my $self = shift;

    my $dir = $self->assets_dir;
    my $dh = DirHandle->new($dir) or Plagger->context->error("$dir: $!");
    for my $file (grep -f $_->[0] && $_->[1] =~ /\.yaml$/,
                  map [ File::Spec->catfile($dir, $_), $_ ], sort $dh->read) {
        $self->load_plugin(@$file);
    }
}

sub load_plugin {
    my($self, $file, $base) = @_;

    Plagger->context->log(debug => "loading $file");
    push @{$self->{plugins}}, YAML::LoadFile($file);
}

sub register {
    my($self, $context) = @_;
    $context->register_hook(
        $self,
        'customfeed.handle' => \&handle,
    );
}

sub handle {
    my($self, $context, $args) = @_;

    my $orig = $args->{feed}->url;
    my $count = 0;

    for my $plugin (@{$self->{plugins}}) {
        my $match = $plugin->{match} || '.'; # anything
        next unless $args->{feed}->url =~ m/$match/i;
        if ($args->{feed}->url =~ m!^$match!
            && $args->{feed}->url !~ /output=(?:rss|atom)/) {
            $args->{plugin} = $plugin;
            $self->aggregate($context, $args);
            return 1;
        }
    }
    return;
}

sub aggregate {
    my($self, $context, $args) = @_;

    my $url = URI->new($args->{feed}->url);
    my $plugin = $args->{plugin};

    if ($plugin->{fetch_before_hook}) {
        eval $plugin->{fetch_before_hook};
        Plagger->context->error($@) if $@;
    }

    $context->log(info => "GET $url");

    my $agent = Plagger::UserAgent->new;
    my $res = $agent->fetch($url, $self);

    if ($res->http_response->is_error) {
        $context->log(error => "GET $url failed: " . $res->status_code);
        return;
    }

    my $content = decode_content($res);
    my $title   = extract_title($content);

    my $feed = Plagger::Feed->new;
    $feed->title($plugin->{extract_encode} ? decode($plugin->{extract_encode}, $title) : $title);
    $feed->link($url);

    if ($plugin->{extract_before_hook}) {
        eval $plugin->{extract_before_hook};
        Plagger->context->error($@) if $@;
    }

    while ($content =~ /$plugin->{extract}/sg) {
        if (my @match = $& =~ /$plugin->{extract}/s) {
            my @capture = split /\s+/, $plugin->{extract_capture};
            my $data;
            @{$data}{@capture} = @match;

            if ($plugin->{extract_after_hook}) {
                eval $plugin->{extract_after_hook};
                Plagger->context->error($@) if $@;
            }

            my $entry = Plagger::Entry->new;
            $entry->title($plugin->{extract_encode} ? decode($plugin->{extract_encode}, $data->{title}) : $data->{title});
            $entry->link($data->{link});
            if ($data->{body}) {
                $entry->body($plugin->{extract_encode} ? decode($plugin->{extract_encode}, $data->{body}) : $data->{body});
            }
            $feed->add_entry($entry);
        }
    }

    $context->update->add($feed);

    return 1;
}

1;

assets/plugins/CustomFeed-Config/SoftAntenna.yaml

match: http://www\.softantenna\.com/index\.html
extract: <li class=saitem><strong><a href="(https?://[^"]*)">(.*?)</a>[^\n]+</a>(.*?)</span><br>\n<span class=small>(.*?)</span>\n
extract_capture: link title1 title2 body
extract_encode: iso 2022-jp
extract_after_hook: $data->{title} =  $data->{title1} . $data->{title2}

assets/plugins/CustomFeed-Config/VersionUpInfo.yaml

match: http://www2s\.biglobe\.ne\.jp/~takao777/versionupinfo/index\.html
extract: <li><a href="(.*?)" target="_blank">(.*?)</a>(.*?)<!--[^\n]*-->(.*?)<(tt|em)>(.*?)</\5>
extract_capture: link title1 title2 body1 null body2
extract_after_hook: |
  $data->{title} =  $data->{title1} . $data->{title2};
  $data->{body} =  $data->{body1} . $data->{body2};