root/lang/perl/misc/flickr_fetcher.pl @ 27874

Revision 27874, 4.1 kB (checked in by yusukebe, 4 years ago)

四捨五入してた><

  • Property svn:executable set to *
Line 
1#!/usr/bin/perl
2
3package FlickrFetcher;
4
5use Moose;
6use Moose::Util::TypeConstraints;
7use Params::Coerce ();
8
9use Digest::MD5 qw(md5_hex);
10use Encode;
11use LWP::UserAgent;
12use Path::Class;
13use POSIX qw(ceil);
14use WebService::Simple;
15use WebService::Simple::Parser::XML::Simple;
16use XML::Simple;
17use Perl6::Say;
18
19our $VERSION = '0.01';
20
21with 'MooseX::Getopt';
22
23subtype 'Dir' => as 'Object' => where { $_->isa('Path::Class::Dir') };
24coerce 'Dir'  => from 'Str'  => via   { Path::Class::Dir->new($_) };
25
26MooseX::Getopt::OptionTypeMap->add_option_type_to_map( 'Dir' => '=s' );
27
28has 'keyword' => ( is => 'rw', isa => 'Str', required => 1 );
29has 'dir' => ( is => 'rw', isa => 'Dir', required => 1, coerce => 1 );
30has 'api_key'  => ( is => 'rw', isa => 'Str' );
31has 'license'  => ( is => 'rw', isa => 'Int' );
32has '_perpage' => ( is => 'ro', isa => 'Int', default => 500 );
33has '_flickr'  => ( is => 'rw', isa => 'WebService::Simple' );
34has '_ua' => (
35    is      => 'ro',
36    isa     => 'LWP::UserAgent',
37    default => sub { LWP::UserAgent->new( keep_alive => 1 ) }
38);
39
40sub BUILD {
41    my ( $self, $args ) = @_;
42
43    unless ( $self->api_key ) {
44        if ( my $api_key = $ENV{FLICKR_API_KEY} ) {
45            $self->api_key($api_key);
46        }
47        else {
48            die "api_key is required\n";
49        }
50    }
51
52    my $xs = XML::Simple->new( KeepRoot => 1, keyattr => [] );
53    my $parser = WebService::Simple::Parser::XML::Simple->new( xs => $xs );
54    my $flickr = WebService::Simple->new(
55        base_url        => "http://api.flickr.com/services/rest/",
56        param           => { api_key => $self->api_key },
57        response_parser => $parser,
58    );
59    $self->_flickr($flickr);
60}
61
62__PACKAGE__->meta->make_immutable;
63no Moose;
64
65sub run {
66    my $self = shift;
67    mkdir $self->dir->relative if !-d $self->dir->is_absolute;
68    say "search keyword : " . $self->keyword;
69    my $photo_total = $self->photo_total( $self->keyword );
70    say "total count : " . $photo_total;
71    my $pages = ceil( $photo_total / $self->_perpage );
72    for my $current_page ( 1 .. $pages ) {
73        say "search page : $current_page";
74        $self->search( $self->keyword, $current_page, $self->_perpage );
75    }
76}
77
78sub search {
79    my ( $self, $keyword, $page , $perpage) = @_;
80    my $response = $self->_flickr->get(
81        {
82            method   => "flickr.photos.search",
83            text     => $keyword,
84            per_page => $perpage,
85            sort     => 'date-posted-desc',
86            extras   => 'date_upload',
87            page  => $page,
88            license => $self->license || "",
89        }
90    );
91    my $xml = $response->parse_response;
92    $self->fetch($xml->{rsp}->{photos}->{photo});
93}
94
95sub fetch {
96    my ( $self, $photo_ref ) = @_;
97    for my $photo ( @$photo_ref ){
98        my $url  = $self->photo_url( $photo->{id} );
99        my $file = $self->dir->file( md5_hex($url) . ".jpg" );
100        my $res  = $self->_ua->mirror( $url, $file );
101        say "try to fetch : " . $res->status_line . " : $url";
102    }
103}
104
105sub photo_url {
106    my ( $self, $photo_id ) = @_;
107    my $response = $self->_flickr->get(
108        {
109            method   => "flickr.photos.getSizes",
110            photo_id => $photo_id
111        }
112    );
113    my $xml         = $response->parse_response;
114    my $largest_ref = pop @{ $xml->{rsp}->{sizes}->{size} };
115    return $largest_ref->{source};
116}
117
118sub photo_total {
119    my ( $self, $keyword ) = @_;
120    my $response = $self->_flickr->get(
121        {
122            method   => "flickr.photos.search",
123            text     => $keyword,
124            per_page => 1,
125            license => $self->license || "",
126        }
127    );
128    my $xml = $response->parse_response;
129    return $xml->{rsp}->{photos}->{total};
130}
131
132package main;
133
134my $fetcher = FlickrFetcher->new_with_options();
135$fetcher->run();
136
137__END__
138
139=head1 NAME
140
141flickr_fetcher.pl - Fetch Flickr photos by keyword
142
143=head1 SYNOPSIS
144
145./flickr_fetcher.pl --keyword hoge --dir hoge --api_key yourflickrapikey
146
147=head1 AUTHOR
148
149Yusuke Wada E<lt>yusuke (at) kamawada.comE<gt>
150
151=head1 LICENSE
152
153This library is free software; you can redistribute it and/or modify
154it under the same terms as Perl itself.
155
156=cut
157
Note: See TracBrowser for help on using the browser.