#! /usr/bin/perl ########################################################################## # This script must be encoded in UTF-8 ########################################################################## # Modules use strict; use CGI; use SOAP::Lite; use BerkeleyDB; use Cache::File; ########################################################################## # Setting my $country = 'JP'; my $cgi_url ='/cgi-bin/barcode2.cgi'; my $associate_tag = 'nakamuraminor-22'; my $susbscription_id = 'ECS-4.0 のサブスクリプション ID で埋めてね'; # data_home 以下に CGI で書き込み可能な JAN、ASIN というディレクトリを作ります my $data_home = '/home/httpd/data/barcode2/'; my $jan_to_asin_db = $data_home . 'JAN/jan_to_asin_db'; my $asin_product_db = $data_home . 'ASIN/'; ########################################################################## # my %aws_wsdl_map = ( 'US' => 'http://webservices.amazon.com/AWSECommerceService/AWSECommerceService.wsdl', 'DE' => 'http://webservices.amazon.com/AWSECommerceService/DE/AWSECommerceService.wsdl', 'JP' => 'http://webservices.amazon.com/AWSECommerceService/JP/AWSECommerceService.wsdl', 'UK' => 'http://webservices.amazon.com/AWSECommerceService/UK/AWSECommerceService.wsdl', ); my $aws_wsdl = $aws_wsdl_map{$country}; ########################################################################## # my $query = new CGI; my @codes = parse_input_lines($query->param("list")); my $category = $query->param('SearchIndex'); my $db1 = new BerkeleyDB::Hash -Filename => $jan_to_asin_db, -Flags => DB_CREATE; my $cache1 = Cache::File->new(cache_root => $asin_product_db, lock_level => Cache::File::LOCK_LOCAL, default_expires => '7 day' ); ########################################################################## # Body print $query->header("text/html; charset=UTF-8"); print < バーコード検索

バーコード検索

Amazon E-Commerce Service を利用して、 商品についているバーコード(13桁の JAN コード) から製品を検索します。


Electronics Music Classical DVD Kitchen Software VideoGames

