Hack #29. Keep Track of Auctions Outside of eBay

Use eBay's auction-tracking tools or create a flexible auction-watching tool better than anything eBay has to offer.

If I bought everything on eBay I wanted, I would've gone broke long ago. But I'm also a collector, and as such, I routinely track many auctions in my various fields of interest, whether or not I actually intend to bid on them.

Keeping track of auctions is among your most important tasks as a bidder—especially for items you've won—if for no other reason than to ensure that you eventually receive everything you've paid for. Tracking auctions is also an essential part of sniping [Hack #26] as well as selling [Hack #43] . If you're really after something specific, you may want to track completed auctions that didn't sell, so you can find them easily when they're relisted. And sometimes you may want to keep track of an auction's progress purely for the sake of curiosity.

The All Buying section of My eBay is where most people turn to track their auctions. The Items I'm Bidding On, Items I've Won, and Items I Didn't Win lists are all updated automatically whenever you place a bid or an auction on which you've bid closes, respectively. These lists include all the vitals, such as the auction titles, amounts of your bids, end dates, and closing prices.

By default, the Items I've Won and Items I Didn't Win lists show only auctions that have ended in the past few days, but you can increase their range to up to 60 days by typing the desired number of days in the box at the top of each list. And like search results, all the lists on this page can be sorted by clicking the hyperlinked column headers.

The Items I'm Watching list is a very handy tool, but it works somewhat differently than the others. It will remain empty until you choose to "watch" an auction: simply go to any auction (or fixed-price listing) page and click "Watch this item." A message then appears, confirming that item is now being tracked in My eBay; click the link to view the updated list. The Watching list is easy to use and adequate if you never track more than a few items at a time.

The eBay toolbar [Hack #23] sports a few additional features that work in conjunction with the Items I'm Watching list, such as watch alerts and bid alerts that remind you when auctions you're watching or have bid on are about to end.

As useful as eBay's tools are, you may find that none of them completely meet your needs. For example:

The first task is to create an easy way to add any given auction to your custom list, an alternative to the Watch This Item link on auction pages. This is accomplished by placing the following snippet of JavaScript in a button on your browser's Links bar [Hack #14] :

   javascript:void(win=window.open('http://www.ebayhacks.com/exec/track.pl?
          do=add&auction='+location.href+'&title='+document.title,'Hack'))

(Make sure the text appears all on one line.) You can name the new link anything you like, such as Watch Auction or simply Track.

The first few bits of the code are used to instruct your browser to open a new browser window and execute the code inside the parentheses, but it's the stuff that follows that's the most interesting. First comes the complete URL of your tracking tool, so you'll need to change www.ebayhacks.com to the name of your own web server, /exec to the name of your executable folder (usually /cgibin), and track.pl to the filename of your script (discussed in the following section). The second half of the URL—the text after the question mark (?)—is composed of three arguments that are passed to your script, separated by ampersands (&):

    do=add&auction='+location.href+'&title='+document.title

The JavaScript code automatically inserts the auction URL (location.href) and page title (document.title) as arguments to pass to the script. One of the neat little tricks of this code is how it works with eBay's auction URL, which also includes arguments separated by ampersands:

	http://cgi.ebay.com/ws/eBayISAPI.dll?ViewItem&item=3125058177

When this URL is passed to your script with the other arguments, it is automatically split into these two arguments:

auction=http://cgi.ebay.com/ws/eBayISAPI.dll?ViewItem

item=3125058177

and thus the auction number is conveniently separated for you!

The second half of this hack is a Perl script that interprets the information it receives from the JavaScript link (see the previous section), stores all your auctions in a file, and then displays a properly sorted list.

    #!/usr/bin/perl
    # *** includes ***
    use Time::ParseDate;
    use POSIX qw(strftime);
    use LWP 5.64;
    use HTML::HeadParser;
    require("cgi-lib.pl");
    &ReadParse;

    # *** variables *** 
	$selfurl = "http://www.ebayhacks.com/exec/track.pl"; 
    $localfile = "/usr/local/home/ebaylist.txt"; 
    $timeoffset = 0;
$url = "http://cgi.ebay.com/ws/eBayISAPI.dll?ViewItem&item=";
	@formatting=("color=#EE0000 STYLE=font-weight:bold", 
                      "color=#000000 STYLE=font-weight:bold", "color=#000000");

$i = 0;
$exists = 0; 
	$numlevels = 2;

# *** read stored list ***
open (INFILE,"$localfile");
  while ( $line = <INFILE> ) {
    $line =~ s/\s+$//;
    $i++;
    ($enddate[$i],$priority[$i],$item[$i],$title[$i]) =

                                                      split(",", $line, 4);

# *** see if passed auction number is in list already ***
if (($item[$i] ne "") && ($item[$i] eq $in{'item'})) { $exists = $i; }
} 
close (INFILE);

# *** add latest auction to list, if valid ***
if (($in{'auction'} =~ "ebay.com") && ($in{'item'} != "") && ($exists==0)) {
  $x = index($in{'title'}, "("); 
  $y = index($in{'title'}, ")", $x); 
  $z = index($in{'title'}, "-", $y);

	$title = &get_title($in{'item'});
   $enddate = parsedate(substr($in{'title'}, $x + 6, $y - $x - 7));

   $i++;
   ($enddate[$i], $priority[$i], $item[$i], $title[$i]) =

                                          ($enddate, 2, $in{'item'}, $title);
 } 
 elsif (($in{'do'} eq "promote")) {
   $priority[$exists]--;
   if ($priority[$exists] < 0) { $priority[$exists] = 0; }
 }
elsif (($in{'do'} eq "demote")) {
$priority[$exists]++;
if ($priority[$exists] > 2) { $priority[$exists] = 2; }
 }
 elsif (($in{'do'} eq "delete")) {
   splice @enddate, $exists, 1;
   splice @priority, $exists, 1;
   splice @item, $exists, 1;
   splice @title, $exists, 1;
   $i--;
 }
 # *** update list ***
 if (($in{'do'} ne "")) {
    open (OUTFILE,">$localfile");
for ($j = 1; $j <= $i; $j++) { 
           print OUTFILE "$enddate[$j],$priority[$j],$item[$j],$title[$j]\n";
         }
       close (OUTFILE);

       print "Location: $selfurl\n\n";
       exit( 0);
     }

     # *** sort list ***
	 @idx = sort criteria 0 .. $i;
     
	 # *** display list ***
	 print "Content-type: text/html\n\n";
	 print "<table border cellspacing=0 cellpadding=6>\n";

	 for ($j = 1; $j <= $i; $j++) { 
       $formatteddate =
              strftime("%a, %b %d - %l:%M:%S %p", localtime($enddate[$idx[$j]]));
	$formattedtitle = "<a href=\"$url$item[$idx[$j]]\" target=\"_blank\"><font 
                   $formatting[$priority[$idx[$j]]]>$title[$idx[$j]]</font></a>";
      if (strftime("%v", localtime($enddate[$idx[$j]])) eq 
											  strftime("%v", localtime(time))) {
	$formattedtitle = "<li>" . $formattedtitle;
 }
 if ($enddate[$idx[$j]] < time) {
	$formattedtitle = "<strike>" . $formattedtitle . "</strike>"; 
 }
 else {
   $timeleft = ($enddate[$idx[$j]] - time) / 60 + ($timeoffset * 60);
   if ($timeleft < 24 * 60) {
     $hoursleft = int($timeleft / 60);
	 $minleft = int($timeleft - ($hoursleft * 60));
	 if ($minleft < 10) { $minleft = "0" . $minleft; }
	$formattedtitle = $formattedtitle . 
                        " <font size=-1>($hoursleft:$minleft left)</font>"; 
      }
  }
  print "<tr><td>$formattedtitle</td>";
  print "<td><font size=-1>$formatteddate</font></td>";
	print "<td><a href=\"$selfurl?item=$item[$idx[$j]]&do=promote\">+</a>"; 
  print " | <a href=\"$selfurl?item=$item[$idx[$j]]&do=demote\">-</a>"; 
  print " | <a href=\"$selfurl?item=$item[$idx[$j]]&do=delete\">x</a></td>";
  print "</tr>\n";
 }
 print "</table>\n";
 sub criteria {
 # *** sorting criteria subroutine ***
 return ($priority[$a] <=> $priority[$b] or $enddate[$a] <=> $enddate[$b])
}
sub get_title($) {
  my $itempage = LWP::UserAgent -> new;
  my $item_contents = $itempage -> get($_[0]);
  my $p = HTML::HeadParser -> new;
  $p -> parse($item_contents -> content);
  $title = $p -> header('Title');
  $title = substr($title, index($title, " - ") + 3);
  return $title; 
}

Save this script as track.pl and place it in your web server's cgi-bin directory, as described in the Preface. Note that the $selfurl and $localfile variables must be modified to match the URL of your script and the location of the local file in which the auction titles are to be stored, respectively. Also, you may need to adjust the$timeoffset variable to compensate for the time zone difference between eBay time (Pacific time) and your computer's clock; e.g., enter 3 if you're in eastern time (GMT–5:00).

With the script in place and the JavaScript link at the ready on your browser toolbar, all that's left is to try it out. Open any auction page on eBay and click the Track link on your Links bar. A new window will open, and the auction you were just looking at will appear at the top of the list, as shown in Figure 3-3. Repeat this for as many auctions as you like; there's virtually no limit. You can even track completed auctions and auctions that you haven't won.

Click the title of any auction to open the eBay listing page in a new window. Click the x link to delete the entry.

Auctions can be prioritized; all new entries start out at the lowest priority and are shown in normal font. Click the + link to promote an auction and make its title bold. Click + again to promote the auction to the highest level and make its title red and bold. Likewise, click - to demote any entry. Higher-priority items appear higher in the list, and all auctions within a certain priority level are sorted by their closing date. I use the lowest priority for auctions on which I don't intend to bid, the medium priority for items I want, and the highest priority for items I've already bid on and won.

Tip

Sellers often lower [Hack #65] the Buy It Now prices [Hack #31] of running auctions that haven't received bids, sometimes repeatedly. If you really want an item, it's a good idea to check back a few times before the end of the auction to see if you can snag it before someone else does.

As with all the hacks in this book, you can download the code for this hack at ebayhacks.com.

Naturally, you'll want to customize this hack to suit your needs, which is really this tool's greatest advantage over eBay's Bidding/Watching page. Among the more interesting ways to hack this script are the following: