Jest gotowa aplikacja służąca do katalogowania książek za pomocą czytnika kodów kreskowych opisana w artykule A Perl script catalogs books and CDs... (tu jest wersja HTML z likiem do kodu źródłowego opisanego skryptu).
Od pierwsze strzału aplikacja nie działa. Żeby w ogóle Perl chciał program wykonać należy z przodu pliku dodać wiersz:
## http://perlmeister.com/forum/viewtopic.php?t=3596&sid=59d9cb0bda64235bda70315d6e9031e8 use POE::Loop::Tk ;
Teraz działa ale nie zawsze. Ponadto program Schilli'ego w zamierzeniu obsługuje tylko kody UPC a moje książki/płyty są oznaczane kodem UPC i/lub EAN.
Kody
EAN są 13 cyfrowe
a UPC
12 cyfrowe. Żeby było śmieszniej amazon.com
nie rozumie kodów EAN
-- trzeba odpytywać jakąś europejską filię, np. amazon.co.uk
.
## moja wersja procedury amzn_fetch: sub amzn_fetch { my($upc_or_ean) = @_; my $resp; my $amz_locale = 'us'; # default is US if ( length ("" . $upc_or_ean ) > 12) { $amz_locale = 'uk'; print STDERR "*** $upc_or_ean looks like EAN code\n"; } else { $amz_locale = 'us'; print STDERR "*** $upc_or_ean looks like UPC code\n"; } my $amzn = Net::Amazon->new( token => $amz_token, secret_key => $amz_secret, locale => $amz_locale, ua => $UA, ); my $req ; if ( $amz_locale eq 'uk') { print STDERR "*** Fetching from $amz_locale with mode $current_amz_cat ***\n"; $req = Net::Amazon::Request::EAN->new( ean => $upc_or_ean, mode => $current_amz_cat, ); } else { print STDERR "*** Fetching from $amz_locale with mode $current_amz_cat ***\n"; $req = Net::Amazon::Request::UPC->new( upc => $upc_or_ean, mode => $current_amz_cat, ); } $resp = $amzn->request($req); ## ... itd ...
Skrypt Schilli'ego zakłada ponadto, że zapytanie zawiera UPC/EAN oraz
nazwę kategorii (books, music DVD), bo tak kiedyś działał Amazon.
Teraz wydaje się, że działa inaczej.
Podanie np. kodu książki + kategorii music,
daje błąd.
Nie zamierzałem grzebać w pakiecie
Net::Amazon
,
więc zmieniłem skrypt w ten sposób, że kategoria jest deklarowana explicite
przez operatora:
my @MODES = qw(books music dvd); ## ... itd ... ## cf. http://www.ibm.com/developerworks/aix/library/au-perltkmodule2/ my $MODE = $top->Label(); my $current_amz_cat = $MODES[0]; ## domyślną jest pierwsza kategoria foreach(@MODES) { $MODE->Radiobutton( -text => $_, -value=> $_, -variable => \$current_amz_cat, -command => sub { print STDERR "*** Current mode is: $current_amz_cat \n"; } )->pack(-side => 'left', -expand => '1', -fill => "x" ) }
Na wypadek gdyby operator zapomniał kliknąć w co trzeba:
if($mode eq "books") { eval { $resp->properties()->isbn(); } ; ## bez eval będzie krasz if ($@) {## błąd jeżeli `item' nie zawiera isbn, tj. nie jest książką... print STDERR "*** ERROR: $@\n"; $PRODUCT->configure( -text => "NOT BOOKS TYPE ITEM / REENTER"); return 1; } ## ... itd ...
Opis książki różni się od opisu CD (np. książka ma element isbn
a płyta tracks
).
Schilli ominął ten problem ignorując elementy specyficzne,
definiując jeden typ rekordu i jedną tabelę.
Ostatnia zmiana w porównaniu do skryptu Schilli'ego, to
dodanie do bazy pola przechowującego opis książki/CD
w formacie XML (zamiast definiowania różnych tabel dla książek, płyt CD i filmów).
W zależności od typu danych
ten opis XML zawiera to co trzeba (czyli specyficzne dla opisywanego obiektu atrybuty).
Np:
Edward R. Tufte Edward R. Tufte The Visual Display of Quantitative Information Graphics Press USA 2nd edition 2001-01-31 0961392142 ]]>
Tak działającym skryptem skatalogowałem jakieś 30--40% zawartości mojej biblioteki. Stare książki nie mają kodu kreskowego. Część polskich książek jest w zasobach Amazona ale części nie ma (np. książki wyd. Readme -- i słusznie bo to prawie w całości badziewie:-)
Tu jest corpus delicti. Moja biblioteka jest tutaj i tutaj -- jakby ktoś był ciekaw.
Skrypty można znaleźć tutaj.
Dopisane 1 września 2011: Zapomniałem napisać o istotnej sprawie. Żeby móc odpytywać Amazon trzeba się zapisać do Product Advertising API, tj. założyć konto. Aby móc korzystać z ww. API trzeba wypełnić odpowiedni formularz i zgodzić się na licencję, która jest mówiąc oględnie taka sobie.
To begin the enrollment process, you must submit a complete and accurate enrollment form. In your enrollment form, you must describe the application you intend to develop and use with the Product Advertising API or on which you intend to display Product Advertising Content. We will evaluate your enrollment form and notify you of its acceptance or rejection. We may reject your enrollment form if we determine that your application is unsuitable. Unsuitable applications include those that:
do not have as their principal purpose advertising and marketing the Amazon Site and driving sales of products and services on the Amazon Site
Wygląda groźnie ale wystarczy podać -- jako opis aplikacji -- URL, pod którym będziemy ,,promować'' Amazon. Proces koncesyjny jest (póki co?) uproszczony -- nikt niczego nie rozpatruje. Ale to się może zmienić...
In addition, we may terminate or suspend your license to access and use the Product Advertising API, Data Feed, or any part of or all Product Advertising Content at any time without terminating this License Agreement by giving you written notice.
Jednym słowem do poważnych zastosowań to się nie nadaje. Ale do katalogowania własnej biblioteczki może być...
Po założeniu konta, pod adresem Manage Your Account→Access Identifiers →Click here w rubryce Access Credentials tworzymy/zarządzamy Access Key ID/Secret Access Key -- niezbędnymi do korzystania z opisywanego wyżej skryptu:
my $amz_token = '???'; ## Access Key ID my $amz_secret = '???'; ## Secret Access Key
Pobieranie informacji o książce/płycie o podanym numerze UPC (z amazon.com
):
#!/usr/bin/perl # use Net::Amazon; use Net::Amazon::Request::UPC; my $code = '633367991522' ; # UPC (z kodem EAN są problemy) # Token/secret_key do pobrania po zarejestrowaniu się na str. # https://aws-portal.amazon.com/gp/aws/developer/account/index.html/177-3749078-2923747 my $ua = Net::Amazon->new( token => '####################', secret_key => '########################################', ); my $req = Net::Amazon::Request::UPC->new( upc => $code, mode => 'music', ); # Response is of type Net::Amazon::Response::UPC my $resp = $ua->request($req); if($resp->is_success()) { print $resp->as_string(), " (UPC)\n"; } else { print "Error: ", $resp->message(), "\n"; } # end
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:-)