Amazon.com Wishlist to RSS

Being perfection herself, my wife loves books, and as a loving and dutiful husband, her Amazon wishlist is required reading for Christmas, birthdays, and all other occasions. But keeping track of the wishlist is a pain if I have to trudge over to Amazon every time. Far better to have my feed reader do it for me, with the help of a little script. Figure 10-1 shows my wishlist to give you an idea of what one looks like.

My Amazon.com wishlist page
Figure 10-1. My Amazon.com wishlist page

This feed uses the Amazon Web Services API to do its evil work. This can be either REST- or SOAP-based, so you can choose your own preferred poison. For fun, I’ll do this using the REST interface, and then using XML::Simple to parse the XML. My idea of fun might not be the same as yours, of course.

Walking Through the Code

As always, we fire up the script with the loading of the modules and the setting of some global variables: the obligatory use strict; and use warnings;, and the required Amazon API subscription key. You’ll need to get your own from http://www.amazon.com/gp/aws/landing.html.

use strict;
use warnings;
use XML::RSS;
use XML::Simple;
use LWP::Simple qw(!head);
use CGI qw(:standard);
use Getopt::Long;
use Date::Manip;

my $amazon_subscription_id = "xxxxxxxxxxxxxxxxxx";
my $rss = new XML::RSS( version => '2.0' );

As this script is running as a CGI application, it requires the Amazon Wishlist ID as a parameter. This allows you to use the same script many times over for each of the lists you want to monitor. Let’s make the parameter compulsory, naturally.

my $cgi = CGI::new( );
my $list_id = $cgi->param('list'),

Now, run the query via the Amazon Web Services REST interface. This takes a specifically formed URI and returns an XML document. We’ll retrieve this using the LWP::Simple module:

my $query_url =
"http://webservices.amazon.com/onca/
xml?Service=AWSProductData&SubscriptionId=$amazon_subscription_
id&Operation=ListLookup&ProductPage=15&ListType=WishList&ListId=$list_
id&ResponseGroup=Request,ListItems";

my $wishlist_in_xml = get("$query_url");

and place it into the Parser:

my $parser = XMLin("$wishlist_in_xml") or die ("Could not parse file");

This produces an array of the items within the wishlist, albeit still stored within the XML format returned by the REST query. That format looks like this:

<ListItem>
        <ListItemId>I2MNVARC9PUUA7</ListItemId>
        <DateAdded>2004-11-03</DateAdded>
        <QuantityDesired>1</QuantityDesired>
        <QuantityReceived>0</QuantityReceived>
        <Item>
                <ASIN>0875963528</ASIN>
                <ItemAttributes>
                        <Title>Hal Higdon's How to Train</Title>
                </ItemAttributes>
        </Item>
</ListItem>

So now you need to take the relevant bits of that information and throw it into the feed. For the taking is the title, the date, and the ASIN number—Amazon’s internal system for identifying its stock. Use this to provide a link. For a change of pace, let’s use a different XML parsing method, too. XML::Simple is tremendously useful for this sort of thing.

Now, we’ll add in some code to create the correct date, based on the date the item was added to the wishlist. Amazon returns the date in the format YYYY-MM-DD, but RSS 2.0 insists on the format Sun, 19 May 2002 15:21:36 GMT. For the sake of sanity, assume all the dates Amazon gives are at exactly midnight.

We need to do some date manipulation, and what better than Date::Manip to do this? Under its UnixDate function, the code %g is exactly the right format for RSS 2.0. Nifty, no?

foreach my $item (@{$parser->{'Lists'}->{'List'}->{'ListItem'}}) {
    
     #my $date = &UnixDate("midnight $item->{'Item'}->{'DateAdded'}","%c, %e %b %Y");
                  
   $rss->add_item(
   title => "$item->{'Item'}->{'ItemAttributes'}->{'Title'}",
   link  => "http://www.amazon.com/exec/obidos/tg/detail/-/$item->{'Item'}->{'ASIN'}",
    description => "$item->{'Item'}->{'ItemAttributes'}->{'Title'}",
    pubDate => &UnixDate("midnight $item->{'DateAdded'}","%g")

        );

}

Then, as ever, it’s just a matter of adding in the channel information and serving the thing out with the correct MIME type:

$rss->channel(
    title       => "Amazon Wishlist, $list_id",
    link        => "http://www.amazon.com",
    description => "An RSS feed of the Amazon Wishlist, id number $list_id"
);

print header('application/xml+rss'),
print $rss->as_string;

The Entire Listing

#!/usr/bin/perl

use strict;
use warnings;
use XML::RSS;
use XML::Simple;
use LWP::Simple qw(!head);
use CGI qw(:standard);
use Getopt::Long;
use Date::Manip;

my $amazon_subscription_id = "08R1SHPFGCA8VYT9P802";
my $rss = new XML::RSS( version => '2.0' );

my $cgi = CGI::new( );
my $list_id = $cgi->param('list'),

my $query_url =
"http://webservices.amazon.com/onca/
xml?Service=AWSProductData&SubscriptionId=$amazon_subscription_
id&Operation=ListLookup&ProductPage=15&ListType=WishList&ListId=$list_
id&ResponseGroup=Request,ListItems";

my $wishlist_in_xml = get("$query_url");

my $parser = XMLin("$wishlist_in_xml") or die ("Could not parse file");

foreach my $item (@{$parser->{'Lists'}->{'List'}->{'ListItem'}}) {
         
    $rss->add_item(
    title => "$item->{'Item'}->{'ItemAttributes'}->{'Title'}",
    link  => "http://www.amazon.com/exec/obidos/tg/detail/-/$item->{'Item'}->{'ASIN'}",
    description => "$item->{'Item'}->{'ItemAttributes'}->{'Title'}",
    pubDate => &UnixDate("midnight $item->{'DateAdded'}","%g")

        );

}

$rss->channel(
    title       => "Amazon Wishlist, $list_id",
    link        => "http://www.amazon.com",
    description => "An RSS feed of the Amazon Wishlist, id number $list_id"
);

print header('application/xml+rss'),
print $rss->as_string;
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.114.132