public
Description: Various scripts written by Jeremy Mates
Homepage: http://thrig.github.com/sial.org-scripts
Clone URL: git://github.com/thrig/sial.org-scripts.git
sial.org-scripts / amazon-util / amazon-util
100755 217 lines (148 sloc) 5.941 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
#!/usr/bin/perl -w
#
# A thin wrapper around Net::Amazon with output templating. Requires
# Net::Amazon and an Amazon Web Services account. Run perldoc(1) on this
# file for additional documentation.
#
# The author disclaims all copyrights and releases this document into
# the public domain.
 
use strict;
 
use Net::Amazon ();
use HTML::Entities qw(encode_entities);
 
my $search_mode;
my $output_template = $ENV{AMAZON_UTIL_TEMPLATE};
my $pages = 1;
 
use Getopt::Long;
GetOptions(
  'mode|m=s' => \$search_mode,
  'pages|p=s' => \$pages,
  'template|t=s' => \$output_template,
  'help|h|?' => \&print_help,
);
print_help() if !@ARGV;
 
if ( !grep { $_ eq 'mode' } @ARGV and defined $search_mode ) {
  push @ARGV, 'mode', $search_mode;
}
 
if ( !defined $output_template ) {
  $output_template = '%{Asin} %{ProductName}';
}
# fix backslashed characters to literal, add newline if no trailing
# whitespace found
$output_template =~ s/(\\.)/qq{"$1"}/eeg;
$output_template .= $/ unless $output_template =~ m/ \s$ /x;
 
my $AWS_ACCESS_KEY_ID = $ENV{AWS_ACCESS_KEY_ID};
if ( !defined $AWS_ACCESS_KEY_ID ) {
  die
    "error: set AWS_ACCESS_KEY_ID env variable: https://aws-portal.amazon.com/gp/aws/developer/account/index.html?action=access-key$/";
}
 
my $ua = Net::Amazon->new(
  token => $AWS_ACCESS_KEY_ID,
  max_pages => $pages,
  strict => 1,
);
 
my $response;
eval { $response = $ua->search(@ARGV); };
if ($@) {
  die "error: invalid search: errstr=$@";
}
if ( !$response->is_success() ) {
  die 'error: request failed: errstr=', $response->message(), $/;
}
 
#binmode( STDOUT, ':utf8' );
for my $item ( $response->properties ) {
  # Most folks would use a proper Template module here...
  my $output_string = $output_template;
  $output_string =~
    s/ %{ (\w+) } / $item->can($1) ? encode_entities($item->$1) : '%{'.$1.'}' /egx;
  print $output_string;
}
 
exit 0;
 
sub print_help {
  print <<"HELP";
Usage: $0 [options] Net::Amazon search() arguments as list
 
Options:
--help, -h, -? Display this message.
 
--mode=search-mode Optional. "books" or "music" or so forth.
--pages=3 Defaults to 1 page. Add more for more results.
--template='...' Customize the output template.
 
Run perldoc(1) on this script for additional documentation.
 
HELP
  exit 100;
}
 
=head1 NAME
 
amazon-util - thin wrapper around Net::Amazon
 
=head1 SYNOPSIS
 
$ export AWS_ACCESS_KEY_ID=...
$ amazon-util --mode=books power 'title: Amazon Hacks'
 
The AWS_ACCESS_KEY_ID can be obtained from:
 
https://aws-portal.amazon.com/gp/aws/developer/account/index.html?action=access-key
 
=head1 DESCRIPTION
 
=head2 Overview
 
A thin wrapper around the C<search()> method of L<Net::Amazon>, with
output templating for easy conversion into HTML or other formats.
 
=head2 Normal Usage
 
$ export AWS_ACCESS_KEY_ID=...
$ amazon-util [--mode=books] \
[--pages=3] \
[--template=...] \
Net::Amazon search() method arguments as list
 
See L<"OPTIONS"> for details on the command line switches supported. See
L<Net::Amazon> for more information on the arguments supported by the
C<search> method.
 
=head1 OPTIONS
 
This script currently supports the following command line switches:
 
=over 4
 
=item B<--help>, B<-h>, B<-?>
 
Prints a brief usage note about the script.
 
=item B<--mode>=I<search-mode>
 
Specify a custom search mode, for example "books" or "music". This
option can also be typed out on the command line:
 
$ amazon-util power 'title: Amazon Hacks' mode books
 
Either method ensures the search() method call passes in the required
C<mode => search-mode> argument. C<mode books> takes precedent over the
B<--mode> option, so a shell alias could set a default C<--mode=books>,
and C<mode music> written on the command line to override the default.
 
=item B<--pages>=I<number-of-pages>
 
The default search returns one page of results (10 items). Increasing
the pages returns more results. More pages will require more time to
query for.
 
=item B<--template>=I<output-template>
 
Custom output template. Defaults to C<%{Asin} %{ProductName}> if not
specified. Also can be set via the C<AMAZON_UTIL_TEMPLATE> environment
variable. This is what I use to ensure links contain my Associate ID:
 
$ export AMAZON_UTIL_TEMPLATE='<a href="http://www.amazon.com/o/ASIN/%{Asin}/sialorg-20/ref=nosim">%{ProductName}</a>'
$ amazon-util --mode=books power 'title: Amazon Hacks ' <a href="http://www.amazon.com/o/ASIN/0596005423/sialorg-20/ref=nosim">Amazon Hacks: 100 Industrial-Strength Tips &amp; Tools (Hacks)</a>
 
Basically, any C<%{name}> parameter in the template is, if possible,
replaced with the HTML-escaped output from a method call of C<name>
to the L<Net::Amazon::Property> or subclass module as appropriate
for the item.
 
=back
 
=head1 EXAMPLES
 
On Mac OS X, the C<pbcopy(1)> utility facilitates moving from the
command line to a HTML editor:
 
$ amazon-util --mode=books power 'title: Amazon Hacks' | pbcopy
 
Otherwise, consult the L<Net::Amazon> documentation. Any argument used
to the C<search> method can be specified as a list on the command line:
 
$ua->search(browsenode=>"4025", mode=>"books", keywords=>"perl")
 
Would become:
 
$ amazon-util browsenode 4025 mode books keywords perl
 
Note that this conversion does not support data structure arguments to
C<search>, such as:
 
$ua->search(asin => ["0201360683", "0596005083"])
 
Only scalar arguments:
 
$ua->search(asin => 0201360683)
 
$ amazon-util asin 0201360683
 
=head1 BUGS
 
=head2 Reporting Bugs
 
If the bug is in the latest version, send a report to the author.
Patches that fix problems or add new features are welcome.
 
=head2 Known Issues
 
None at this time. Note, however, the lack of unit tests.
 
=head1 SEE ALSO
 
perl(1), L<Net::Amazon>
 
=head1 AUTHOR
 
Jeremy Mates, http://sial.org/contact/
 
=head1 COPYRIGHT
 
The author disclaims all copyrights and releases this document into the
public domain.
 
=cut