File Coverage

blib/lib/URI/Amazon/APA.pm
Criterion Covered Total %
statement 51 53 96.2
branch 3 6 50.0
condition 3 8 37.5
subroutine 10 10 100.0
pod 3 3 100.0
total 70 80 87.5


line stmt bran cond sub pod time code
1             package URI::Amazon::APA;
2 2     2   66603 use warnings;
  2         11  
  2         95  
3 2     2   15 use strict;
  2         2  
  2         109  
4             our $VERSION = sprintf "%d.%02d", q$Revision: 0.6 $ =~ /(\d+)/g;
5 2     2   11 use Carp;
  2         3  
  2         119  
6 2     2   1040 use Digest::SHA qw(hmac_sha256_base64);
  2         5962  
  2         154  
7 2     2   941 use URI::Escape;
  2         2846  
  2         120  
8 2     2   1137 use Encode qw/decode_utf8/;
  2         20901  
  2         140  
9 2     2   21 use base 'URI::http';
  2         4  
  2         850  
10              
11             sub new{
12 1     1 1 85 my $class = shift;
13 1         8 my $self = URI->new(@_);
14 1 50       252 $self->scheme =~ /^https?$/ or carp "must be http or https";
15             # we need the following or URI resets the port to 80.
16 1 50 33     99 $self->port(443) if $self->scheme eq 'https' && $self->port == 443;
17 1         19 bless $self, $class;
18             }
19              
20             sub sign {
21 1     1 1 105 my $self = shift;
22 1         5 my (%arg) = @_;
23 1         4 my %eq = map { split /=/, $_ } split /&/, $self->query();
  7         33  
24 1         5 my %q = map { $_ => decode_utf8( uri_unescape( $eq{$_} ) ) } keys %eq;
  7         199  
25 1 50       25 $q{Keywords} =~ s/\+/ /g if $q{Keywords};
26 1         3 $q{AWSAccessKeyId} = $arg{key};
27 1   33     3 $q{Timestamp} ||= do {
28 0         0 my ( $ss, $mm, $hh, $dd, $mo, $yy ) = gmtime();
29 0         0 join '',
30             sprintf( '%04d-%02d-%02d', $yy + 1900, $mo + 1, $dd ), 'T',
31             sprintf( '%02d:%02d:%02d', $hh, $mm, $ss ), 'Z';
32             };
33 1   50     32 $q{Version} ||= '2010-09-01';
34             my $sq = join '&',
35 1         10 map { $_ . '=' . uri_escape_utf8( $q{$_}, "^A-Za-z0-9\-_.~" ) }
  7         404  
36             sort keys %q;
37 1         44 my $tosign = join "\n", 'GET', $self->host, $self->path, $sq;
38 1         108 my $signature = hmac_sha256_base64( $tosign, $arg{secret} );
39 1         8 $signature .= '=' while length($signature) % 4; # padding required
40 1         4 $q{Signature} = $signature;
41 1         8 $self->query_form( \%q );
42 1         322 $self;
43             }
44              
45             sub signature {
46 1     1 1 5 my $self = shift;
47 1         2 my (%arg) = @_;
48 1         3 my %eq = map { split /=/, $_ } split /&/, $self->query();
  8         33  
49 1         5 my %q = map { $_ => uri_unescape( $eq{$_} ) } keys %eq;
  8         72  
50 1         21 $q{Signature};
51             }
52              
53             1; # End of URI::Amazon::APA
54              
55             =head1 NAME
56              
57             URI::Amazon::APA - URI to access Amazon Product Advertising API
58              
59             =head1 VERSION
60              
61             $Id: APA.pm,v 0.6 2018/09/22 14:19:06 dankogai Exp dankogai $
62              
63             =head1 SYNOPSIS
64              
65             # self-explanatory
66             use strict;
67             use warnings;
68             use URI::Amazon::APA;
69             use LWP::UserAgent;
70             use XML::Simple;
71             use YAML::Syck;
72              
73             use URI::Amazon::APA; # instead of URI
74             my $u = URI::Amazon::APA->new('http://webservices.amazon.com/onca/xml');
75             # or https://webservices.amazon.com/onca/xml
76             $u->query_form(
77             Service => 'AWSECommerceService',
78             Operation => 'ItemSearch',
79             Title => shift || 'Perl',
80             SearchIndex => 'Books',
81             );
82             $u->sign(
83             key => $public_key,
84             secret => $private_key,
85             );
86              
87             my $ua = LWP::UserAgent->new;
88             my $r = $ua->get($u);
89             if ( $r->is_success ) {
90             print YAML::Syck::Dump( XMLin( $r->content ) );
91             }
92             else {
93             print $r->status_line, $r->as_string;
94             }
95              
96             =head1 EXPORT
97              
98             None.
99              
100             =head1 METHODS
101              
102             This adds the following methods to L object
103              
104             =head2 sign
105              
106             Sings the URI accordingly to the Amazon Product Advertising API.
107              
108             $u->sign(
109             key => $public_key,
110             secret => $private_key,
111             );
112              
113             =head2 signature
114              
115             Checks the signature within the URI;
116              
117             print "The signature is " : $u->signature;
118              
119             =head1 AUTHOR
120              
121             Dan Kogai, C<< >>
122              
123             =head1 BUGS
124              
125             Please report any bugs or feature requests to C, or through
126             the web interface at L. I will be notified, and then you'll
127             automatically be notified of progress on your bug as I make changes.
128              
129             =head1 SUPPORT
130              
131             You can find documentation for this module with the perldoc command.
132              
133             perldoc URI::Amazon::APA
134              
135              
136             You can also look for information at:
137              
138             =over 4
139              
140             =item * RT: CPAN's request tracker
141              
142             L
143              
144             =item * AnnoCPAN: Annotated CPAN documentation
145              
146             L
147              
148             =item * CPAN Ratings
149              
150             L
151              
152             =item * Search CPAN
153              
154             L
155              
156             =back
157              
158             =head1 ACKNOWLEDGEMENTS
159              
160             L
161              
162             =head1 COPYRIGHT & LICENSE
163              
164             Copyright 2009 Dan Kogai, all rights reserved.
165              
166             This program is free software; you can redistribute it and/or modify it
167             under the same terms as Perl itself.