poniedziałek, 23 września 2013

Pobranie zawartości zbioru/grupy zdjęć z flickr.com

Zbiór to set a grupa to pool. Zbiór zawiera zdjęcia jednego użytkownika a grupa (pool) to zbiór zdjęć różnych użytkowników. To tak tytułem wyjaśnienia.

Flickr API zawiera funkcje flickr.groups.pools.getPhotos oraz flickr.photosets.getPhotos, które zwracają informacje o zdjęciach należących do określonego zbioru (albo grupy). Wynik wygląda jakoś tak:


<photoset id="4" primary="2483" page="1" perpage="500" pages="1" total="2">
<photo id="2484" secret="123456" server="1" title="my photo" isprimary="0" />
<photo id="2483" secret="123456" server="1" title="flickr rocks" isprimary="1" />
</photoset>

Poniższy skrypt wykorzystujący flickr.groups.pools.getPhotos/flickr.photosets.getPhotos ściąga informacje o zdjęciach dodanych do grupy/zbioru. Wynik zapisuje w Perlowej notacji:


@photos=( {'id'=>"2484", 'secret'=>"123456", 'server'=>"1", 'title'=>"my photo", 'isprimary'=>"0"},
{'id' =>"2483", 'secret'=>"123456", 'server'=>"1", 'title'=>"flickr rocks", 'isprimary'=>"1", );

Jest to zatem gotowy do dołączenia do innego skryptu np. za pomocą require kod Perla (lista haszy). Ściągana jest informacja o grupie lub zbiorze określonej/określonym przez podanie stosownego id:


flickr_albums.getPhotos.pl -s set-id
# albo
flickr_albums.getPhotos.pl -p group-id

Uwaga: moduł login2flickr.rc deklaruje m.in stosowną wartość api_key co jest niezbędne do korzystania z API flickra.


#!/usr/bin/perl
#
use Flickr::API;
use Compress::Zlib;
use Getopt::Long;
use XML::DOM;

require 'login2flickr.rc'; # prywatny moduł do

$set_id = $pool_id = $method = $Photos='';

GetOptions( "set=s" => \$set_id, "pool=s" => \$pool_id, ) ;

if ( $set_id ne "" ) {
$root_ele = 'photoset';
$method = 'flickr.photosets.getPhotos';
$ofname = "set-${set_id}.ph";
}
elsif ( $pool_id ne "" ) {
$root_ele='photos';
$method = 'flickr.groups.pools.getPhotos';
$ofname = "pool-${pool_id}.ph";
} else {
die "*** Podaj id zbioru/pula (set-id/pool-id)\n";
}

## ### ### ### ### ###
my $extras = 'date_taken,views,url_o,url_m,geo,tags';

my $api = new Flickr::API({'key' => $api_key, secret => $sharedsecret});
my $parser = XML::DOM::Parser->new();

my $nbrPages = $photoIdx = 0;

do
{
my $params = { per_page => 500, page => $nbrPages+1, extras => $extras };

$params->{group_id} = $pool_id if $pool_id;
$params->{photoset_id} = $set_id if $set_id;

##print STDERR "*** Method/params: $method, $params ***\n";
my $response = $api->execute_method($method, $params );

die "Problem: $response->{error_message}\n" if !$response->{success};

## sprawdz czy _content nie jest gzipniety, jezeli to rozpakuj:
my $content_encoding = $response->{_headers}->{'content-encoding'} ;
my $plain_content ;

if ($content_encoding =~ /gzip/ ) {
$plain_content = Compress::Zlib::memGunzip( $response->{_content});
} else { $plain_content = $response->{_content}; }

my $log = $parser->parse($plain_content);

## Dane są podzielone na strony o maksymalnej wielkości 500 zdjęć:
for $ps ( $log->getElementsByTagName( $root_ele ) ) {
if ($ps->getAttributeNode ("page") ) { $page = $ps->getAttributeNode ("page")->getValue(); }
if ($ps->getAttributeNode ("pages") ) { $pages = $ps->getAttributeNode ("pages")->getValue(); }
}

print "*** Page $page of $pages ***\n";

## dla każdego elementu:
for $p_ ( $log->getElementsByTagName('photo') ) {
$element_content='';

## zapisz wszystkie atrybuty
if ($p_ ->getAttributes() !=null){
$numberAttributes = $p_->getAttributes()->getLength();
}

for ($loopIndex =0; $loopIndex < $numberAttributes; $loopIndex++) {
$attribute = ($p_ -> getAttributes())->item($loopIndex);
$attrname = $attribute->getNodeName();
$attrvalue = $attribute->getNodeValue();
$element_content .= "'$attrname' => '$attrvalue', ";
}

$Photos .= "{ $element_content },\n";
$photoIdx++;
}

++$nbrPages;

} while ($page < $pages );

## ## ###
print STDERR "Writing to $ofname\n";
open (OFILE, ">$ofname");
print OFILE "## Created with $method\n\@photos = (\n $Photos \n);\n1;\n";
close OFILE;

print STDERR "*** $photoIdx photos written to $ofname ***\n";

Skrypt jest do pobrania tutaj.