Section 10.4. Amazon.com Wishlist to RSS


10.4. 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.

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.

10.4.1. 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 numberAmazon'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;

10.4.2. 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;



    Developing Feeds with RSS and Atom
    Developing Feeds with Rss and Atom
    ISBN: 0596008813
    EAN: 2147483647
    Year: 2003
    Pages: 118

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net