Wii Watching, Part II

Geek

So I updated check_wii.rb to make it more flexible - i.e. to enable it to watch multiple vendor websites for available Wiis. Here's the updated code:

require 'open-uri'
require 'net/smtp'

logfile=File.open('check_wii.log', 'a')
startdate=Time.now
logfile.write("Started check_wii at #{startdate.to_s}\n")

vendors=Array.new

i=0
infile=File.open("vendor_list.txt")
infile.each do |line|
  vendors[i]=line
  i+=1
end

def get_page(url, string)
   result=nil
   open(url) do |wii|
     wii.each_line do |line|
     if line[string]
       result=line
       break
     end
   end
   end
   result
end

def send_msg(message)
   Net::SMTP.start('mail.host.com', 25, nil, 'user', 'pass', :login) do |smtp|
     smtp.open_message_stream('sender@domain', ['recipient@domain', 'recipient@domain']) do |f|
       f.puts
       f.puts message
     end
   end
end

def write_stop_file(stop_file)
   afile=File.new(stop_file, "w+")
   afile.write("Stop processing.")
   afile.close
end

vendors.each do |vendor|
   parts=vendor.split(',')
   vendor_name=parts[0]
   vendor_url=parts[1]
   vendor_string=parts[2].chomp

   logfile.write(" Checking #{vendor_name}...\n")

   stop_file="STOP.#{vendor_name}"
   next if FileTest.exist?(stop_file)

   instock=get_page(vendor_url, vendor_string)

   if instock.nil?
     send_msg("#{vendor_name} has the Wii in stock. Order now!")
     write_stop_file(stop_file)
   end
end

You might notice that I added some logging. It's simple, but it gives me a warm fuzzy that the program has run recently. So I spit out a start date, each vendor that I check, and an end date. These bits of info allow me to know:

  • If it's running
  • That the selective checking works - i.e. when I get a hit at a specific vendor, say Amazon, I don't check there anymore as I've either bought the thing or didn't like their offering, as in the case of WalMart.
  • How long it's taking

Here's a sample log entry:

Started check_wii at Tue Dec 12 15:30:02 CST 2006
  Checking Amazon...
   Checking Sams Club...
   Checking Sams Club...
   Checking Circuit City...
Finished check_wii at Tue Dec 12 15:30:09 CST 2006

But the real improvement comes from these sections of code:

vendors=Array.new
...
infile.each do |line|
   vendors[i]=line
   i+=1
end
...
vendors.each do |vendor|
  ...
end

The first line simply creates a new Array object.
The block immediately following populates the array from the input file, vendor_list.txt.
The last block parses each array element into its parts: vendor name, url, and the specific text I DON'T want to see on their website, namely an 'out of stock' sort of message. If that's NOT there, then there's a high probability that the item is in stock. (As a side note, you could use this script to watch for any hard-to-get item. It's just the Wii that motivated me to learn enough Ruby to get this working in the first place. So it's true in my scae, at least, that the Wii is a valuable educational tool. See parents? Video games are GOOD for us!)
The vendor_list.txt file is a comma separated values file in this order:

vendor_name,url,message

This setup makes it easy to add vendors to the watch list. Just update the vendor_list.txt file, and the script will run against the new vendor the next time it runs.