SweetPotato::Plagger このページをアンテナに追加 RSSフィード

2006-11-19

[] CustomFeed::Manganomori 21:08  CustomFeed::Manganomori - SweetPotato::Plagger を含むブックマーク はてなブックマーク -  CustomFeed::Manganomori - SweetPotato::Plagger  CustomFeed::Manganomori - SweetPotato::Plagger のブックマークコメント

Web::Scraperを使って書き直した。

まんがの森新刊コミックリストを取得し,単行本ごとにエントリ化する。

Plagger/Plugin/CustomFeed/Manganomori.pm

リファクタリングと無駄省きをした。以下の記事を参照。

「旬」の表記が「(上|中|下)旬」から単純な「(上|中|下)」に変わった模様。それに対応すると同時に,「(上|中|下)旬」に戻られても困るから正規表現で判断するようにした。

モジュール内で日本語を使用しているのでUTF-8(BOMなし)で保存すること。

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

use Plagger::Date;
use Plagger::Util;
use Switch;
use URI;

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

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

    my $date = $self->conf->{month}
             ? Plagger::Date->strptime("%Y.%m", $self->conf->{month})
             : Plagger::Date->now();
    my $id = ($date->year - 2003) * 12 + $date->month - 4; # month=2003.5 -> id=1

    my $feed = Plagger::Feed->new;
    $feed->aggregator( sub { $self->aggregate($context, $id); });
    $context->subscription->add($feed);
}

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

    my $content = Plagger::Util::load_uri(URI->new("http://www.manganomori.net/list.asp?listid=$id"));

    my ($year, $month) = ($content =~ m!<font color="#FF0000"><b>(\d{4})\.(\d{2})</b></font>!);
    if (!$year || !$month) {
        Plagger->context->log(error => "List not found in http://www.manganomori.net/list.asp?listid=$id");
        return;
    }

    my $feed = Plagger::Feed->new;
    $feed->link("http://www.manganomori.net/list.asp?listid=$id");
    $feed->title("まんがの森 コミックリスト $year.$month");

    my $list = $self->parse($content);
    for my $item (@$list) {
        my $entry = Plagger::Entry->new;
        $entry->title($item->{title});
        $entry->author($item->{author});
        $entry->tags([$item->{publisher}]);
        $entry->body("$item->{author}, $item->{publisher}, $item->{price}");

        if ($item->{day} !~ /\d+/) {
            $entry->body("$item->{day}, ".$entry->body);
            $item->{day} = $self->part_to_day($item->{day});
        }
        $entry->date(Plagger::Date->strptime("%Y/%m/%d", "$year/$month/$item->{day}"));

        $feed->add_entry($entry);
    }

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

sub parse {
    my ($self, $content) = @_;

    my $list = [];
    my $publisher;
    while ($content =~ m!<tr bgcolor="#(.*?)">(.*?)</tr>!gs) {
        my ($color, $item) = ($1, $2);
        if ($color eq "FF00FF") { # publisher
            $publisher = ($item =~ m!<b>(.*?)</b>!)[0];
        } elsif ($item =~ m{
            <td.*?</td>
            .*?<td.*?>(.*?)</td>
            .*?<td.*?>(.*?)</td>
            .*?<td.*?>(.*?)</td>
            .*?<td.*?>(.*?)</td>
        }sx) { # comic
            push @$list, {
                day => $1, title => $2, author => $3, price => $4,
                publisher => $publisher,
            };
        }
    }

    $list;
}

sub part_to_day {
    my ($self, $part) = @_;

    switch ($part) {
        case /<e4><b8><8a>/ { return "01"; }
        case /<e4><b8><ad>/ { return "11"; }
        case /<e4><b8><8b>/ { return "21"; }
    }

    "01";
}

1;

config.manganomori.comiclist.yaml

plugins:
  - module: CustomFeed::Manganomori
    config:
      month: 2006.11

monthには取得したいコミックリストの年月を %Y.%m 形式で指定する。指定しない場合は今月のコミックリストを取得する。

スクリーンショット1(Publish::iCal + Google Calendar)

f:id:SweetPotato:20061119211804p:image

スクリーンショット2(Publish::iCal + Google Calendar)

f:id:SweetPotato:20061119211753p:image

関連リンク