Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
FlickrDownload.pl:
#!/usr/bin/perl use strict; use warnings; use Digest::MD5 qw(md5_hex); use Config::Simple; use Image::ExifTool; use File::MimeInfo::Magic qw(mimetype extensions); use Flickr::API::Photos; use Flickr::Person; use Getopt::Std; use HTML::Entities (); use File::MimeInfo::Magic; use IO::Scalar; use LWP; use Tie::File::AsHash; use XML::Parser::Lite::Tree::XPath; ############################## my $cfg = new Config::Simple('FlickrDownload.ini'); my $user_name; my $id; my $email; my %arg_options; my $photo_directory; my $found; getopts('e:i:u:', \%arg_options); $user_name = $arg_options{u}; $id = $arg_options{i}; $email = $arg_options{e}; my $flickr_api_key = $cfg->param('Flickr.API_KEY'); my $flickr_secret = $cfg->param('Flickr.API_SHARED_SECRET'); my $flickr_email = $cfg->param('Flickr.email'); my $flickr_password = $cfg->param('Flickr.password'); ############################## sub decode_html { my $string = shift; my $new_string = HTML::Entities::decode($string); if ($string ne $new_string) { $new_string = decode_html($new_string); } return $new_string; } ############################## my $flickr_person = Flickr::Person->new( { api_key => $flickr_api_key, email => $flickr_email, password => $flickr_password } ); if ($user_name) { $found = $flickr_person->find( { username => $user_name } ); } elsif ($email) { $found = $flickr_person->find( { email => $email } ); $user_name = $flickr_person->username(); $found = $flickr_person->find( { username => $user_name } ); } elsif ($id) { $found = $flickr_person->id( {id => $id} ); $user_name = $flickr_person->username(); $found = $flickr_person->find( { username => $user_name } ); } if ( $found ) { my $page_num = 1; my $more_pages = 1; my $api = $flickr_person->{people_api}->{api}; $photo_directory = $cfg->param('Photos.directory') . "/" . $user_nam +e; $api->{api_secret} = $flickr_secret; my $flickr_photos = Flickr::API::Photos->new( $flickr_api_key, $flickr_email, $flickr_password); unless (-d $photo_directory) { mkdir $photo_directory or die ('Unable to create directory "' . $photo_directory . '"' +); } # for determine whether we might be downloading a duplicate, we need + a hash with # the MD5 sum & filename. We tie both hashes to a file in the fli +ckr user's # directory tie my %MD5_HASH, 'Tie::File::AsHash', $photo_directory . "/.md5s", +split => ':' or die "Problem tying %hash: $!\n"; tie my %FILES_HASH, 'Tie::File::AsHash', $photo_directory . "/.files +_md5s", split => ':' or die "Problem tying %hash: $!\n"; while ($more_pages) { my $response = $api->execute_method('flickr.people.getPublicPhotos +', { api_key => $flickr_api_key, user_id => $flickr_person->id, per_page => 500, page => $page_num } ); my $xpath = new XML::Parser::Lite::Tree::XPath($response->{tree}); my @nodes = $xpath->select_nodes('/photos/photo'); if ($#nodes > 0) { foreach my $node (@nodes) { my $original_photo; my $photo_id = $node->{attributes}->{id}; my $photo_hash = $flickr_photos->getInfo($photo_id); my $photo_title = $photo_hash->{'title'} ? $photo_hash->{'title'} : ""; my $description = $photo_hash->{'description'} ? decode_html( $photo_hash->{'description'} ) : ""; my %photo_sizes = map { $_->{'label'} => $_ } @{ $flickr_photos->getSizes($photo_id)->{sizes} }; if (exists $photo_sizes{'Original'}) { $original_photo = $photo_sizes{'Original'}; } elsif (exists $photo_sizes{'Large'}) { $original_photo = $photo_sizes{'Large'}; } elsif (exists $photo_sizes{'Medium'}) { $original_photo = $photo_sizes{'Medium'}; } elsif (exists $photo_sizes{'Small'}) { $original_photo = $photo_sizes{'Small'}; } else { warn "Unable to find url. Skipping photo."; next; } printf "name: %s id: %s description: %s\n", $photo_title, $photo_hash->{'id'}, $description; my $photo_filename = $photo_directory . '/' . $photo_title; $photo_filename =~ s/\.\w+$//; # Prepopulating the file extension will allow us to eliminate # the vast majority of duplicate images by not downloading # them in the first place. if (exists $photo_hash->{'originalformat'}) { my $extension = $photo_hash->{'originalformat'}; $photo_filename .= "_" . $photo_hash->{'id'} . "." . $extens +ion; } else { # if we don't know at this point what format the image file +is # without downloading the image, we can assume it is a jpg # because the vast majority of the photos are jpg. $photo_filename .= "_" . $photo_hash->{'id'} . ".jpeg"; } if (-f $photo_filename && (stat($photo_filename))[7] > 2048) { printf "We already have photo %s .. Skipping\n", $photo_titl +e; } else { my $FH; my $request = HTTP::Request->new(GET => $original_photo->{'s +ource'} ); my $response = $api->request($request); my $md5_sum = md5_hex($response->content); # since we have downloaded the photo, let's put the proper f +ile # extension on it. if (my $file_ext = extensions( mimetype(new IO::Scalar \($re +sponse->content) ) ) ) { $photo_filename =~ s/\.\w+$//; $photo_filename .= "." . $file_ext; } if (exists $MD5_HASH{$md5_sum}) { printf "We already have photo %s .. Skipping\n", $photo_ti +tle; } else { $MD5_HASH{$md5_sum} = $photo_filename; $FILES_HASH{$photo_filename} = $md5_sum; open($FH, ">", $photo_filename) or warn ("Unable to write to $photo_filename.\n" ); binmode $FH; print $FH $response->content; close $FH; # We're going to use Image::ExifTool instead of the built +in # exif extracted information from Flickr::API::Photos bec +ause # we want to write to the file. my $exifTool = new Image::ExifTool; my $info = $exifTool->ImageInfo($photo_filename); unless ($info->{'DateTimeOriginal'}) { if ($photo_hash->{'dates'}->{'taken'}) { my $taken_date = $photo_hash->{'dates'}->{'taken'}; $taken_date =~ s/\-/\:/g; $exifTool->SetNewValue("DateTimeOriginal", $taken_date +); } } $exifTool->SetNewValue("Comment", $photo_title . ": " . $d +escription . " " . $original_photo->{'source'}); my $result = $exifTool->WriteInfo($photo_filename); } } } $page_num++; } else { $more_pages = undef; } untie %MD5_HASH; untie %FILES_HASH; } }
FlickrDownload.ini
[Flickr] email=jason_froebe@email.org password=**SuperSecretPassword** API_KEY=**YOUR Flickr API KEY** API_SHARED_SECRET=**YOUR SHARED SECRET FROM Flickr** [Photos] # where you want to put the photos directory=/home/jason/flickr

In reply to FlickrDownload.pl by jfroebe

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (5)
As of 2024-04-24 20:10 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found