001 #!/usr/local/bin/perl -w
002 use strict;
003 use Tk;
004 use Tk::JPEG;
005 use POE;
006 use LWP::UserAgent::POE;
007 use Net::Amazon;
008 use Net::Amazon::Request::UPC;
009 use MIME::Base64;
010 use Rose::DB::Object::Loader;
011 use Log::Log4perl qw(:easy);
012
013 my @MODES = qw(books music dvd);
014
015 my $UA = LWP::UserAgent::POE->new();
016
017 my $loader = Rose::DB::Object::Loader->new(
018 db_dsn =>
019 "dbi:SQLite:dbname=articles.dat",
020 db_options => {
021 AutoCommit => 1, RaiseError => 1 },
022 );
023 $loader->make_classes();
024
025 my $top = $poe_main_window;
026 $top->configure(-title => "UPC Reader",
027 -background=> "#a2b2a3");
028 $top->geometry("200x300");
029
030 my $FOOTER = $top->Label();
031 $FOOTER->configure(-text =>
032 "Scan next item");
033
034 my $BYWHO = $top->Label();
035 my $UPC = $top->Label();
036 my $PHOTO = $top->Photo(-format => 'jpeg');
037 my $photolabel =
038 $top->Label(-image => $PHOTO);
039 my $entry = $top->Entry(
040 -textvariable => \my $UPC_VAR);
041
042 my $PRODUCT = $top->Label();
043
044 $entry->focus();
045
046 for my $w ($entry, $photolabel, $PRODUCT,
047 $BYWHO, $UPC, $FOOTER) {
048 $w->pack(-side => 'top', -expand => 1,
049 -fill => "x" );
050 }
051
052 $entry->bind("<Return>", \&scan_done);
053
054 my $session = POE::Session->create(
055 inline_states => {
056 _start => sub{
057 $poe_kernel->delay("_start", 60);
058 }
059 });
060
061 POE::Kernel->run();
062
063 ###########################################
064 sub scan_done {
065 ###########################################
066 $PHOTO->blank();
067 $PRODUCT->configure(-text => "");
068 $FOOTER->configure(-text =>
069 "Processing ...");
070 $BYWHO->configure(-text => "");
071 $UPC->configure(-text => $UPC_VAR);
072 resp_process(
073 amzn_fetch( $UPC_VAR ) );
074 $UPC_VAR = "";
075 }
076
077 ###########################################
078 sub amzn_fetch {
079 ###########################################
080 my($upc) = @_;
081
082 my $resp;
083
084 my $amzn = Net::Amazon->new(
085 token => 'XXXXXXXXXXXXXXXXXXXX',
086 ua => $UA,
087 );
088
089 for my $mode (@MODES) {
090
091 my $req =
092 Net::Amazon::Request::UPC->new(
093 upc => $upc,
094 mode => $mode,
095 );
096
097 $resp = $amzn->request($req);
098
099 if($resp->is_success()) {
100 return($resp, $mode, $upc);
101 last;
102 }
103
104 WARN "Nothing found in mode '$mode'";
105 }
106 return $resp;
107 }
108
109 ###########################################
110 sub resp_process {
111 ###########################################
112 my($resp, $mode, $upc) = @_;
113
114 if($resp->is_error()) {
115 $PRODUCT->configure(
116 -text => "NOT FOUND");
117 return 0;
118 }
119
120 my ($property) = $resp->properties();
121 my $imgurl = $property->ImageUrlMedium();
122 img_display( $imgurl );
123
124 my $a = Article->new();
125 $a->upc($upc);
126 $a->type($mode);
127 $a->title( $property->Title() );
128
129 if($mode eq "books") {
130 $a->bywho( $property->author() );
131 } elsif( $mode eq "music") {
132 $a->bywho( $property->artist() );
133 } else {
134 $a->bywho( "" );
135 }
136
137 $BYWHO->configure(-text => $a->bywho() );
138 $PRODUCT->configure(
139 -text => $a->title() );
140
141 if($a->load( speculative => 1 )) {
142 $PRODUCT->configure(
143 -text => "ALREADY EXISTS");
144 } else {
145 $a->save();
146 }
147
148 $FOOTER->configure(
149 -text => "Scan next item");
150 return 1;
151 }
152
153 ###########################################
154 sub img_display {
155 ###########################################
156 my($imgurl) = @_;
157
158 my $imgresp = $UA->get( $imgurl );
159
160 if($imgresp->is_success()) {
161 $PHOTO->configure( -data =>
162 encode_base64( $imgresp->content() ));
163 }
164 }