#!/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 $EBAY_HOST = "http://search.ebay.de";
our $MINS_TO_END    = 10;
our $RC_FILE   = "$ENV{HOME}/.ebaywatchrc";
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(<FILE>) {
    # 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, 
      { ebay_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());
    
    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 = "<A HREF=" . $r->url() . 
      ">" . $r->title() .  "</A> " .
      "(${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) = @_;

    my $min = 0;

    $min += 60*24*$1 if $s =~ /(\d+)[dT]/;
    $min += 60*$1 if $s =~ /(\d+)[hS]/;
    $min += $1 if $s =~ /(\d+)[mM]/;

    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;
}
