#!/usr/bin/python # Adapted from arduino-specific code to run on most any linux machine with gtk. # Quick and dirty AmbientOrb code to scrape and report election results # most of this code came from: # http://www.exothermia.net/monkeys_and_robots/2008/11/03/code-to-scape-cnncom-election-results/#more-34 import urllib2 import re import pygtk pygtk.require('2.0') import gtk import gobject UPDATE = 600 # 10 minutes class ElectionWon(Exception): pass class CNN(object): def __init__(self): self.url = "http://www.cnn.com/ELECTION/2008/results/president/" def get(self): """return the electoral balance (dpopular, delectoral), (rpopular, relectoral) """ u = urllib2.urlopen(self.url) d = None r = None for line in u.readlines(): res = re.search(r'var CNN_NData=(.*?);', line) if res is not None: data = res.group(1) data = data.replace("true", "True") data = data.replace("false", "False") data = eval(data) d,r = None, None for candidate in data['P']['candidates']: if candidate['party'] == 'D': d = candidate['votes'], candidate['evotes'] if candidate['winner']: raise ElectionWon("D") elif candidate['party'] == 'R': r = candidate['votes'], candidate['evotes'] if candidate['winner']: raise ElectionWon("R") if not d or not r: return ((0,0),(0,0)) return d,r def normalize(d,r, interval=0.5): """normalize to -1 => democrat winning +1 => republican winning abs(1.0) is having "2*interval" higher percent than the other guy """ if d+r == 0: return 0.0 rnorm = 2.0*(1.0*r/(d+r) - 0.5) / (2*interval) if rnorm > 1.0: rnorm = 1.0 if rnorm < -1.0: rnorm = -1.0 return rnorm def calc_color(value): """ Assumes a normaized -1:1 range and returns 0000FF through FF0000 Only manipulates the Red and Blue values -1 ==> 0000FF 0 ==> 000000 1 ==> FF0000 """ print value if value == 0: return "FF00FF" blue = max(0, (value * -128) + 127) red = max(0, (value * 128) + 127) return('%02x00%02x' % (red, blue)) def tick(image, pixbuf, label): try: (d,r) = cnn.get() n = normalize(d[0], r[0]) r_percent = ((n + 1.0) / 2.0) * 100.0 d_percent = ((1.0 - n) / 2.0) * 100.0 print r_percent label.set_text("McCain: %02.1f / Obama: %02.1f" % (r_percent, d_percent)) color = calc_color(n) pixbuf.fill(long("0x"+color+"FF", 16)) except ElectionWon, elewon: if(elewon.message == 'D'): print "OBAMANIA!" pixbuf.fill(0x0000FFFF) elif(elewon.message == 'R'): print "McAw hell naw" pixbuf.fill(0xFF0000FF) image.set_from_pixbuf(pixbuf) return True tick_val = -1 def test_tick(image, pixbuf): import random global tick_val color = calc_color(tick_val) print "set:",color pixbuf.fill(long("0x"+color+"FF", 16)) image.set_from_pixbuf(pixbuf) tick_val += 0.1 if tick_val >= 1: return False return True def done(wid): gtk.main_quit() if __name__=='__main__': cnn = CNN() window = gtk.Window() image = gtk.Image() pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, 240, 180) image.set_from_pixbuf(pixbuf) pixbuf.fill(0xFFFFFFFF) vbox = gtk.VBox() vbox.pack_start(image) label = gtk.Label("50/50") vbox.pack_start(label) tick(image, pixbuf, label) gobject.timeout_add(UPDATE * 1000, tick, image, pixbuf, label) #gobject.timeout_add(1000, test_tick, image, pixbuf) window.add(vbox) window.show_all() window.set_title("Elect-o-meter") window.connect('destroy', done) gtk.main()