#!/usr/bin/env python # # NFL update bot. 0.1 # # Copyright (c) 2009, Jonas Haggqvist # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # * Neither the name of the program nor the names of its contributors may be # used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. from twisted.words.protocols import irc from twisted.internet import reactor, protocol, task import urllib2 from xml.etree import ElementTree class Team(): city = "" team = "" bg = "" fg = "" stadium = "" short = "" irccolors = { 'white':0, 'black':1, 'blue':2, 'green':3, 'lightred':4, 'red':5, 'purple':6, 'orange':7, 'yellow':8, 'lightgreen':9, 'teal':10, 'aqua':11, 'lightblue':12, 'magenta':13, 'darkgrey':14, 'lightgrey':15, } def __init__(self, city, team, fg, bg, stadium, short): self.city = city self.team = team self.fg = fg self.bg = bg self.stadium = stadium self.short = short def shortirc(self): return "%c%d,%d%s%c" % ( 3, self.irccolors[self.fg], self.irccolors[self.bg], self.short, 3 ) class NFLBot(irc.IRCClient): nickname = "nflbot" games = {} bps = [] teams = { "ARI": Team("Arizona", "Cardinals", "white", "red", "", "ARI"), "ATL": Team("Atlanta", "Falcons", "black", "red", "", "ATL"), "BAL": Team("Baltimore", "Ravens", "yellow", "lightblue", "", "BAL"), "BUF": Team("Buffalo", "Bills", "red", "blue", "", "BUF"), "CAR": Team("Carolina", "Panthers", "lightblue", "black", "", "CAR"), "CHI": Team("Chicago", "Bears", "orange", "lightblue", "", "CHI"), "CIN": Team("Cincinatti", "Bengals", "black", "orange", "", "CIN"), "CLE": Team("Cleveland", "Browns", "white", "orange", "", "CLE"), "DAL": Team("Dallas", "Cowboys", "blue", "lightgrey", "", "DAL"), "DEN": Team("Denver", "Broncos", "orange", "lightblue", "", "DEN"), "DET": Team("Detroit", "Lions", "white", "lightblue", "", "DET"), "GB": Team("Green Bay", "Packers", "yellow", "green", "", "GB"), "HOU": Team("Houston", "Texans", "red", "blue", "", "HOU"), "IND": Team("Indianapolis", "Colts", "white", "lightblue", "", "IND"), "JAC": Team("Jacksonville", "Jaguars", "white", "blue", "", "JAC"), "KC": Team("Kansas City", "Chiefs", "white", "red", "", "KC"), "MIA": Team("Miami", "Dolphins", "orange", "teal", "", "MIA"), "MIN": Team("Minnesota", "Vikings", "white", "purple", "", "MIN"), "NE": Team("New England", "Patriots", "blue", "red", "", "NE"), "NO": Team("New Orleans", "Saints", "black", "orange", "", "NO"), "NYG": Team("New York", "Giants", "blue", "red", "", "NYG"), "NYJ": Team("New York", "Jets", "white", "green", "", "NYJ"), "OAK": Team("Oakland", "Raiders", "black", "white", "", "OAK"), "PHI": Team("Philadelphia", "Eagles", "black", "teal", "", "PHI"), "PIT": Team("Pittsburgh", "Steelers", "black", "yellow", "", "PIT"), "SD": Team("San Diego", "Chargers", "yellow", "blue", "", "SD"), "SEA": Team("Seattle", "Seahawks", "lightgrey", "blue", "Qwest Field", "SEA"), "SF": Team("San Francisco", "49ers", "red", "orange", "Candlestick Park", "SF"), "STL": Team("St. Louis", "Rams", "blue", "orange", "Edward Jones Dome", "STL"), "TB": Team("Tampa Bay", "Buccaneers", "red", "darkgrey", "Raymond James Stadium", "TB"), "TEN": Team("Tennessee", "Titans", "aqua", "blue", "LP Field", "TEN"), "WAS": Team("Washington", "Redskins", "white", "red", "FedExField", "WAS"), } def gamestring(self, game): qs = { 'F':'Final', 'FO':'Final (OT)', 'H':'Halftime', 'P':'Pending', '1':'1st', '2':'2nd', '3':'3rd', '4':'4th', '5':'Overtime', } v = { 'home':self.teams[game['h']].shortirc(), 'away':self.teams[game['v']].shortirc(), 'c':chr(0x3), 'vs':int(game['vs']), 'hs':int(game['hs']), 'u':'', 'o':chr(0xf), 'time':" %s" % qs[game['q']], } if game['q'] == 'F' or game['q'] == 'FO': v['u']=chr(0x1f) v['time']='' elif game['q'] in ('1', '2', '3', '4', '5'): v['time'] += " %s" % game['k'] if game['q'] == 'P': fmt = "%(away)s @ %(home)s%(time)s" else: fmt = "%(away)s %(u)s%(vs)d @ %(hs)d%(o)s %(home)s%(time)s" ret = fmt % (v) return ret def saygame(self, game, oldgame): if game == None or oldgame == None: return False gamestring = self.gamestring(game) scores = { 1:'Extra point', 2:'Safety/2pt.', 3:'Field goal', 6:'Touchdown!', } for score, team in ('hs', 'h'), ('vs', 'v'): diff = int(game[score]) - int(oldgame[score]) if diff != 0: if abs(diff) in scores: scorestr = scores[abs(diff)] else: scorestr = "%d points" % abs(diff) msg = "%s %s " % (gamestring, self.teams[game[team]].shortirc()) if diff > 0: msg += "scores %s" % scorestr else: msg += "%s is reversed" % scorestr self.msg(self.factory.channel, msg) if game['rz'] != oldgame['rz'] and game['rz'] != 0 and 'p' in game: print(repr(game)) self.msg(self.factory.channel, gamestring + " %s is in the %c%dred zone%c" % (self.teams[game['p']].shortirc(), 3, 5, 3)) if game['q'] != oldgame['q']: self.msg(self.factory.channel, gamestring) def saybp(self, bp): self.msg(self.factory.channel, "%c%d,%dBIG PLAY ALERT%c: %s @ %s: %s (%s)" % ( 3,8,5,3, self.games[bp['eid']]['v'], self.games[bp['eid']]['h'], bp['x'], self.teams[bp['abbr']].shortirc(), )) def getcurrent(self): print("Get current") url = "http://gaia.local/nfl/" url = "http://www.nfl.com/liveupdate/scorestrip/ss.xml" data = urllib2.urlopen(url) if data == None: data = open('ss.xml','r') tree = ElementTree.parse(data) for game in [g.attrib for g in tree.find('gms').findall('g')]: if game != self.games.get(game['eid']): self.saygame(game, self.games.get(game['eid'])) if game['eid'] not in self.games: self.games[game['eid']] = {} self.games[game['eid']] = game if tree.find('bps'): for bp in [b.attrib for b in tree.find('bps').findall('b')]: if bp['id'] not in self.bps: self.bps.append(bp['id']) self.saybp(bp) def signedOn(self): print("Signed on") """Called when bot has succesfully signed on to server.""" self.join(self.factory.channel) task.LoopingCall(self.getcurrent).start(15, now=True) def lineReceived(self, data): irc.IRCClient.lineReceived(self, data) print(data) class NFLBotFactory(protocol.ClientFactory): protocol = NFLBot def __init__(self, channel): self.channel = channel def clientConnectionLost(self, connector, reason): print("Connection lost, reconnecting") connector.connect() def clientConnectionFailed(self, connector, reason): print("Connection failed, giving up") reactor.stop() if __name__ == "__main__": f = NFLBotFactory('#nflbot') reactor.connectTCP("irc.quakenet.org", 6667, f) reactor.run()