root/trunk/plagger/lib/Plagger/Plugin/CustomFeed/FlickrSearch.pm

Revision 896 (checked in by miyagawa, 14 years ago)

refactored CustomFeed?::Flickr

  • Enclosure support
  • Use cache for speed up
Line 
1 package Plagger::Plugin::CustomFeed::FlickrSearch;
2 use strict;
3 use warnings;
4 use base qw( Plagger::Plugin );
5
6 use Flickr::API;
7 use XML::LibXML;
8 use DateTime::Format::Epoch;
9 use Plagger::Enclosure;
10
11 sub register {
12     my($self, $context) = @_;
13     $context->register_hook(
14         $self,
15         'subscription.load' => \&load,
16     );
17 }
18
19 sub load {
20     my($self, $context) = @_;
21
22     my $feed = Plagger::Feed->new;
23     $feed->aggregator(sub { $self->aggregate(@_) });
24     $feed->id('flickr:search');
25     $context->subscription->add($feed);
26 }
27
28 sub aggregate {
29     my($self, $context, $args) = @_;
30
31     my $feed = Plagger::Feed->new;
32     $feed->type('flickr.search');
33     $feed->title("Flickr Search"); # xxx
34     $feed->id('flickr:search'); # xxx
35
36     my $flickr = Flickr::API->new({key => $self->conf->{api_key}});
37     my $method = $self->conf->{method} || 'flickr.photos.search';
38
39     my $params = $self->conf->{params} || {};
40     $params->{per_page} ||= 20;
41
42     $context->log(info => "calling $method on Flickr API");
43     my $search = $self->call_method(
44         $flickr,
45         $method,
46         $params,
47         60 * 60,
48     );
49
50     my $parser = XML::LibXML->new;
51
52     $context->error("$method failed: $search->{error_text}")
53       unless $search->{success};
54     my $search_doc = $parser->parse_string($search->{_content});
55
56     foreach my $search_photo ( $search_doc->findnodes('/rsp/photos/photo') ) {
57         my $entry = $self->_create_entry($context, $flickr, $parser, $search_photo);
58         $feed->add_entry($entry);
59     }
60
61     $context->update->add($feed);
62 }
63
64 sub _create_entry {
65     my ($self, $context, $flickr, $parser, $search_photo) = @_;
66
67     my $photo_id  = $search_photo->findvalue('@id');
68     my $server_id = $search_photo->findvalue('@server');
69     my $secret    = $search_photo->findvalue('@secret');
70
71     my $size      = $self->conf->{size} || 'm';
72     my $thumb_src = sprintf "http://static.flickr.com/%s/%s_%s_t.jpg",
73         $server_id, $photo_id, $secret;
74
75     $context->log(info => "calling flickr.photos.getInfo on $photo_id");
76     my $info = $self->call_method(
77         $flickr,
78         'flickr.photos.getInfo',
79         { photo_id => $photo_id },
80         60 * 60,
81     );
82     next unless $info->{success};
83
84     my $info_doc = $parser->parse_string($info->{_content});
85     my $link     = $info_doc->findvalue(q[/rsp/photo/urls/url[@type='photopage']]);
86     my $author   = $info_doc->findvalue(q[/rsp/photo/owner/@realname])
87                 || $info_doc->findvalue(q[/rsp/photo/owner/@username]);
88     my $title    = $info_doc->findvalue(q[/rsp/photo/title]);
89     my $date     = $info_doc->findvalue(q[/rsp/photo/dates/@posted]);
90     my $format   = $info_doc->findvalue(q[/rsp/photo/@originalformat]) || 'jpg';
91     my $desc     = $info_doc->findvalue(q[/rsp/photo/description]);
92     my @tags     = map $_->textContent, $info_doc->findnodes('/rsp/photo/tags/tag');
93
94     my $original = sprintf "http://static.flickr.com/%s/%s_%s_o.%s",
95         $server_id, $photo_id, $secret, $format;
96     my $epoch = DateTime->from_epoch(epoch => 0, time_zone => '+0000');
97
98     my $entry = Plagger::Entry->new;
99     $entry->title($title);
100     $entry->link($link);
101     $entry->author($author);
102     $entry->body($desc);
103     $entry->date(Plagger::Date->parse('Epoch::Unix', $date));
104     $entry->add_tag($_) for @tags;
105     $entry->icon({ url => $thumb_src });
106
107     my $enclosure = Plagger::Enclosure->new;
108     $enclosure->url($original);
109     $enclosure->auto_set_type;
110     $entry->add_enclosure($enclosure);
111
112     return $entry;
113 }
114
115 sub call_method {
116     my($self, $flickr, $method, $param, $cache) = @_;
117
118     my $cache_key = "$method:" . join("|", map "$_=$param->{$_}", sort keys %$param);
119     $self->cache->get_callback(
120         $cache_key,
121         sub { $flickr->execute_method($method, $param) },
122         $cache,
123     );
124 }
125
126 1;
127
128 __END__
129
130 =head1 NAME
131
132 Plagger::Plugin::CustomFeed::FlickrSearch - Flickr API as Custom Feed
133
134 =head1 SYNOPSIS
135
136   - module: CustomFeed::FlickrSearch
137     config:
138      api_key: YOUR-FLICKR-APIKEY
139      method: flickr.photos.search
140      params:
141        tags: plagger
142
143 =head1 AUTHOR
144
145 Casey West
146
147 Tatsuhiko Miyagawa
148
149 =head1 SEE ALSO
150
151 L<Plagger>, L<http://www.flickr.com/>, L<Flickr::API>
152
153 =cut
Note: See TracBrowser for help on using the browser.