閑古鳥

オールドプログラマの日記。プログラミングとか病気(透析)の話とか。

Amazon2iCal(2) 書き直した

  • なんとなく名前を変更
  • customfeed.handleをフックするのをやめてsubscription.loadをフックするようにした
  • 「発売日が一ヶ月以上前の商品を省く」という処理はやめた
    • 必要に応じてRuleを使う
  • GitHub Pages · File Not Found · GitHubのソースを反映
    • でも自分の環境では逆にencodeすると検索に失敗してしまうので(最初のソースもencodeするようにしていたんですがこれが原因で消していた)、ここはオプションで指定する形に

config

plugins:
  - module: CustomFeed::AmazonWebService
    config:
      developer_token: XXXXXXXXXXXXX
      keywords:
        - げんしけん
        - Perl
      mode: books-jp
      locale: jp
      keyword_encoding: 0

  - module: Filter::Rule
    rule:
      module: Fresh
      duration: 43200

  - module: Publish::iCal
    config:
      dir: /Users/user/Sites/plagger/amazon/
      filename: books.ics

CustomFeed::AmazonWebService

package Plagger::Plugin::CustomFeed::AmazonWebService;
use strict;
use base qw( Plagger::Plugin );
use Net::Amazon;
use Net::Amazon::Request::Keyword;
use Encode;

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

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

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

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

    for my $keyword (@{$self->conf->{keywords}}) {
        $self->_search($context, $keyword);
    }
}

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

    my $ua  = Net::Amazon->new(
        token     => $self->conf->{developer_token},
        locale    => $self->conf->{locale},
    );

    $keyword = encode('UTF-8', $keyword) if $self->conf->{keyword_encoding};
    my $req = Net::Amazon::Request::Keyword->new(
        keyword => $keyword,
        mode    => $self->conf->{mode},
        sort    => "daterank",
    );

    my $res = $ua->request($req);
    if($res->is_error) {
        $context->log(error => $res->message);
        return;
    }

    my $feed = Plagger::Feed->new;

    for my $prop ($res->properties) {
        my $e = Plagger::Entry->new;
        $e->title($prop->ProductName);
        $e->body($prop->ProductDescription);

        my $date = Plagger::Date->strptime("%Y/%m/%d", $prop->ReleaseDate);
           $date = Plagger::Date->strptime("%Y/%m", $prop->ReleaseDate) unless $date;
        next unless $date;

        $e->date($date);

        $feed->add_entry($e);
    }

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

1;

日付の取得に失敗するのは、フォーマットが年だけになってたりするのかな……。