#!/usr/bin/perl ########################################### # ebaywatch # Mike Schilli, 2003 (m@perlmeister.com) ########################################### use warnings; use strict; our $JABBER_ID      = "mikes-ebay-watcher"; our $JABBER_PASSWD  = "*******"; our $JABBER_SERVER  = "jabber.org"; our $JABBER_PORT    = 5222; our $SEEN_DB_FILE   = "/tmp/ebaywatch"; our $MINS_TO_END    = 10; our $RC_FILE   = "$ENV{HOME}/.ebaywatchrc"; our $EBAY_HOST = "http://search.ebay.de"; our %SEEN; use Net::Jabber qw(Client); use DB_File; use Log::Log4perl qw(:easy); use WWW::Search::Ebay; Log::Log4perl->easy_init(   { level => $DEBUG,     file => ">>/tmp/ebaywatch.log" }); tie %SEEN, 'DB_File', $SEEN_DB_FILE,     O_CREAT|O_RDWR, 0755 or     LOGDIE "tie: $SEEN_DB_FILE ($!)"; END { untie %SEEN } my $search = WWW::Search->new(                         'Ebay::ByEndDate'); open FILE, "<$RC_FILE" or     LOGDIE "Cannot open $RC_FILE"; while() {     # Discard comment and empty lines   s/^\s*#.*//;   next if /^\s*$/;   chomp;   my $term = $_;   my $hits = 0;   if(exists $SEEN{"notuntil/$term"} and      time() < $SEEN{"notuntil/$term"}) {     DEBUG "Not checking '$term' until ",           scalar localtime           $SEEN{"notuntil/$term"};     next;   }   DEBUG "Searching for '$term'";   my $q = WWW::Search::escape_query($term);   $search->native_query($q,       { search_host => $EBAY_HOST } );   while (my $r = $search->next_result()) {     $hits++;     DEBUG "Result: ", $r->url(),           " ", $r->title(),           " ", $r->description(),           " ", $r->change_date();     if($SEEN{"url/" . $r->url()}) {       DEBUG "Already notified";       next;     }     my $mins = minutes($r->change_date());     $mins = minutes(date_to_rel($r->change_date())) unless $mins;     if($mins > $MINS_TO_END) {       $SEEN{"notuntil/$term"} =         time + ($mins - $MINS_TO_END) * 60;       last;     }     INFO "Notify for ", $r->description;     $SEEN{"url/" . $r->url()}++;     my $msg = "url() .       ">" . $r->title() .  " " .       "(${mins}m) " .  $r->description;     $msg =~ s/[^[:print:]]//g;     jabber_send($msg);   }       # Pause for 1 day on no results   $SEEN{"notuntil/$term"} =      time + 24*3600 unless $hits; } ########################################### sub minutes { ###########################################     my($s) = @_;     DEBUG "minutes($s)";     my $min = 0;     return $min unless defined $s;     $min += 60*24*$1 if $s =~ /(\d+)\s*[dT]/;     $min += 60*$1 if $s =~ /(\d+)\s*[hS]/;     $min += $1 if $s =~ /(\d+)\s*[mM]/;     DEBUG "minutes($s) = $min";     return $min; } ########################################### sub jabber_send { ###########################################     my($message) = @_;     my $c = Net::Jabber::Client->new();     $c->SetCallBacks(presence => sub {});     my $status = $c->Connect(         hostname => $JABBER_SERVER,         port     => $JABBER_PORT,     );     LOGDIE "Can't connect: $!"         unless defined $status;     my @result = $c->AuthSend(         username => $JABBER_ID,         password => $JABBER_PASSWD,         resource => 'ebaywatcher',     );     LOGDIE "Can't log in: $!"         unless $result[0] eq "ok";     $c->PresenceSend();     my $m = Net::Jabber::Message->new();     my $jid = "$JABBER_ID" . '@' .               "$JABBER_SERVER/GAIM";     $m->SetBody($message);     $m->SetTo($jid);     DEBUG "Jabber to $jid: $message";     my $rc = $c->Send($m, 1);     $c->Disconnect; } ####################################### sub date_to_rel { #######################################     my($string) = @_;     DEBUG "date_to_rel: $string";     use Date::Manip;     my($date) = ParseDate($string);     my $today = ParseDate("today");     my $delta = DateCalc($today, $date);     return undef unless defined $delta;     DEBUG "delta: $delta";     my($d1, $d2, $d3, $d, $h, $m, $s) = split /:/, $delta;     my $result = "${d}d ${h}h ${m}m ${s}s";     DEBUG "Date parsed to $result";     return $result; }