Wycieczka do Swornychgaci spowodowała m.in. konieczność dopasowania moich starych skryptów Perla służących do obsługi Flickra.
Flickr zmienił bowiem niedawno API przechodząc na SSL. Zapewne nowa wersja modułu Flickr-API tą zmianę uwzględnia, ale można też rozwiązać sprawę dodając stosowny parametr do starych skryptów. Konkretnie poniższy wiersz:
my $api = new Flickr::API({'key' => $api_key, 'secret' => $shared_secret, });
należy uzupełnić o parametr rest_uri
, tj:
my $api = new Flickr::API({'key' => $api_key, 'secret' => $shared_secret, 'rest_uri' => 'https://api.flickr.com/services/rest/' });
Podobnie niewielkich modyfikacji wymaga skrypt służący do wysyłania zdjęć (moduł Flickr-Upload):
my $ua = Flickr::Upload->new( {'key' => $api_key, 'secret' => $shared_secret, 'uri' => 'https://up.flickr.com/services/upload/' } );
W tzw. międzyczasie zmieniła się też nieco metoda flickr.photos.geo.setLocation
:
#if ( $response->{success} ) { ## przestało działać unless ( $response->{error_code} > 0 ) {
W dokumentacji jest napisane:
This method has no specific response -- It returns an empty success
response if it completes without error.. No to faktycznie jak jest empty
to if (EMPTY) {
zwraca fałsz i warunek jest źle interpertowany.
Poza tą jedną poprawką wszystko inne działa.
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.
Darmowe konto na flickr.com może zostać skasowane jeżeli nie jest używane przez kolejne 90 dni. If your free account is inactive for 90 consecutive days, it may be deleted.
Od ręki nie działa. Próbowałem rozwiązać problem instalując następujące pakiety:
yum install gphoto2 gvfs-gphoto2 gtkam digikam gthumb geeqie
Geeqie
to zamiennik gqview
,
które używałem do tej pory.
DigiKam
nie działa (gryzie się z XFce
).
Wydaje mi się, że większość tego
co zainstalowałem
nie jest potrzebna -- istotne jest geeqie
,
dzięki któremu mogę wygodnie
zaimportować zdjęcia
z aparatu na komputer (lądują w katalogu ~/Pictures
).
Prawie działa. Problem stanowią słowa kluczowe zawierające
polskie znaczki. Trzeba nieco zmodyfikować skrypty generujące
bazę słów kluczowych tj. flickr_getalltags
, i inne.
Cała procedura odświeżania tagów i innych metadanych jest
uruchamiana skryptem flickr_update_kb
, który
w uproszczeniu wygląda następująco:
#!/bin/bash # Get list of public photos with 'flickr.people.getPublicPhotos flickr_getphotolist.pl -u hr.icio # Refreshing information on tags/sets/geolocs" # Get information on sets defined by the user: flickr_getsets && \ # Get tags from flickr for current user flickr_getalltags && \ # Get information on groups to which one can add photos flickr_getgroups && \ ## For flickr_xml2el we need _special treatment_ otherwise UTF is spoiled PERL_UNICODE=S flickr_xml2el > ~/.flickr/hr.icio.el cd ~/.knows && make 2flicker && \ cd ~/.flickr && make check
Z nieustalonych powodów cześć komunikatu zwracana przez flickra
jest teraz kompresowana (a nie była -- nowsza wersja pakietu Perla?).
Z tego też powodu konstrukcja (ze
skryptu flickr_getalltags.pl
-- w innych skryptach
podobnie):
my $xm = $xmlp->XMLin($response->{_content}, forcearray=>[raw]);
została zamieniona na:
## zmienione 15.08.2011 (gzip as content-encoding) ## ustalenie w jakim `content_encoding' jest _content my $content_encoding = $response->{_headers}->{'content-encoding'} ; my $plain_content; if ($content_encoding =~ /gzip/ ) {## jeżeli gzip to odpakować: $plain_content = Compress::Zlib::memGunzip( $response->{_content}); } else { $plain_content = $response->{_content}; }
Powyższe załatwia problem z (nie) działaniem skryptów
flickr_getphotolist.pl
,
flickr_getsets
,
flickr_getalltags
,
flickr_getgroups
.
Konwersja plików XML do formatu Emacsa
za pomocą skryptu flickr_xml2el
daje w rezultacie las
komunikatów Wide character in print at... a plik wynikowy jest
błędnie kodowany. Problem ciągle wraca a ja ciągle nie wiem czemu.
Zaślepkowo pomogło
dodanie PERL_UNICODE=S
(zaklęcie to należy wstawić
w odpowiednie miejsce
także do pliku Make
w katalogu ~/.knows
).
Po tych wszystkich ww. zabiegach (które zajęły mi pół dnia) jestem w stanie odświeżyć bazę metadanych z mojego konta na flickr.com. Sukces:-)
Nie mogę się zalogować w programie picasa (wersja dla linuksa, 3.0 beta). Wpisując Picasa Linux signup problem do Google znalazłem podpowiedź:
cp /usr/lib/wine/wininet.dll.so /opt/google/picasa/3.0/wine/lib/wine/
U mnie przynajmniej powyższe działa.
Się przy okazji okazało, że zdjęcia zawierające współrzędne geograficzne przesłane via formularz nie są traktowane jako geotagowane . Picasaweb rozpoznaje zdjęcia jako geotagowane jeżeli są ładowane programem picasa. Na flickr.com jest pod tym względem prościej, bo współrzędne geograficzne są pobierane ze zdjęcia po stronie serwera--wystarczy przesłać plik i nie jest istotne w jaki sposób...
Flickr2Map to usługa, dzięki której użytkownicy flickr.com mogą wyświetlić geotagowane zdjęcia m.in. na google maps. Przykład:
http://www.robogeo.com/Flickr2Map?referer=http://www.flickr.com/photos/tprzechlewski/3087054865/&type=map&view=satellite
Żeby za dużo nie musieć wpisywać, zrobiłem skrót do usługi.
Moje najbardziej oblegane zdjęcie na flickr.com. niedługo będzie miało jubileusz 2000 oglądnięć (przeciętna dla całego mojego zbioru to ok. 10 odsłon). Ponad 50 użytkowników zaznaczyło je jako ulubione. Tylko hmm... upodobania tych użytkowników takie trochę...
Wyświetlanie zdjęć zrobionych w pobliżu innego zdjęcia na flickr.com jest łatwe, ale ta funkcja jakoś mi umknęła do tej pory a jest przydatna. Na przykład żeby się nie `zapętlić' i robić zdjęcie tego co już było sfotografowane. Otóż przykładowo:
http://www.flickr.com/photos/tprzechlewski/3087051333/
Pokazuje stronę ze zdjęciem. Natomiast
http://www.flickr.com/photos/tprzechlewski/3087051333/nearby
Ze zdjęciami zrobionymi obok tego zdjęcia. Oczywiście zdjęcie musi być geotagowane żeby powyższe zadziałało.
Od pewnego czasu pobieram dane z flickr.com dotyczące
najbardziej interesujących zdjęć [sposób w jaki flickr.com tworzy
listę `najbardziej interesujących'
zdjęć nie jest znany]. Konkretnie wykonuję
flickr.interestingness.getList
pobierając 500 zdjęć
dla każdego kolejnego dnia.
Dla takiego zbioru policzyłem: -- średnią liczbę tagów, tagów maszynowych (tj. takich, które zawierają dwukropek, np.: geo:lat=54.00) i tagów wielowyrazowych; -- średnią liczbę zbiorów i średnią liczbę puli, do których należy zdjęcie. Wreszcie -- odsetek zdjęć geokodowanych. Wszystkie ww. statystyki w rozbiciu na kolejne miesiące...
Teza była taka, że z czasem średnie/udziały będą miały większe wartości bo użytkownicy coraz chętniej będą swoje zdjęcia oznakowywać, doceniając płynące stąd korzyści. Rosnąca liczba tagów maszynowych i/lub wielowyrazowych oraz rosnący odsetek zdjęć geokodowanych w pewnym stopniu świadczyłaby o rosnącej semantycznej precyzji metadanych na flickr.com. Dane przedstawione poniżej nie potwierdzają tego założenia:
Statystyki flickra. Od : 2006-11-28 do 2008-08-28 ----------------------------------------------------- Mc/Yr : Loc MTag Poo RTag Set Tag --> 200611: 13.9 0.067 8.810 1.704 1.543 8.975 --> 200612: 13.3 0.064 8.690 1.740 1.501 8.942 --> 200701: 14.0 0.066 8.607 1.603 1.596 9.281 --> 200702: 13.8 0.063 8.862 1.413 1.654 9.675 --> 200703: 13.4 0.063 9.159 1.398 1.679 9.936 --> 200704: 13.6 0.056 9.556 1.434 1.703 10.302 --> 200705: 14.4 0.056 10.229 1.432 1.700 10.568 --> 200706: 13.2 0.057 9.968 1.386 1.688 10.217 --> 200707: 12.8 0.048 8.136 1.401 1.613 9.547 --> 200708: 14.0 0.059 7.770 1.585 1.773 10.249 --> 200709: 13.5 0.053 7.321 1.638 1.767 10.174 --> 200710: 13.6 0.057 6.939 1.610 1.743 9.722 --> 200711: 12.9 0.055 6.698 1.532 1.714 9.392 --> 200712: 12.4 0.048 6.698 1.606 1.749 9.644 --> 200801: 12.1 0.052 6.818 1.599 1.685 9.456 --> 200802: 11.2 0.049 6.962 1.603 1.664 9.401 --> 200803: 10.4 0.049 6.786 1.637 1.675 9.457 --> 200804: 10.3 0.049 6.475 1.623 1.672 9.315 --> 200805: 10.6 0.053 6.505 1.661 1.690 9.205 --> 200806: 10.0 0.047 6.369 1.693 1.650 9.023 --> 200807: 10.0 0.038 6.534 1.664 1.658 9.101 --> 200808: 11.1 0.048 6.181 1.726 1.715 9.471 -----------------------------------------------------
Gdzie: Loc -- odsetek zdjęć geokodowanych; MTag -- średnia liczba tagów maszynowych; Poo -- średnia liczba puli; RTag -- średnia liczba tagów wielowyrazowych ; Set -- średnia liczba zbiorów ; Tag -- średnia liczba tagów.
Jak widać w zasadzie wartości są stałe. Można nawet zauważyć, że odsetek zdjęć geokodowanych uległ niewielkiemu obniżeniu (z 13--14, do 10--11%). Także spadła nieznacznie przeciętna liczba puli, do których wysłano zdjęcie... Liczba tagów maszynowych jest śladowa. Hmmm...
Dopisane 16 września 2008:
Policzę jeszcze ww. statystyki dla danych bardziej losowych. Ściągnę
mianowicie opisy zdjęć za pomocą flickr.photos.getRecent
:
do { $pageno++; ## następna strona my $resp = get ( "http://www.flickr.com/services/rest/?" . "method=$method&api_key=$api_key&per_page=$max_per_page&" . "page=$pageno&extras=geo,views,tags,machine_tags,license" ); ## sprawdź czy jest OK: eval { $photos = $parser->parse_string($resp) } ; unless ($@) {## pomiń stronę z błędami ## ... obrób dokument XML zawarty w $resp ## } } while ( ($current_page < $total_pages) && ($pageno < $max_pages) );
Konstrukcja eval{ ... }
służy do tego żeby skrypt się nie wywalał
po fatal error tylko wykonywał następną iterację. A potrafi się
wywalić na parsowaniu XML bo rzadko-bo-rzadko ale czasami
coś jest nie tak z kodowaniem (UTF).
Skrypt, którego fragment jest wyżej będzie uruchamiany losowo plus/minus co 15 minut:
#!/usr/bin/perl ## Do forever with 15 min random delay or ca 4 x hour (\approx 100 per 24 hrs) while (1) { my $runTask = `perl flickr_photo_recent.pl`; sleep (int(rand(600 )) + 600); }
Plan jest taki żeby ściągać dane przez 10 dni. Zakładając 100 tys zdjeć na dzień da to próbę wielkości 1 mln zdjęć.
Dopisane 26 września 2008:
Niebuforowany zapis do STDOUT oraz do pliku. Sprawa ciut niejasna:
w Internecie większość tekstów wskazuje, że problem załatwia
nadanie zmiennej $|
wartości
niezerowej. Mi to jednak nie działa...
W końcu znalazłem
działającą odpowiedź:
#!/usr/bin/perl use FileHandle; # to make STDOUT flush immediately, simply set the variable $| $| = 1; # to prevent buffering when writing to files, set autoflush on # the file handle open (OUT, ">>test.out") || die "could not create test.out - $!"; OUT->autoflush(1); print OUT "writing to file\n"; close(OUT); exit(0);
Dopisane 2 października 2008: Pierwsze wyniki dla danych z 18.09--30.09 (łącznie 364,127 zdjęć): 1) odsetek zdjęć zawierających co najmniej jeden tag: 40,77%; 2) odsetek zdjęć geotagowanych: 4,06%; 3) odsetek zdjęć tagowanych i umieszczonych w co najmniej jednym pulu: 10,17%; 4) odsetek zdjęć geotagowanych, tagowanych i umieszczonych w co najmniej jednym pulu: 1,15%. Przeciętnie zdjęcie było oznaczone 2,5 tagami. Jak widać najbardziej interesujących zdjęcia są ca 3 razy częściej geotagowane i mają 3--4 razy tyle tagów... Zrozumiałe bo znaczna część zdjęć jest wrzucana ,,jak leci'' bez oznaczenia ich czymkolwiek. Z reguły też zdjęcia takie są mało interesujące dla szerszej publiczności...
Dopisane 4 października 2008:
Dziś wylosowałem 2,5% z 233520 użytkowników flickr, których zdjęcia pobrałem w ostatnich dniach.
Te 2,5% to było dokładnie 5838.
Ściągnąłem za pomocą flickr.people.getInfo
informacje dotyczące liczby zdjęć
i daty zawartej w elemencie firstdate
. (The firstdate element contains the unix timestamp
of the first photo uploaded by the user.). Myślałem, że to data pierwszego uploadu,
ale tak nie jest. Wygląda to raczej na (opis jest raczej lakoniczny) na datę wykonania pierwszego zdjęcia
zamieszczonego na flickr.com. Data ta jest zapewne odczytana z odpowiedniego pola Exif, a co za tym idzie
może jej nie być, albo może być lipna... Anyway wyniki są następujące:
Wyszczególnienie N mediana średnia dominan od.st. max min Ws Ws' L.zdjęć 5837 191.00 846.11 200.00 3121.26 171182 0 0.21 (0.63) L. dni 5837 307.00 435.80 18.00 546.00 14157 2 0.77 (0.71)
L. dni, to liczba dni od firstdate (coś w rodzaju stażu). Próba się zmniejszyła
do 5837, bo z jednym użytkownikiem był problem...
Ws to współczynnik skośności Pearsona (x-D)/sd (a w nawiasie podobny współczynnik skośności (Ws')
liczony na podstawie Mediany, jako 3(x-Me)/sd.)
Rozkłady są zatem prawostronnie asymetryczne. A ten gość co ma 170tys zdjęć
jest tutaj:-).
Interpretacja: 50% użytkowników, którzy publikują swoje zdjęcia ma ich mniej niż 191...
BTW element count
zawiera liczbę wszystkich zdjęć umieszczonych
na flickr.com, nie tylko zdjęć o statusie public. Nie jest to napisane w dokumentacji
ale zweryfikowałem empirycznie...
W książce Flickr Hacks Paula Bauscha i Jima Bumgardnera
do manipulowania danymi w formacie XML
przesyłanymi z flickr.com
używa się XML::Simple
. Jakoś XML::Simple
nie wydaje mi się specjalnie
simple w tym wypadku. Zdecydowanie wolę XML::LibXML
,
który pozwala przede wszystkim na dotarcie do poszczególnych fragmentów dokumentów XML
w prosty sposób bez używania karkołomnych referencji.
Przykładowo poniższy skrypt (fragment) wykonuje zapytanie flickr.photos.search
[najistotniejszą częścią skryptu -- zaznaczoną odmiennym kolorem tła --
jest pętla do { ... }
]:
use XML::LibXML;
use LWP::Simple;
use Getopt::Long;
require 'login2flickr.rc';
our $api_key;
our $my_flickr_id;
my $tags_txt;
my $show_help;
my ($user_id, $all_users, $report_views);
my @Photos;
GetOptions( "all" => \$all_users,
"user=s" => \$user_id, "views" => \$report_views,
"tags=s" => \$tags_txt);
unless ( $user_id ) { $user_id = $my_flickr_id; }
if ( $all_users ) { $user_id = ''; } ## search all photos
my $parser = XML::LibXML->new;
my $pageno;
my $method = 'flickr.photos.search';
my $max_per_page = 500;
my ($total_pages, $current_page);
my $search_query = "&extras=geo,views"; # http://www.flickr.com/services/api/flickr.photos.search.html
if ( $user_id ) { $search_query .= "&user_id=$user_id"; }
if ( $tags_txt ) { $search_query .= "&tags=$tags_txt" }
do {
$pageno++;
my $resp = get ( "http://www.flickr.com/services/rest/?" .
"method=$method&api_key=$api_key&per_page=$max_per_page&page=$pageno" .
$search_query );
## sprawdź czy jest OK:
my $photos = $parser->parse_string($resp);
unless ( $photos->getElementsByTagName('rsp' )->[0]->getAttribute( 'stat' ) eq 'ok') {
die "Problems with retriving photo list!\n" }
push @Photos, $photos->getElementsByTagName('photo' );
$total_pages = $photos->getElementsByTagName('photos' )->[0]->getAttribute('pages' );
$current_page = $photos->getElementsByTagName('photos' )->[0]->getAttribute('page' );
# Dla dużych zbiorów zdjęć może długo trwać, więc wypisz że coś robisz:
printf STDERR " *** Page %d of %d retreived...\n", $current_page, $total_pages;
} while ( $current_page lt; $total_pages );
## Lista @Photos zawiera wszystkie zdjęcia...
## ... dalsza część skryptu ...
Pętla jest niezbędna ponieważ flickr API
organicza wielkość zwracanego dokumentu do maksymalnie 500 zdjęć.
Jeżeli zdjęć jest więcej, to zapytanie należy zadać wielokrotnie, zmieniając wartość parametru
page
. Przy czym liczbę wszystkich stron określa wartość atrybutu pages
.
Po ściągnięciu dokumentu skrypt sprawdza czy wszystko jest OK. Jeżeli tak, to za pomocą
getElementsByTagName
pobiera wszystkie elementy photo
i dodaje
je do listy @Photos
. Teraz pobierane są wartości atrybutów pages
/page
w celu ustalenia czy wszystko już ściągnięto. Jeżeli pages
< page
to pętla działa dalej...
Zwracam uwagę, że od jakiegoś czasu zapytanie może zawierać parametr extras
, dzięki
któremu zwracany dokument XML zawiera dodatkowe informacje, takie jak: tagi, współrzędne geograficzne,
liczbę odsłon, itd...
Jest to opisane w API na flickr.com a także
tutaj.
W wyżej przedstawionym skrypcie deklaracja:
my $search_query = "&extras=geo,views";
Oznacza, że do standardowych opisów zdjęć będą dodane także współrzędne geograficzne (oczywiście
tylko wtedy gdy zdjęcia będą nimi oznaczone) oraz liczba odsłon. BTW dodanie extras=views
powoduje, że kiedyś niemożliwy do wykonania poprzez API problem ustalenia ile razy zdjęcie było
oglądane teraz jest jak najbardziej wykonalny. Zatem skrypty -- opisane
w Nowa usługa na flickr.com
oraz Czy flickr umie liczyć -- lepsze rozwiązanie
-- są już niepotrzebne.
Kompletny skrypt pobierający zdjęcia z flickr.com i wypisujący plik GPX dla tych, które zawierają współrzędne geograficzne jest tutaj. Ale uwaga: próba wykonania zestawienia wszystkich wież ciśnień z flickr.com:
flickr_photo_gsearch.pl -a -t 'wieżaciśnień,wasserturm,watertower' > wasserturme-alles.xml
Skończyła się pobraniem ponad 23 tysięcy zdjęć (z tego około 6 tys. było geokodowane). Plik GPX pn. wasserturme-alles.xml miał 1,8 Mb i za nic nie szło tego wyświetlić w przeglądarce. Za duże... Mniejsze pliki są ok: kaplice [mapa ] albo moje wieże ciśnień [mapa ].
Pakiet Net::Flickr::Backup, o którym pisałem niedawno nie działa prawidłowo. Dziś ustaliłem co jest nie tak i szczegółowo opisałem w tamtym wpisie.
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 %s
w Net/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.
Obrazek, bo to nie jest zdjęcie, tylko zrzut ekranu. Dziś liczba odsłon doszła do 1000. Wielki sukces:-) Nie znam przyczyn tego fenomenu, ale zrzuty z ekranu wydają się cieszyć dużo wielką popularnością niż zdjęcia. Panie z reklam bielizny nie mają najmniejszych szans nawiązać z Emacsem -- najpopularniejsza była oglądana zaledwie 135 razy. A zdjęcie oznaczone prowokacyjnie jako big cock to już się zupełną klapą okazało (5 razy oglądane).
Podobno MS chce kupić za 44 Mld USD (z ogonkiem) Yahoo. Nie będę
się mądrzył czy to dobrze czy źle ale tak dla ilustracji czego boi się Balmer,
poniżej tabelka rocznych zysków
netto zainteresowanych firm (wiersz oznaczony jako %
oznacza dynamikę zysku rok/rok_poprzedni * 100 - 100;
ostatni wiersz to udział zysku Google w zysku MSFT, w %).
Symbol 2007 2006 2005 2004 2003 2002 -------------------------------------------------------------------- MSFT 14,065.00 12,599.00 12,254.00 8,168.00 7,531.00 5,355.00 % 11.63 2.80 50.02 8.46 40.63 -- YHOO 660.00 751.39 1,896.23 839.55 237.88 42.81 % -12.3 -61.00 125.83 252.93 455.66 -- GOOG --+ 3,077.44 1,465.40 399.12 105.65 99.66 % --+ 101.00 267.15 277.77 6.01 -- GOOG/MSFT -- 24.42 11.96 4.88 1.40 1.86 -------------------------------------------------------------------- + Brak danych za rok 2007.
Jak widać zyski Google mają dramatyczną z punktu widzenia firmy Microsoft, w tym, a zwłaszcza jej akcjonariuszy, dynamikę. Jak tak dalej by poszło, Balmer jest już dead and buried ze swoim szmelcem aka pomnikiem dla ludzkości od Bila G. Z drugiej strony Yahoo też tak miało w latach 2005--2003 ale od dwóch lat jest kiepsko. Na zdrowy chłopski nie da się w nieskończoność robić super biznesu sprzedając Windows+Office. Ale czy da się długo robić super biznes sprzedając reklamy? Też nie wiadomo. MS w Internecie nic nie znaczy, więc kupno Yahoo niby nie jest złym pomysłem, ale... Ale Yahoo za wyjątkiem flickr.com z niczym (w przeciwieństwie do Google) mi się nie kojarzy... Jednym słowem zobaczymy...
Ważniejszy w całej tej sprawie jest ewentualny zakup przez Microsoft firmy od lat związanej/sponsorującej wiele projektów OS, por. what-happens-if-microsoft-buys-yahoo albo Yahoo! buy would give Microsoft ownership of open source e-mail, projects, code. Ugh.
Zapisać się łatwo. Wypisać trudniej. Należy wybrać stronę your Groups, następnie wybrać grupę. Po prawej stronie wyszukać link Quit nazwa-grupy. Po kliknięciu znajdziemy się na stronie, na której będzie się można wypisać.
Niedawno (13 grudnia 2007) Flickr uruchomił nowy serwis pn. stats! Użytkownicy serwisu z wykupioną usługą pro (ca 25 USD, czyli niedużo -- jak to się czasy zmieniły BTW) mają dostęp do różnych statystyk dotyczących swoich zdjęć. Informacje o usłudze zobaczyłem dzisiaj. Żeby z niej skorzystać trzeba się zasubskrybować -- czytaj nacisnąć duży guzik ze stosownym napisem. Wówczas ukazuje się napis, że OK, ale statystyki będą jutro. Grozę potęguje animacja gościa z pneumatycznym młotem. Widocznie jestem jednym z pierwszych bo były od razu -- wystarczyło odświeżyć stronę.
A więc pro-user dostaje takie informacje jak: liczba odsłon dla każdego zdjęcia oraz statystyki adresów referer w podziale na ,,wczoraj'' oraz ,,ogółem''. Ponadto wykres liniowy liczby odsłon zawierający dzienne dane z ostatniego miesiąca oraz zestawienie tabelaryczne zawierające podsumowania liczby odsłon (wczoraj, ostatni tydzień, ostatni miesiąc oraz ogółem) dla stron głównych (photostream), zbiorów (sets), kolekcji (collections) i stron pojedynczych zdjęć.
Statystki ,,oglądnięć'' dostępne ze strony
http://www.flickr.com/photos/tprzechlewski/stats/allphotos/
(Nie ma co klikać, więc i linka nie ma -- strona dostępna po
zalogowaniu:-) są kompletne, tj. dla każdego zdjęcia dostępna jest
liczba odsłon (z wczoraj, z ostatniego tygodnia oraz ogółem).
W pierwszej chwili pomyślałem, że nowa usługa renders obsolete
jak mawiają Anglicy moje
skrypty,
które z takim zapałem ostatnio udoskonalałem.
Ale niekoniecznie! Dane
ze strony stats! primo nie są trwałe (niektóre tak -- ale nie wszystkie,
np. dzienne statystyki oglądalności dostępne są tylko dla ,,wczoraj''),
secundo żeby były trwałe trzeba je ściągać na swój komputer
na przykład codziennie. No i tu się przyda programik
flickr_store_views.pl
,
który potrafi się zalogować na flickr.com, pobrać
stronę i zapisać co trzeba na dysk.
Zamiast ściągać 170 stron i z nich
wyciągać potrzebne informacje wystarczy teraz ściągnąć kilka stron
spod adresu tprzechlewski/stats/allphotos/yesterday/pageliczba
robiąc to metodycznie, czyli codziennie.
Jeszcze link z forum z informacjami nt. omawianej wyżej usługi. Your stats will eventually be a rolling 28 day window, czyli dostępne będą tylko dane z ostatniego miesiąca. Zwracam też uwagę na komentarz dot. tłumaczenia słowa interestingness na język hiszpański jako interesidad. Że niby takie słowo nie istnieje. Faktycznie nie ma w słowniku a google znajduje raptem 4 strony z interesidad (w tym powyższa). Ale jak przetłumaczyć interestingness (za WordNet: the power of attracting or holding one's interest), np. na j. polski? Moc przyciągania?
Dopisane 13 maja 2008:
Skrypt
flick-store-views.pl
przestał działać. Coś zostało zmienione w procedurze logowania.
Nie chce mi się tego poprawiać...
Znacząco poprawiłem swój tryb do dodawania zdjęć na flikr.com. Teraz wszystko się dzieje
wewnątrz Emacsa łącznie z uruchomieniem wysyłania plików na serwer. W starej wersji
pliki konfiguracyjne czytał Emacsowy moduł xml.el
co było może
i eleganckie ale odbywało się przeraźliwie wolno. W nowej wersji plik konfiguracyjny
jest plikiem lispowym wygenerowanym skryptem Perla z plików XML.
Jak to działa opisałem
na oddzielnej stronie.
Jedna sprawa jest tajemnicza:
#!/usr/bin/perl -w require 'login2flickr.rc'; require 'flickr_utils.rc'; my @tmpx = get_sets_ids(); my @tmpy = get_pools_ids();
W plikach login2flickr.rc
oraz flickr_utils.rc
są zdefiniowane
procedury, który czytają plik z dysku i zwracają zmienne. W szczególności
flickr_utils.rc
zawiera dwie prawie identyczne
procedury (get_sets_ids
oraz get_pools_ids
), czytające
różne pliki konfiguracyjne. Kurcze... na jednym komputerze perl zwraca błąd:
Undefined subroutine &main::get_pools_ids called at... a na drugim działa.
Ten sam perl, ta sama wersja FC5, jedna procedura z pliku dołączanego
poleceniem require
jest zdefiniowana druga nie...
Wystarczy zmienić kolejność poleceń require
żeby powyższe działało w obu systemach. Nic mi do głowy nie przychodzi...
Wymyśliłem lepsze rozwiązanie problemu
opisanego tutaj.
Ściągane strony są obrabiane ,,w locie'' a w pliku na dysku są zapisywane
tylko informacje o liczbie odsłon.
Mówiąc konkretniej korzystam z metod
store
/retrive
modułu Storable
,
zapisując/czytając hasz
postaci $PhotoLog{data}{photoid}= views
.
Generowaniem podsumowań zajmuje się inny skrypt, który wypisuje wyniki w postaci
dobrze sformatowanego fragmentu dokumentu HTML (,,opakowanego''
wewnątrz elementu <div>
).
Ten fragment następnie można wstawić w odpowiednie miejsce strony HTML.
Wreszcie ostatni skrypt tworzy wykres
liniowy (przy wykorzystaniu modułu GD::Graph
) liczby odsłon
oraz liczby odsłoniętych zdjęć. Trzy skrypty można połączyć w całość:
#!/bin/bash perl flick-store-views.pl if [ "$?" -ne "0" ] ; then echo "** Problems ..." ; exit 1 ; fi perl flick-report-views.pl -lang=pl -max=25 > 00-pl.phtml && \ perl flick-graph-views.pl if [ "$?" -ne "0" ] ; then echo "** Problems ..." ; exit 1 ; fi echo "OK"
Jakoś tak... Przykład wykorzystania
jest na tych stronach [1]
[2]
[3].
Skrypty można pobrać
stąd
(flick-store-views.pl,
flick-report-views.pl oraz
flick-graph-views.pl.)
Powyższe można nawet wsadzić do crona.
Skrypty wykorzystują m.in. moduły GD::Graph::lines
oraz
Storable
. Ten pierwszy musiałem doinstalować do mojej FC5.
Z tym był zresztą pewien kłopot ponieważ yum
nie zadziałał--nie
wiem czemu. Ostatecznie sprawę rozwiązało ,,ręczne'' ściągnięcie
perl-GDGraph-1.4307-1.fc5.noarch.rpm
,
perl-GDTextUtil-0.86-7.fc5.noarch.rpm
i perl-GD-2.35-1.fc5.i386.rpm
ze strony
rpm.pbone.net.
Przy okazji dowiedziałem się jak ,,porządnie'' wycentrować tabelę w oknie przeglądarki:
<table style='margin-left: auto; margin-right: auto;' ...
Łączną liczbę odsłon dla
wszystkich zdjęć -- por. poprzedni
wpis na ten temat -- można ustalić
programistycznie ściągając wszystkie strony albumu (mają one URLe
kończące się na pageliczba
, tj. page1
,
page2
, page3
, itp.). Pod miniaturą
każdej fotografii jest odpowiednia informacja. Zwykłe
LWP::Simple
w zupełności by do tego wystarczył:
use LWP::Simple; my $max_page = $ARGV[0] || 1; # nie podano ile -- ściągnij pierwszą $urlbase = "http://www.flickr.com/photos/tprzechlewski/page"; for ($p=1; $p =< $max_page; $p++ ) { $content = get($urlbase . $p ); die "Couldn't get it!" unless defined $content; print $content; }
Niech powyższy kod zapisano w ftotal.pl
.
Teraz można by np. ściągnąć wszystkie strony podając
ftotal.pl 161 > ftotal.log
a następnie wyłuskać odpowiednie
informacje z pliku ftotal.log
innym skryptem.
Ale... Ale jest jeden problem. Flickr słusznie nie liczy odsłon (zalogowanego) właściciela albumu. Skrypt nie autoryzuje dostępu i działa jako ,,osoba trzecia'' więc jednocześnie sztucznie nabija statystykę. Jeżeli skrypt byłby uruchamiany cyklicznie zmieniłby znacząco statystykę odsłon głównych stron w albumie. Przykładowo w moim przypadku byłoby to dodanie 161 odsłon, bo tyle liczy -- obecnie -- stron głównych mój album. Można by machnąć ręką, ale z drugiej strony jakby udało się skrypt zalogować...
Logowanie
do www.flickr.com
jest
jednak cokolwiek skomplikowane.
Kombinowałem na różne sposoby szukając w google albo gotowców albo
podpowiedzi. Pierwszym ,,podejrzanym''
był moduł WWW::Mechanize
:
#!/usr/bin/perl use WWW::Mechanize; my $mech = WWW::Mechanize->new( autocheck => 1 ); $mech->credentials( 'login' => 'password' ); $mech->get( 'http://www.flickr.com/photos/tprzechlewski/page1/' ); print $mech->content();
Nie działa... Próbowałem, też WWW::Mechanize::Shell
,
opisany przykładowo w tekście Michaela Schilli
Simple
Data Scraper
(tutaj
jest polskie tłumaczenie). BTW były pewne kłopoty z jego zainstalowaniem, ponieważ
make test
kończy się błędem...
Szukając wskazówek do rozwiązania mojego problemu
znalazłem także potencjalnie przydatny tekst pt.
Secure
Web site access with Perl. Podsumowując WWW::Mechanize
okazał
się strzałem w płot, ale może się przyda do czegoś innego...
Rozwiązanie znalazłem -- jak to często bywa -- trochę przypadkowo. Punktem wyjścia
były skrypty ze
strony: coder.home.cosmic-cow.net
(ich kopie
umieściłem tutaj).
Następnie posługując się wtyczką do Firefoxa pn. Live HTTP headers
ustaliłem co i gdzie trzeba zmienić.
Skrypt wykorzystuje moduły HTTP::Request::Common
i LWP::UserAgent
, koncepcyjnie jest mało skomplikowany ale dość rozwlekły
bo liczy ca 100 wierszy. Nie będę go więc cytował, jest dostępny
tutaj.
Nie do końca jestem też pewny czy wszystkie wywołania GET
są potrzebne, ale nie mam czasu/wiedzy tego optymalizować,
ważne że działa, tj. udaje zalogowanego
użytkownika serwisu flickr.
Skrypt działa w ten sposób, że ściąga n stron ,,głównych'' z mojego konta
flickr (te URLe przypominam kończą się na pageliczba
). Liczbę
n, podaną jako parametr wywołania skryptu,
ustalam ,,empirycznie'' konsultując
się z flickr.com (ewentualnie w wersji gold-extended skryptu można by to zautomatyzować):
perl flick-total-views.pl 161 > flick-total-views.log && \ perl -h flick-aggr-totals.pl flick-total-views.log > stats.html
Skrypt flick-aggr-totals.pl
zlicza
co trzeba parsując flick-total-views.log
.
Na razie pomija pliki, które nie były wcale oglądane (tj. 0 views),
ale to łatwo poprawić/zmienić, bo
kod HTML generowany przez www.flickr/ nie jest specjalnie zaplątany.
Wynik pierwszego zastosowanie ww. skryptów zamieściłem
na mojej stronie.
Flickr wyświetla liczbę że tak powiem odsłon pod każdym zdjęciem, zbiorczo dla każdego zbioru oraz łącznie dla całego albumu (zakreślone na czerwono na rysunkach poniżej). Wydawać by się mogło, że np. sumując odsłony dla wszystkich zdjęć otrzyma się łączną liczbę odsłon w albumie, to znaczy ile razy oglądano nasze zdjęcia. Już na pierwszy rzut oka widać, że tak nie jest. Po prostu nic nie jest sumowane a każdy licznik ,,liczy'' swoją stronę. Odzielnie jest sumowana ,,strona główna'', oddzielnie każda strona dla pojedynczego zdjęcia i oddzielnie strona główna każdego zbioru.
A jak obliczyć łączną liczbę odsłon dla wszystkich zdjęć?
Wydawałoby się, że to pryszcz, bo flickr słynny jest ze swojego API.
Akurat tego jednak nie da się ustalić -- nie ma takiej metody.
Wprawdzie
flickr.activity.userPhotos
.
zwraca m.in. liczbę wyświetleń każdej pojedynczej strony, ale
tylko dla stron na których coś się stało: dodano komentarz, ktoś
dodał taga albo dodał zdjęcie do swoich ulubionych. Do tego maksymalnie
można ściągnąć 50 zdjęć na raz (maksymalna wartość per_page
),
parametr timeframe
może przyjąć maksymalnie
wartość jednego miesiąca (30d
, większe wartości są ignorowane)
a metodę można uruchomić
powtórnie nie częściej niż co godzinę (czyli co godzinę można ściągnąć jedną stronę).
Poddałem się...
Nie ustaliłem wprawdzie ile było odsłon zdjęć w moim albumie
ale eksperymentując z API flickera odkryłem przynajmniej jak można
obejść się bez perlowego pakietu
Flickr-API
(ale nie bez Perla). Otóż wystarczą moduły LWP::Simple
oraz Digest::MD5
:
Niektóre metody nie wymagają uwierzytelnienia. Ich wywołanie jest szczególnie
proste -- nie jest potrzebny nawet moduł Digest::MD5
-- i sprowadza się do konstruowania adresów
URL według następującego schematu (znak \
na końcu oznacza kontynuację wiersza):
http://www.flickr.com/services/rest/?method=metoda¶metr1=wartość1\ ¶metr2=wartość2...
W metodach, które uwierzytelnienia wymagają sprawa się komplikuje. Trzeba
podać api_key, auth_token oraz secret (poniżej nazwany shared_secret)
opisane tutaj
i/lub w dokumentacji modułu Flickr-Upload
.
Najpierw należy zbudować napis według schematu:
secretapi_keyapi_keyauth_tokenauth_tokenmethodmethodarg1wart1arg2wart2 ...
Następnie utworzyć jego skrót za pomocą funkcji MD5. W przypadku Perla może to
wyglądać jak na poniższym przykładzie (metoda flickr.activity.userPhotos
ma argumenty
page
, per_page
oraz timeframe
).
Obliczony skrót dodajemy jako ostatnią część adresu URL:
Digest::MD5 qw(md5_hex); my $method = 'flickr.activity.userPhotos'; ## ... ## skrót MD5: my $api_sig = md5_hex( "${shared_secret}api_key${api_key}auth_token${auth_token}method${method}" . "page${page}" . "per_page${per_page}" . "timeframe${timeframe}" ) ; my $url = "http://www.flickr.com/services/rest/?method=$method" . "&api_key=$api_key" . "&auth_token=$auth_token" . "&page=$page" . "&per_page=$per_page" . "&timeframe=$timeframe" . "&api_sig=$api_sig" ; ## wstaw skrót tutaj print $url;
Przy okazji -- jak to często bywa -- znalazłem ciekawą stronę dotyczącą języka Perl. Jest też na ww. stronie opis pakietu Flickr-Upload, z którego też korzystam. Norman Walsh zaimplementował nawet API flickra w XSLT -- ciekawe ale przydatność taka sobie.
Dodać jest łatwo, ale jak usunąć? Nie jest to oczywiste. Ale doszedłem
jak to zrobić: uruchomić tzw. organizera (czyli kliknąć
w organize). Teraz kliknąć w Set&Collections.
Wybrać -- dwuklikiem -- odpowiedni zbiór (Set). Jak się załadują
miniaturki zdjęć przeciągnąć niechciane poza ramkę zawierającą
miniaturki jednocześnie wciskając klawisz r
. Powinno
działać. U mnie przynajmniej działało z FF (wersja 2.0.0.4).