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("", \&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 }