Plagger::Plugin::CustomFeed::AmazonWebService

先日の続き。とりあえず動いた。

package Plagger::Plugin::CustomFeed::AmazonWebService;

use strict;
use base qw( Plagger::Plugin );
use Net::Amazon;
use Encode;

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

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

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

    my $feed = Plagger::Feed->new;
    $feed->type('AmazonWebService');

    my $title = $self->conf->{title} || 'Amazon Web Service';
    $feed->title($title);

    my $attr;
    $attr->{token}        = $self->conf->{developer_token};
    $attr->{locale}       = $self->conf->{locale} || 'jp';
    $attr->{affiliate_id} = $self->conf->{associate_id};
    $attr->{max_pages}    = $self->conf->{max_pages} || 1;

    my $mode = $self->conf->{mode} || 'books';
    my $sort = $self->conf->{sort} || 'daterank';

    for my $keyword (@{$self->conf->{keywords}}) {
        my $items = search_aws($context, $attr, $keyword, $mode, $sort);
        next unless $items;

        for my $item ( @$items ) {
            my $entry = Plagger::Entry->new;

            $entry->title($item->Title);
            $entry->body($item->ProductDescription);
            $entry->link($item->url);
            $entry->icon({ url => $item->SmallImageUrl });
            $entry->author($item->author);

            my $date = Plagger::Date->strptime('%Y-%m-%d', $item->ReleaseDate);
            $date = Plagger::Date->strptime('%Y-%m', $item->ReleaseDate) unless $date;
            unless($date){
                $context->log(error => 'Date format is invalid: ' . $item->ReleaseDate);
                next;
            }
            $date->set_time_zone( $context->conf->{timezone} || 'local' );
            $entry->date($date);
            $feed->add_entry($entry);
        }
    }

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

}

sub search_aws {
    my ( $context, $attr, $keyword, $mode, $sort ) = @_;
    my $ua = Net::Amazon->new(%$attr);

    $keyword = encode('UTF-8', $keyword);
    my $response = $ua->search(
        keyword => $keyword,
        mode    => $mode,
        sort    => $sort,
	);

    if($response->is_error) {
        $context->log("er:" . error => $response->message . ": $keyword");
        return;
    }

    my @items = $response->properties;
    return \@items;
}

*Net::Amazon::Property::Music::author = *Net::Amazon::Property::Music::artist;
*Net::Amazon::Property::DVD::author   = sub { return ( $_[0]->starring() )[0] };

1;
__END__
  • Net::Amazon::Request::Keywordを使うやり方だと上手く行かなかったので変えてみた。
  • search_awsの引数で「"$mode-" . $attr->{locale}」として渡しているところを「$mode」だけにした。
  • $item->ProductNameを$item->Titleに変更。
  • $item->ImageUrlSmallを$item->SmallImageUrlに変更。


とりあえずこれでbookは取れるようになったんだけど、DVDだと取り方が全然違う。今後の課題。