poniedziałek, 21 lipca 2008

Katalog zdjęć umieszczonych na flickr.com

Od dłuższego już czasu przymierzałem się do zrobienia katalogu moich zdjęć umieszczonych na flickr.com. Ponieważ przed wysłaniem zdjęcia na flickr.com jego opis w postaci tagów i współrzędnych kopiuję do pliku ze zdjęciem (do odpowiednich pól EXIF) więc teoretycznie ów katalog można by zbudować wydłubując teraz to co trzeba z każdego pliku z osobna. Można by ale... Ale nie zawsze opis na flickr.com zgadza się z opisem lokalnym, bo jak coś spapram to już drugi raz nie ładuję tylko poprawiam ręcznie, bo kiedyś skrypt umieszczający zdjęcia działał inaczej, itd... Mówiąc krótko prościej będzie ściągnąć to wszystko z powrotem z flickr.com. Zrobiłem rozpoznanie w google i się okazało, że jest narzędzie pn. Net::Flickr::Backup służące dokładnie do tego co chcę zrobić: ściągnąć każde zdjęcie z konta na flickr.com wraz z opisem, który to opis zostanie zapisany w formacie RDF. Co dalej będzie z tym RDF-em -- zobaczymy jak się ściągnie.

Postępując zgodnie ze wskazówkami ze strony leobard.twoday.net zainstalowałem moduł Net::Flickr::Backup:


perl -MCPAN -e 'install Net::Flickr::Backup'
yum install perl-XML-LibXML perl-XML-LibXML-Common

Polecenie yum instaluje moduł XML::LibXML, niezbędny do działania Net::Flickr::Backup. W przypadku fedory moduł ten znajduje się w pakiecie perl-XML-LibXML. (Uwaga: zgodnie z tym co napisano na ww. stronie dla systemów Debianowych odpowiednikiem perl-XML-LibXML jest pakiet libxml-libxml-perl.) Na wszelki wypadek doinstalowałem też perl-XML-LibXML-Common, być może niepotrzebnie. Teraz przepisałem zawartość pliku backup-flickr.pl ze wspomnianej wyżej strony (a na tej stronie z kolei jest to przepisane z dokumentacji:-):


#!/usr/bin/perl
#
use Net::Flickr::Backup;
use Log::Dispatch::Screen;
use Config::Simple;

my $CFGFILE = "$ENV{HOME}/.flickr/flickr_backuprc";
my $cfg = new Config::Simple(filename=>"$CFGFILE");

my $flickr = Net::Flickr::Backup->new($cfg);
my $feedback = Log::Dispatch::Screen->new('name' => 'info', 'min_level' => 'info');

$flickr->log()->add($feedback);
$flickr->backup();

oraz utworzyłem w katalogu ~/.flickr/ plik konfiguracyjny flickr_backuprc o następującej zawartości:


#
# http://leobard.twoday.net/stories/4122767/
# ###
[flickr]
api_key=AAAAAAAAAAAAAAAAAAAA
api_secret=BBBBBBBBBBBBBBBBBB
auth_token=CCCCCCCCCCCCCC
api_handler=LibXML

[backup]
photos_root=/cmn/archive/Flickr/backup
scrub_backups=1
fetch_original=0
fetch_medium=0
fetch_square=1
force=0

[rdf]
do_dump=1
#rdfdump_root=/home/asc/photos

Uruchomienie perl backup-flickr.pl skończyło się wkrótce błędem dotyczącym kodowania:


Can't escape \x{0119}, try uri_escape_utf8() instead at \
/usr/local/share/perl/5.8.8/Net/Flickr/RDF.pm line 1497

Z opisu wynika, że coś jest nie tak w pliku RDF.pm. Przy bliższej inspekcji okazało się, że nazwy miejscowości, zawierające polskie znaki (np. Rębiechowo) nie mogą być zakodowane poprawnie przez procedurę uri_escape (Nazwy geograficzne są używane do tworzenia URI postaci: http://www.flickr.com/places/Poland/Pomorskie/Rębiechowo.)

Nie do końca jestem pewien czy dobrze robię ale wymieniłem (dwukrotnie) wywołanie procedury uri_escape na:


URI::Escape::uri_escape_utf8

Teraz program działa. Zostawiłem go na noc żeby zrobić kopię ale się okazało, że kopiowanie działa bardzo wolno. Przez noc ściągnęło się niewiele; potem jak wyłączyłem maszynę ponownie, to wprawdzie program nie ściągał danych drugi raz, ale samo sprawdzanie, w którym miejscu skończył zajęło mu okropnie dużo czasu. Ponieważ mam dostęp -- od jakiegoś czasu -- do tajnego serwera w pracy więc postanowiłem zrobić kopię wykorzystując ową maszynę.

Maszyna jest całkowicie out-of-date i dodatkowo zainstalowałem na niej Ubuntu... Zainstalowałem zaś Ubuntu z tej prozaicznej przyczyny, że nie mogłem znaleźć dysków z instalacją Fedory a jakąś instalkę Ubuntu akurat miałem pod ręką. Jak powszechnie wiadomo Ubuntu i Fedora różnią się nieco, w szczególności różnią się program służącym do instalowania i aktualizacji systemu.

Próba zainstalowania Net::Flickr::Backup tak jak w Fedorze, tj. poprzez perl -MCPAN -e '...' skończyła się błędem na etapie instalowania pakietu SOAP-Lite. Rozczarowujące, ale się nie załamałem:-) Zrobiłem upgrade a potem zainstalowałem dla pewności SOAP-Lite aptem (akurat był dostępny):


