Simple Woot-watching Perl Script
Mar. 27th, 2009 01:42 pm![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
This is a Perl script that outputs periodically the name, price, percent sold, and number of comments of the current item up for sale at woot.com. It has a few options for customization. Run woot.pl -? to see those. This script needs the LWP and XML::Parser::Lite::Tree modules.
#!perl -w # Shows periodic updates of Woot sale status. # Last updated: March 27, 2009 # Author: Po Shan Cheah (morton@mortonfox.com) use strict; use LWP::UserAgent; use XML::Parser::Lite::Tree; use POSIX; use Data::Dumper; use Getopt::Long; use MIME::Base64; my $wooturl = "http://www.woot.com/salerss.aspx"; # Output the status of the item in one line. sub show_item { my $item = shift; my $title = ""; my $price = ""; my $soldoutpct = 0; my $comments = 0; my $soldout = 0; for my $node1 (@$item) { if (defined $node1->{name}) { if ($node1->{name} eq "title") { $title = $node1->{children}[0]{content}; } elsif ($node1->{name} eq "woot:price") { $price = $node1->{children}[0]{content}; } elsif ($node1->{name} eq "woot:soldoutpercentage") { $soldoutpct = $node1->{children}[0]{content}; } elsif ($node1->{name} eq "woot:soldout") { my $soldouttxt = $node1->{children}[0]{content}; $soldout = ($soldouttxt =~ /true/i); } elsif ($node1->{name} eq "woot:comments") { $comments = $node1->{children}[0]{content}; } } } print strftime("%H:%M:%S", localtime), " $title $price - ", ($soldout ? "Sold Out" : $soldoutpct * 100 . "% sold"), " - $comments comments\n"; } # Encode in base64 if user:password is not already encoded. sub make_base64 { my $s = shift; $s =~ /:/ ? encode_base64($s) : $s; } # Get current item from Woot API. sub get_woot { my $sleep = shift; my $proxy = shift; my $proxylogin = shift; my $ua = LWP::UserAgent->new; if ($proxy ne '') { $ua->proxy('http', "http://" . $proxy); } if ($proxylogin ne '') { $ua->default_header('Proxy-Authorization' => 'Basic '. make_base64($proxylogin)); } my $response = $ua->get($wooturl); if ($response->is_success) { my $tree = XML::Parser::Lite::Tree::instance()->parse($response->content); # print Dumper($tree); for my $node1 (@{$tree->{children}}) { if (defined $node1->{name} and $node1->{name} eq "rss") { for my $node2 (@{$node1->{children}}) { if (defined $node2->{name} and $node2->{name} eq "channel") { for my $node3 (@{$node2->{children}}) { if (defined $node3->{name} and $node3->{name} eq "item") { show_item($node3->{children}); } } } } } } } else { warn $response->status_line, "\n"; } } my $proxy = ''; my $proxylogin = ''; my $sleep = 15; my $result = GetOptions("sleep=i" => \$sleep, "proxy=s" => \$proxy, "proxylogin=s" => \$proxylogin); unless ($result) { warn <<EOM; Usage: $0 --sleep=N --proxy=str --proxylogin=str --sleep: Time between updates in seconds. --proxy: Proxy server (Format: server:port) --proxylogin: Proxy auth info (Format: user:password, can be base64 encoded) EOM exit 1; } while (1) { eval { get_woot($sleep, $proxy, $proxylogin); }; $@ and warn $@; sleep($sleep); } __END__