#!/usr/bin/perl use Flickr::API; package Flickr; our $flickr; our $dbfile = 'flickr_data.txt'; # These need to be replaced by suitable values. You can use the # 'get_auth_url', 'get_frob' and 'get_token' subs below for this, although # I honestly can't remember how they work at this point. Consider this a # rite-of-passage. our $key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'; our $secret = 'xxxxxxxxxxxxxxxx'; our $token = 'xxxxxx-xxxxxxxxxxxxxxxx'; our $user_id = 'xxxxxxxxxx@N00'; # Create a new API object. our $api = new Flickr::API({'key' => $key, 'secret' => $secret}); sub loaddb # Loads the Flickr cache, as saved by savedb(); { require $dbfile; } sub savedb # Saves the Flickr cache, as created by createdb(); { open OUT, "> $dbfile" or die "Argh: $!"; { use Data::Dumper; local $Data::Dumper::Terse = 1; local $Data::Dumper::Purity = 1; local $Data::Dumper::Indent = 0; print OUT 'our $flickr = '; print OUT Dumper($flickr); print OUT ";1;"; } close OUT; } sub createdb # Queries Flickr for all photos, photosets and metadata for your # collection. { # First, get photos not in any set. my $response; $response = $api->execute_method('flickr.photos.getNotInSet', {'auth_token'=>$token}); # For each photo... (kinda) foreach $child (@{$response->{tree}{children}[1]{children}}) { # Skip whitespace garbage. next if($$child{name} ne 'photo'); my $title = $$child{attributes}{title}; my $id = $$child{attributes}{id}; printf "\t%i\t%s\n", $id, $title; # Get metadata for photo my $response2 = $api->execute_method('flickr.photos.getInfo', {'photo_id'=>$id, 'auth_token'=>$token}); my $response3 = $api->execute_method('flickr.photos.getExif', {'photo_id'=>$id, 'auth_token'=>$token}); # Index the photo $$flickr{photos}{$id} = { id=>$id, title=>$title, info=>$$response2{tree}{children}[1], exif=>$$response3{tree}{children}[1] }; } # Now, get the list of all photosets. $response = $api->execute_method('flickr.photosets.getList', {'auth_token'=>$token}); # For each photoset... (kinda) foreach $child (@{$response->{tree}{children}[1]{children}}) { # Skip whitespace garbage. next if($$child{name} ne 'photoset'); # Get the photoset title and ID chomp (my $pstitle = $$child{children}[1]{children}[0]{content}); my $psid = $$child{attributes}{id}; # Index the photoset $$flickr{photosets}{$psid} = {title=>$pstitle}; # Get all photos in the photoset $response = $api->execute_method('flickr.photosets.getPhotos', {'photoset_id'=>$psid, 'auth_token'=>$token}); printf "%s\n", $pstitle; # For each photo... foreach $child (@{$response->{tree}{children}[1]{children}}) { # Skip whitespace garbage. next if($$child{name} ne 'photo'); # Get photo title and ID my $title = $$child{attributes}{title}; my $id = $$child{attributes}{id}; # Get metadata for photo my $response2 = $api->execute_method('flickr.photos.getInfo', {'photo_id'=>$id, 'auth_token'=>$token}); my $response3 = $api->execute_method('flickr.photos.getExif', {'photo_id'=>$id, 'auth_token'=>$token}); # Add to the index for the photoset push @{$$flickr{photosets}{$psid}{children}}, $id; # Index the photo $$flickr{photos}{$id} = { id=>$id, title=>$title, info=>$$response2{tree}{children}[1], exif=>$$response3{tree}{children}[1] }; printf "\t%i\t%s\n", $id, $title; } } # Save the database savedb(); } sub child($$) # Retrieve the named child from the parse tree { my ($tree, $name) = @_; foreach my $child (@{$tree->{children}}) { return $child if($name eq $$child{name}); } } sub index_by_taken() # Creates an index of the photos by date taken { foreach my $pid (keys %{$$flickr{photos}}) { my $dates = child($$flickr{photos}{$pid}{info}, 'dates'); my $taken = $$dates{'attributes'}{'taken'}; push @{$$flickr{bytaken}{$taken}}, $pid; } } # Flickr API auth gubbins. I wrote this ages ago, and I can't remember # how to work it. sub get_auth_url { my $frob = shift; return $api->request_auth_url('write', $frob); } sub get_frob { $resp = $api->execute_method('flickr.auth.getFrob'); die "Can't get frob" unless ($resp->{tree}{children}[1]{name} eq 'frob'); return $resp->{tree}{children}[1]{children}[0]{content}; } sub get_token { my $frob = shift; my $resp = $api->execute_method('flickr.auth.getToken', {frob=>$frob}); print Dumper $resp; die "Can't get token" unless defined $resp and $resp->{success}; return $resp->{tree}{children}[1]{children}[1]{children}[0]{content}; } 1;