File Coverage

blib/lib/XML/Amazon.pm
Criterion Covered Total %
statement 35 177 19.7
branch 0 58 0.0
condition 0 23 0.0
subroutine 12 18 66.6
pod 4 4 100.0
total 51 280 18.2


line stmt bran cond sub pod time code
1             package XML::Amazon;
2              
3 1     1   14161 use 5.008;
  1         2  
4              
5 1     1   4 use strict;
  1         1  
  1         16  
6 1     1   3 use warnings;
  1         1  
  1         21  
7              
8 1     1   499 use utf8;
  1         11  
  1         6  
9              
10 1     1   377 use LWP::Simple qw ();
  1         48695  
  1         23  
11 1     1   657 use XML::Simple;
  1         6019  
  1         5  
12 1     1   470 use XML::Amazon::Item;
  1         1  
  1         23  
13 1     1   299 use XML::Amazon::Collection;
  1         2  
  1         21  
14 1     1   508 use Data::Dumper qw ();
  1         4107  
  1         21  
15 1     1   5 use URI::Escape qw();
  1         1  
  1         15  
16 1     1   436 use Digest::SHA qw(hmac_sha256_hex hmac_sha256_base64);
  1         2498  
  1         72  
17 1     1   429 use POSIX qw(strftime);
  1         4120  
  1         4  
