#!/usr/bin/perl -w ########################################### # amtrack - Watch Amazon Prices # Mike Schilli, 2008 (m@perlmeister.com) ########################################### use strict; use Getopt::Std; use Net::Amazon; use Net::Amazon::Request::ASIN; use Log::Log4perl qw(:easy); use Cache::Historical 0.02; use DateTime; use Mail::DWIM qw(mail); use FindBin qw($Bin); my ($home) = glob "~"; my $amzn_rc = "$home/.amtrack-rc"; Log::Log4perl->init("$Bin/amtrack.l4p"); my $cache = Cache::Historical->new( sqlite_file => "$home/.amtrack-sqlite" ); my $UA = Net::Amazon->new( token => 'YOUR_AMZN_TOKEN', # locale => 'de', ); my($config, $txt_by_asin) = config_read(); getopts("al", \my %opts); if($opts{l} or $opts{a}) { for my $key (sort keys %$txt_by_asin) { my $txt = $txt_by_asin->{$key}; for my $val ($cache->values( $key )) { my($dt, $price) = @$val; print "$dt $txt $price\n"; last if $opts{l}; } } } else { update($config); } ########################################### sub fix_price { ########################################### my($price) = @_; if(defined $price) { $price =~ s/[^\d]//g; $price =~ s/..$/.$&/g; } return $price; } ########################################### sub update { ########################################### my($config) = @_; for my $line (@$config) { my($asin, $txt) = @$line; my $now = DateTime->now(); my $last_price = fix_price($cache-> get_interpolated($now, $asin)); track($asin, $txt, $cache); my $price_now = fix_price($cache-> get_interpolated($now, $asin)); if(defined $last_price and defined $price_now) { if( $price_now < $last_price) { mail( to => 'foo@bar.com', subject => "[amtrack] " . "$txt cheaper ($price_now < " . "$last_price)", text => "URL: " . "http://amazon.com/dp/$asin", ); } } } } ########################################### sub config_read { ########################################### my @config = (); my %config = (); open AMZNRC, "$amzn_rc" or die "Cannot open $amzn_rc"; while() { s/#.*//; next if /^\s*$/; chomp; my($asin, $txt) = split ' ', $_, 2; push @config, [$asin, $txt]; $config{ $asin } = $txt; } close AMZNRC; return \@config, \%config; } ########################################### sub track { ########################################### my($asin, $txt, $cache) = @_; INFO "Tracking asin $asin"; my $req = Net::Amazon::Request::ASIN->new( asin => $asin); my $resp = $UA->request($req); if($resp->is_success()) { my($prop) = $resp->properties(); my $price = $prop->OurPrice(); INFO "Tracking $asin ", "($txt): $price"; $cache->set(DateTime->now(), $asin, $price) if $price; } else { ERROR "Can't fetch asin $asin: ", $resp->message(); } }