File Coverage

blib/lib/XML/Amazon.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


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