18              
19             our $VERSION = '0.13';
20              
21             sub new{
22 0     0 1   my($pkg, %options) = @_;
23 0 0         die 'No Access Key ID provided!' unless $options{'token'};
24 0 0         die 'No Secret Access Key provided!' unless $options{'sak'};
25 0           my $locale = $options{'locale'};
26 0   0       $locale ||= "us";
27 0 0 0       die "Invalid locale" unless $locale eq "jp" || $locale eq "uk" || $locale eq "fr" || $locale eq "us" || $locale eq "de"|| $locale eq "ca";
      0        
      0        
      0        
      0        
28 0   0       my $associate = $options{'associate'} || 'webservices-20';
29              
30 0           my $url;
31              
32 0 0         $url = 'ecs.amazonaws.jp' if $locale eq "jp";
33 0 0         $url = 'ecs.amazonaws.co.uk' if $locale eq "uk";
34 0 0         $url = 'ecs.amazonaws.fr' if $locale eq "fr";
35 0 0         $url = 'ecs.amazonaws.de' if $locale eq "de";
36 0 0         $url = 'ecs.amazonaws.ca' if $locale eq "ca";
37 0 0         $url = 'ecs.amazonaws.com' if $locale eq "us";
38              
39              
40             my $req = {
41             'Service' => 'AWSECommerceService',
42 0           'AWSAccessKeyId' => $options{'token'},
43             'AssociateTag' => $associate,
44             'Version' => '2009-03-31',
45             'Timestamp' => strftime( "%Y-%m-%dT%TZ", gmtime() )
46             };
47              
48             bless{
49             token => $options{'token'},
50 0           sak => $options{'sak'},
51             associate => $associate,
52             locale => $locale,
53             url => $url,
54             req => $req,
55             data => undef,
56             success => '0'
57             }, $pkg;
58             }
59              
60             sub _get {
61 0     0     my $self = shift;
62 0           my $type = shift;
63 0           my $query = shift;
64 0           my $field = shift;
65 0 0         $self->asin($query) if $type eq "asin";
66 0 0         $self->search($query,$field) if $type eq "search";
67             }
68              
69             sub asin{
70 0     0 1   my $self = shift;
71 0           my $asin = shift;
72 0           my $url = $self->{url};
73 0           my $ITEM = XML::Amazon::Item->new();
74              
75 0 0         warn 'Apparently not an appropriate ASIN' if $asin =~ /[^a-zA-Z0-9]/;
76              
77 0           my %params = %{$self->{req}};
  0            
78              
79 0           $params{'Operation'} = 'ItemLookup';
80 0           $params{'ResponseGroup'} = 'Images,ItemAttributes';
81 0           $params{'ItemId'} = $asin;
82 0           $params{'Version'} = '2009-03-31';
83              
84 0           my $data = $self->_get_data(\%params);
85              
86 0           my $xs = new XML::Simple(SuppressEmpty => undef, ForceArray => ['Creator', 'Author', 'Artist', 'Director', 'Actor']);
87 0           my $pl = $xs->XMLin($data);
88 0           $self->{data} = $pl;
89              
90 0 0         if ($pl->{Items}->{Item}->{ASIN}){
91 0           $ITEM->{asin} = $pl->{Items}->{Item}->{ASIN};
92 0           $ITEM->{title} = $pl->{Items}->{Item}->{ItemAttributes}->{Title};
93 0           $ITEM->{type} = $pl->{Items}->{Item}->{ItemAttributes}->{ProductGroup};
94              
95              
96 0 0         if ($pl->{Items}->{Item}->{ItemAttributes}->{Author}->[0]){
97 0           for (my $i = 0; $pl->{Items}->{Item}->{ItemAttributes}->{Author}->[$i]; $i++){
98 0           $ITEM->{authors}->[$i] = $pl->{Items}->{Item}->{ItemAttributes}->{Author}->[$i];
99             }
100             }
101              
102 0 0         if ($pl->{Items}->{Item}->{ItemAttributes}->{Artist}->[0]){
103 0           for (my $i = 0; $pl->{Items}->{Item}->{ItemAttributes}->{Artist}->[$i]; $i++){
104 0           $ITEM->{artists}->[$i] = $pl->{Items}->{Item}->{ItemAttributes}->{Artist}->[$i];
105             }
106             }
107 0 0         if ($pl->{Items}->{Item}->{ItemAttributes}->{Actor}->[0]){
108 0           for (my $i = 0; $pl->{Items}->{Item}->{ItemAttributes}->{Actor}->[$i]; $i++){
109 0           $ITEM->{actors}->[$i] = $pl->{Items}->{Item}->{ItemAttributes}->{Actor}->[$i];
110             }
111             }
112              
113 0 0         if ($pl->{Items}->{Item}->{ItemAttributes}->{Director}->[0]){
114 0           for (my $i = 0; $pl->{Items}->{Item}->{ItemAttributes}->{Director}->[$i]; $i++){
115 0           $ITEM->{directors}->[$i] = $pl->{Items}->{Item}->{ItemAttributes}->{Director}->[$i];
116             }
117             }
118              
119              
120 0 0         if ($pl->{Items}->{Item}->{ItemAttributes}->{Creator}->[0]->{content}){
121 0           for (my $i = 0; $pl->{Items}->{Item}->{ItemAttributes}->{Creator}->[$i]->{content}; $i++){
122 0           $ITEM->{creators}->[$i] = $pl->{Items}->{Item}->{ItemAttributes}->{Creator}->[$i]->{content};
123             }
124             }
125              
126              
127 0           $ITEM->{price} = $pl->{Items}->{Item}->{ItemAttributes}->{ListPrice}->{FormattedPrice};
128 0           $ITEM->{author} = $ITEM->{authors}->[0];
129 0           $ITEM->{url} = $pl->{Items}->{Item}->{DetailPageURL};
130 0           $ITEM->{publisher} = $pl->{Items}->{Item}->{ItemAttributes}->{Publisher};
131 0           $ITEM->{smallimage} = $pl->{Items}->{Item}->{SmallImage}->{URL};
132 0           $ITEM->{mediumimage} = $pl->{Items}->{Item}->{MediumImage}->{URL};
133 0 0         $ITEM->{mediumimage} = $ITEM->{smallimage} unless $ITEM->{mediumimage};
134 0           $ITEM->{largeimage} = $pl->{Items}->{Item}->{LargeImage}->{URL};
135 0 0         $ITEM->{largeimage} = $ITEM->{mediumimage} unless $ITEM->{largeimage};
136              
137 0           $self->{success} = '1';
138 0           return $ITEM;
139             }
140             else{
141 0           $self->{success} = '0';
142 0           warn 'No item found';
143 0           return '';
144             }
145             }
146              
147             sub search{
148 0     0 1   my($self, %options) = @_;
149 0           my $keywords = $options{'keywords'};
150 0   0       my $type = $options{'type'} || "Blended";
151 0   0       my $page = $options{'page'} || 1;
152              
153 0           my %params = %{$self->{req}};
  0            
154              
155 0           $params{'Operation'} = 'ItemSearch';
156 0           $params{'SearchIndex'} = $type;
157 0           $params{'ResponseGroup'} = 'Images,ItemAttributes';
158 0           $params{'Keywords'} = $keywords;
159 0           $params{'ItemPage'} = $page;
160              
161 0           my $data = $self->_get_data(\%params);
162              
163 0           my $xs = new XML::Simple(SuppressEmpty => undef, ForceArray => ['Item', 'Creator', 'Author', 'Artist', 'Actor', 'Director']);
164 0           my $pl = $xs->XMLin($data);
165 0           $self->{data} = $pl;
166              
167 0           my $collection = XML::Amazon::Collection->new();
168 0 0         if ($pl->{Items}->{Item}->[0]->{ASIN}){
169 0           $collection->{total_results} = $pl->{Items}->{TotalResults};
170 0           $collection->{total_pages} = $pl->{Items}->{TotalPages};
171 0           $collection->{current_page} = $pl->{Items}->{Request}->{ItemSearchRequest}->{ItemPage};
172              
173 0           for (my $i = 0; $pl->{Items}->{Item}->[$i]; $i++){
174              
175 0           my $new_item = XML::Amazon::Item->new();
176              
177 0           $new_item->{asin} = $pl->{Items}->{Item}->[$i]->{ASIN};
178 0           $new_item->{title} = $pl->{Items}->{Item}->[$i]->{ItemAttributes}->{Title};
179 0           $new_item->{publisher} = $pl->{Items}->{Item}->[$i]->{ItemAttributes}->{Publisher};
180 0           $new_item->{url} = $pl->{Items}->{Item}->[$i]->{DetailPageURL};
181 0           $new_item->{type} = $pl->{Items}->{Item}->[$i]->{ItemAttributes}->{ProductGroup};
182              
183 0 0         if ($pl->{Items}->{Item}->[$i]->{ItemAttributes}->{Author}->[0]){
184 0           for (my $j = 0; $pl->{Items}->{Item}->[$i]->{ItemAttributes}->{Author}->[$j]; $j++){
185 0           $new_item->{authors}->[$j] = $pl->{Items}->{Item}->[$i]->{ItemAttributes}->{Author}->[$j];
186             }
187             }
188              
189 0 0         if ($pl->{Items}->{Item}->[$i]->{ItemAttributes}->{Artist}->[0]){
190 0           for (my $j = 0; $pl->{Items}->{Item}->[$i]->{ItemAttributes}->{Artist}->[$j]; $j++){
191 0           $new_item->{artists}->[$j] = $pl->{Items}->{Item}->[$i]->{ItemAttributes}->{Artist}->[$j];
192             }
193             }
194              
195 0 0         if ($pl->{Items}->{Item}->[$i]->{ItemAttributes}->{Creator}->[0]->{content}){
196 0           for (my $j = 0; $pl->{Items}->{Item}->[$i]->{ItemAttributes}->{Creator}->[$j]->{content}; $j++){
197 0           $new_item->{creators}->[$j] = $pl->{Items}->{Item}->[$i]->{ItemAttributes}->{Creator}->[$j]->{content};
198             }
199             }
200              
201 0 0         if ($pl->{Items}->{Item}->[$i]->{ItemAttributes}->{Director}->[0]){
202 0           for (my $j = 0; $pl->{Items}->{Item}->[$i]->{ItemAttributes}->{Director}->[$j]; $j++){
203 0           $new_item->{directors}->[$j] = $pl->{Items}->{Item}->[$i]->{ItemAttributes}->{Director}->[$j];
204             }
205             }
206              
207              
208 0 0         if ($pl->{Items}->{Item}->[$i]->{ItemAttributes}->{Actor}->[0]){
209 0           for (my $j = 0; $pl->{Items}->{Item}->[$i]->{ItemAttributes}->{Actor}->[$j]; $j++){
210 0           $new_item->{actors}->[$j] = $pl->{Items}->{Item}->[$i]->{ItemAttributes}->{Actor}->[$j];
211             }
212             }
213              
214              
215              
216 0           $new_item->{price} = $pl->{Items}->{Item}->[$i]->{ItemAttributes}->{ListPrice}->{FormattedPrice};
217 0           $new_item->{smallimage} = $pl->{Items}->{Item}->[$i]->{SmallImage}->{URL};
218 0           $new_item->{mediumimage} = $pl->{Items}->{Item}->[$i]->{MediumImage}->{URL};
219 0 0         $new_item->{mediumimage} = $new_item->{smallimage} unless $new_item->{mediumimage};
220 0           $new_item->{largeimage} = $pl->{Items}->{Item}->[$i]->{LargeImage}->{URL};
221 0 0         $new_item->{largeimage} = $new_item->{mediumimage} unless $new_item->{largeimage};
222              
223 0           $collection->add_Amazon($new_item);
224             }
225 0           $self->{success} = '1';
226 0           return $collection;
227              
228             }
229              
230             else{
231 0           $self->{success} = '0';
232 0           warn 'No item found';
233 0           return '';
234             }
235             }
236              
237             sub is_success {
238 0     0 1   my $self = shift;
239 0           return $self->{success};
240              
241             }
242              
243             sub _get_data {
244 0     0     my $self = shift;
245 0           my $params = shift;
246              
247 0           my $url = $self->{url};
248 0           my @param;
249 0           foreach my $key (sort { $a cmp $b } keys %{$params}){
  0            
  0            
250 0           push @param, $key . '=' . URI::Escape::uri_escape(${$params}{$key}, "^A-Za-z0-9\-_.~");
  0            
251             }
252              
253 0           my $string_to_sign = 'GET' . "\n" . $url . "\n" . '/onca/xml' . "\n" . join('&', @param);
254              
255 0           my $sign = hmac_sha256_base64($string_to_sign,$self->{sak});
256              
257 0           while (length($sign) % 4) {
258 0           $sign .= '=';
259             }
260              
261 0           push @param, 'Signature=' . URI::Escape::uri_escape($sign, "^A-Za-z0-9\-_.~");
262              
263 0 0         my $data = LWP::Simple::get('http://' . $url . '/onca/xml?' . join('&', @param))
264             or warn 'Couldn\'t get the XML';
265 0           return $data;
266              
267             }
268              
269             1;
270              
271             __END__