#!/usr/bin/perl -w # # $Id: amazon-util,v 1.2 2008/01/09 07:31:11 jmates Exp $ # # The author disclaims all copyrights and releases this document into # the public domain. # # 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. use strict; use Net::Amazon (); use HTML::Entities qw(encode_entities); my $VERSION; ( $VERSION = '$Revision: 1.2 $ ' ) =~ s/[^0-9.]//g; 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 for version $VERSION: --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 method of L, 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 for more information on the arguments supported by the C 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 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 search-mode> argument. C takes precedent over the B<--mode> option, so a shell alias could set a default C<--mode=books>, and C written on the command line to override the default. =item B<--pages>=I 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 Custom output template. Defaults to C<%{Asin} %{ProductName}> if not specified. Also can be set via the C environment variable. This is what I use to ensure links contain my Associate ID: $ export AMAZON_UTIL_TEMPLATE='%{ProductName}' $ amazon-util --mode=books power 'title: Amazon Hacks ' Amazon Hacks: 100 Industrial-Strength Tips & Tools (Hacks) Basically, any C<%{name}> parameter in the template is, if possible, replaced with the HTML-escaped output from a method call of C to the L or subclass module as appropriate for the item. =back =head1 EXAMPLES On Mac OS X, the C utility facilitates moving from the command line to a HTML editor: $ amazon-util --mode=books power 'title: Amazon Hacks' | pbcopy Otherwise, consult the L documentation. Any argument used to the C 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, 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 =head1 AUTHOR Jeremy Mates, http://sial.org/contact/ =head1 COPYRIGHT The author disclaims all copyrights and releases this document into the public domain. =head1 VERSION $Id: amazon-util,v 1.2 2008/01/09 07:31:11 jmates Exp $ =cut