apt-get upgrade #
aptitude search SOAP-Lite # jaki pakiet zawiera SOAP-Lite ?
apt-get install libsoap-lite-perl # instaluję SOAP-Lite

Teraz polecenie


perl -MCPAN -e 'install Net::Flickr::Backup'

Zostało wykonanie pomyślnie. Poprawiam teraz uri_escape na uri_escape_utf8 w sposób opisany wyżej. Kopiuję do ~/.flickr/ plik flickr_backuprc także opisany wyżej.

Teraz mogę uruchomić:


./backup-flickr.pl > BACKUP_FLICKR.LOG 2>&1 &

Wygląda, że działa. I mogę się wylogować. Zobaczymy za parę dni czym to się wszystko skończy.

Dla przypomnienia, zapis >BACKUP_FLICKR.LOG 2>&1 wysyła strumienie stdout i stderr do pliku BACKUP_FLICKR.LOG.

Dopisane 4 sierpnia 2008: Bardziej fundamentalny problem się pojawił. Mianowicie, identyfikatory zdjęć (photo_id), które m.in. definiują adres URL do strony ze zdjęciem są całkowicie do kitu, np.:


<flickr:photo rdf:about="http://www.flickr.com/photos/20425995@N00/-1617918774">

Trudno nawet powiedzieć do jakiego zdjęcia odnosi się powyższe. Przy bliższym oglądzie stwierdziłem co następuje: photo_id są ok dla zdjęć wysłanych na flickr przed rokiem 2008. Zacząłem podejrzewać że gdzieś się ,,licznik przekręcił'', ale jak to się stało w językach beztypowych takich jak Perl? Ponieważ nie za bardzo mi się chciało dłubać w kodzie Net::Flickr::Backup zgłosiłem błąd korzystając -- zgodnie z tym co jest napisane w dokumentacji pakietu -- z http://rt.cpan.org. Do samego zgłoszenia błędu wystarczy napisać list na adres bug-Net-Flickr-Backup@rt.cpan.org (do komentowania trzeba się zarejestrować). Mój raport jest tutaj.

Wygląda, że nikt tego Net::Flickr::Backup nie używa, bo przez 12 dni pies z kulawą nogą się nie odezwał. Ponieważ sprawa nie dawała mi spokoju zacząłem dziś drążyć temat. W szczególności przyjrzałem się jak działa procedura backup zdefiniowana w Net/Flickr/Backup.pm. Podejrzenie padło na wiersz:


$self->log()->info(sprintf("process image %d (%s)",
$id, &_clean($node->getAttribute("title"))));

A konkretnie specyfikację %d funkcji sprintf. Hmm..., jaka jest maksymalna/minimalna wartość dla liczby całkowitej w Perlu? Doczytałem, że jest to system-dependent i można ją ustalić wykonując poniższy skrypt (znalezione na stronie www.issociate.de):


perl -le 'use POSIX; print for SHRT_MAX, INT_MAX, LONG_MAX, FLT_MAX, DBL_MAX;'

U mnie INT_MAX wynosi 2147483647 (tyle samo wynosi LONG_MAX btw) a przykładowo id tego zdjęcia to 2727375455. Ewidentnie 2727375455 jest większe od 2147483647, więc Net::Flickr::Backup nie może działać prawidłowo. Pozostało teraz ustalić jak jest definiowane photo_id w dokumentacji API flickr.com. Jakoś trudno znaleźć, ale jest po dłuższym szukaniu udało się ustalić co następuje: (por. tutaj): The Flickr API exposes identifiers for users, photos, photosets and other uniquely identifiable objects. These IDs should always be treated as opaque strings, rather than integers of any specific type. The format of the IDs can change over time, so relying on the current format may cause you problems in the future. .

Wymieniłem %d na %sNet/Flickr/Backup.pm oraz Net/Flickr/RDF.pm, wszędzie tam gdzie jest drukowane photo_id. Mam nadzieję, że nie pominąłem niczego i teraz da się zrobić poprawnie backup flikra.

Brak komentarzy:

Prześlij komentarz