EOF my $counter = 1; foreach my $i (@codes) { print ""; print ""; my ($status, $code) = ($i =~ /^(\S+)\t(.*)$/); my $item; if ($status eq 'JAN' || $status eq 'ASIN') { if ($status eq 'JAN') { if ($code =~ /^978(\d{10})/ ){ my $asin = tran_isbn($code); if ($asin) { $db1->db_put($code, $asin); $db1->db_sync(); } $item = make_request_asin($asin); } else { $item = make_request_jan($code, $category); } } else { $item = make_request_asin($code); } # View print ""; if ($item) { my $asin = $item->{ASIN}; my $url = $item->{DetailPageURL}; my $group = $item->{ItemAttributes}->{ProductGroup}; my $price = $item->{ItemAttributes}->{ListPrice}->{FormattedPrice}; my $title = $item->{ItemAttributes}->{Title}; print ""; } else { print ""; } } else { print ""; print ""; } print "\n"; $counter++; } print < EOF # close database $db1->db_close(); exit(0); ########################################################################## # Subroutines # -------------------------------------------------------------------- # FORM から入力されたデータを解析して、EAN-13 コードか ASIN コードだけを抽出して返す。 sub parse_input_lines { my ($list) = @_; my @result; my @lines = split('\n', $list); foreach my $line (@lines) { ($line) = ($line =~ /\s*(\S+)/); my ($jan1) = ($line =~ /^(\d{13})$/); if ($jan1) { push @result, "JAN\t$jan1"; next; } my ($asin) = ($line =~ /^(\S{10})$/); if ($asin) { push @result, "ASIN\t$asin"; next; } push @result, "ERR\t$line"; } return @result; } # -------------------------------------------------------------------- # 書籍の EAN-13 を ISBN に変換 sub tran_isbn { my ($code) = @_; my ($isbn) = ($code =~ /^978(\d{9})\d$/); if ($isbn) { my ($n1,$n2,$n3,$n4,$n5,$n6,$n7,$n8,$n9) = ($isbn =~/(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)/); my $sum = 1*$n1+2*$n2+3*$n3+4*$n4+5*$n5+6*$n6+7*$n7+8*$n8+9*$n9; my $rem = $sum % 11; if ($rem == 10) { return sprintf('%9dX', $isbn); } else { return sprintf('%9d%1d', $isbn, $rem); } } return 0; } # -------------------------------------------------------------------- # EAN-13/JAN-13 で ECS にリクストを行う sub make_request_jan { my ($jan, $category) = @_ or die "Incorrect number of arguments passed to make_request \n"; my $asin; my $c; my $item; my $value; if ($db1->db_get($jan, $value) == 0) { if ($value =~ /\t/) { ($asin, $c) = ($value =~ /(\S+)\t(\S+)/); } else { $asin = $value; } if ($cache1->exists($asin)) { return $cache1->thaw($asin); } else { return make_request_asin($asin); } } else { my $request_complex_type = \SOAP::Data->value( SOAP::Data->name('IdType')->value('EAN'), SOAP::Data->name('ItemId')->value($jan), SOAP::Data->name('SearchIndex')->value($category), ); my $itemsearch_request = SOAP::Data->value( SOAP::Data->name('ResponseGroup')->value('Large'), SOAP::Data->name('SubscriptionId')->value($susbscription_id), SOAP::Data->name('AssociateTag')->value($associate_tag), SOAP::Data->name('Request')->value($request_complex_type), ); my $aws_handle = SOAP::Lite->service("$aws_wsdl"); $aws_handle->outputxml(); # invoking AWS::ItemSearch my $response = $aws_handle->ItemLookup($itemsearch_request); my $som = $aws_handle->call(); # When using a wsdl, SOAP::Lite returns the actual data from the server, if ($som->fault) { die "SOAP request failed"; } my $node_num = 1; while($som->match("//Items/[$node_num]")) { $node_num++; next unless $som->match("//Items/[$node_num]/ItemAttributes"); # my @authors = $som->valueof("//Items/[$node_num]/ItemAttributes/Author"); $item = $som->valueof("//Items/[$node_num]"); $asin = $item->{ASIN}; $db1->db_put($jan, $asin); $db1->db_sync(); $cache1->freeze($asin, $item); return $item; } } return 0; } # -------------------------------------------------------------------- # ASIN コードをキーに ECS へリクエストを行う。 sub make_request_asin { my ($asin) = @_ or die "Incorrect number of arguments passed to make_request \n"; if ($cache1->exists($asin)) { return $cache1->thaw($asin); } my $item; my $request_complex_type = \SOAP::Data->value( SOAP::Data->name('IdType')->value('ASIN'), SOAP::Data->name('ItemId')->value($asin), ); my $itemsearch_request = SOAP::Data->value( SOAP::Data->name('ResponseGroup')->value('Large'), SOAP::Data->name('SubscriptionId')->value($susbscription_id), SOAP::Data->name('AssociateTag')->value($associate_tag), SOAP::Data->name('Request')->value($request_complex_type), ); my $aws_handle = SOAP::Lite->service("$aws_wsdl"); $aws_handle->outputxml(); # invoking AWS::ItemSearch my $response = $aws_handle->ItemLookup($itemsearch_request); my $som = $aws_handle->call(); # When using a wsdl, SOAP::Lite returns the actual data from the server, if ($som->fault) { die "SOAP request failed"; } my $node_num = 1; while($som->match("//Items/[$node_num]")) { $node_num++; next unless $som->match("//Items/[$node_num]/ItemAttributes"); # my @authors = $som->valueof("//Items/[$node_num]/ItemAttributes/Author"); $item = $som->valueof("//Items/[$node_num]"); $cache1->freeze($asin, $item); return $item; } return 0; }
NoInput numberASINTitleGroupPrice
$counter$code$asin$title$group$priceNot Found$code?