You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
224 lines
8.3 KiB
224 lines
8.3 KiB
""" |
|
.. module:: NFLLive |
|
:synopsis: Show upcoming NFL games and current scores. |
|
|
|
.. moduleauthor:: Dave Pedu <dave@davepedu.com> |
|
|
|
""" |
|
|
|
from pyircbot.modulebase import ModuleBase, command |
|
from pyircbot.modules.ModInfo import info |
|
from time import time |
|
from requests import get |
|
from lxml import etree |
|
from datetime import datetime, timedelta |
|
|
|
|
|
class NFLLive(ModuleBase): |
|
def __init__(self, bot, moduleName): |
|
ModuleBase.__init__(self, bot, moduleName) |
|
self.cache = None |
|
self.cacheAge = 0 |
|
|
|
@info("nfl show nfl schedule & score", cmds=["nfl"]) |
|
@command("nfl") |
|
def nflitup(self, message, cmd): |
|
games = self.getNflGamesCached() |
|
msg = [] |
|
|
|
liveGames = [] |
|
gamesLaterToday = [] |
|
gamesToday = [] |
|
gamesUpcoming = [] |
|
gamesEarlierWeek = [] |
|
|
|
# sort games |
|
for game in games["games"]: |
|
if game["time"] is not None: |
|
liveGames.append(game) |
|
elif game["quarter"] == "P" and game["startdate"].day == datetime.now().day: |
|
gamesLaterToday.append(game) |
|
elif game["startdate"].day == datetime.now().day: |
|
gamesToday.append(game) |
|
elif game["startdate"].day > datetime.now().day: |
|
gamesUpcoming.append(game) |
|
else: |
|
gamesEarlierWeek.append(game) |
|
|
|
# create list of formatted games |
|
liveGamesStr = [] |
|
for game in liveGames: |
|
liveGamesStr.append(self.formatGameLive(game)) |
|
liveGamesStr = ", ".join(liveGamesStr) |
|
|
|
gamesLaterTodayStr = [] |
|
for game in gamesLaterToday: |
|
gamesLaterTodayStr.append(self.formatGameFuture(game)) |
|
gamesLaterTodayStr = ", ".join(gamesLaterTodayStr) |
|
|
|
gamesTodayStr = [] |
|
for game in gamesToday: |
|
gamesTodayStr.append(self.formatGamePast(game)) |
|
gamesTodayStr = ", ".join(gamesTodayStr) |
|
|
|
gamesUpcomingStr = [] |
|
for game in gamesUpcoming: |
|
gamesUpcomingStr.append(self.formatGameFuture(game)) |
|
gamesUpcomingStr = ", ".join(gamesUpcomingStr) |
|
|
|
gamesEarlierWeekStr = [] |
|
for game in gamesEarlierWeek: |
|
gamesEarlierWeekStr.append(self.formatGamePast(game)) |
|
gamesEarlierWeekStr = ", ".join(gamesEarlierWeekStr) |
|
|
|
msgPieces = [] |
|
|
|
msgPieces.append("\x02NFL week %s\x02:" % (games["season"]["week"])) |
|
|
|
# Depending on args build the respon pieces |
|
if len(cmd.args) > 0 and cmd.args[0] == "today": |
|
if not liveGamesStr == "": |
|
msgPieces.append("\x02Playing now:\x02 %s" % liveGamesStr) |
|
if not gamesLaterTodayStr == "": |
|
msgPieces.append("\x02Later today:\x02 %s" % gamesLaterTodayStr) |
|
if not gamesTodayStr == "": |
|
msgPieces.append("\x02Earlier today:\x02 %s" % gamesTodayStr) |
|
elif len(cmd.args) > 0 and cmd.args[0] == "live": |
|
if not liveGamesStr == "": |
|
msgPieces.append("\x02Playing now:\x02 %s" % liveGamesStr) |
|
elif len(cmd.args) > 0 and cmd.args[0] == "scores": |
|
if not liveGamesStr == "": |
|
msgPieces.append("\x02Playing now:\x02 %s" % liveGamesStr) |
|
if not gamesTodayStr == "": |
|
msgPieces.append("\x02Earlier today:\x02 %s" % gamesTodayStr) |
|
if not gamesEarlierWeekStr == "": |
|
msgPieces.append("\x02Earlier this week: \x02 %s" % gamesEarlierWeekStr) |
|
else: |
|
if not liveGamesStr == "": |
|
msgPieces.append("\x02Playing now:\x02 %s" % liveGamesStr) |
|
if not gamesLaterTodayStr == "": |
|
msgPieces.append("\x02Later today:\x02 %s" % gamesLaterTodayStr) |
|
if not gamesTodayStr == "": |
|
msgPieces.append("\x02Earlier today:\x02 %s" % gamesTodayStr) |
|
if not gamesEarlierWeekStr == "": |
|
msgPieces.append("\x02Earlier this week: \x02 %s" % gamesEarlierWeekStr) |
|
if not gamesUpcomingStr == "": |
|
msgPieces.append("\x02Upcoming:\x02 %s" % gamesUpcomingStr) |
|
|
|
# Collaspe the list into a repsonse string. Fix grammar |
|
msg = ", ".join(msgPieces).replace(":, ", ": ") |
|
|
|
# Nothing means there were probably no games |
|
if len(msgPieces) == 1: |
|
msg = "No games!" |
|
|
|
if len(msg) > 0: |
|
# The message can be long so chunk it into pieces splitting at commas |
|
while len(msg) > 0: |
|
piece = msg[0:330] |
|
msg = msg[330:] |
|
while not piece[-1:] == "," and len(msg) > 0: |
|
piece += msg[0:1] |
|
msg = msg[1:] |
|
self.bot.act_PRIVMSG(message.args[0], "%s: %s" % (message.prefix.nick, piece.strip())) |
|
|
|
def formatGameLive(self, game): |
|
c_vis = 3 if int(game["visitor_score"]) > int(game["home_score"]) else 4 |
|
c_home = 4 if int(game["visitor_score"]) > int(game["home_score"]) else 3 |
|
|
|
return "\x03%s%s(%s)\x03 @ \x03%s%s(%s)\x03 Q%s %s" % ( |
|
c_vis, |
|
game["visitor"], |
|
game["visitor_score"], |
|
c_home, |
|
game["home"], |
|
game["home_score"], |
|
game["quarter"], |
|
game["time"] |
|
) |
|
|
|
def formatGameFuture(self, game): |
|
return "\x02%s\x02@\x02%s\x02" % ( |
|
game["visitor"], |
|
game["home"] |
|
) |
|
|
|
def formatGamePast(self, game): |
|
c_vis = 3 if int(game["visitor_score"]) > int(game["home_score"]) else 4 |
|
c_home = 4 if int(game["visitor_score"]) > int(game["home_score"]) else 3 |
|
|
|
return "\x03%s%s(%s)\x03@\x03%s%s(%s)\x03" % ( |
|
c_vis, |
|
game["visitor"], |
|
game["visitor_score"], |
|
c_home, |
|
game["home"], |
|
game["home_score"] |
|
) |
|
|
|
def getNflGamesCached(self): |
|
if time() - self.cacheAge > self.config["cache"]: |
|
self.cache = NFLLive.getNflGames() |
|
self.cacheAge = time() |
|
return self.cache |
|
|
|
@staticmethod |
|
def getNflGames(): |
|
result = {} |
|
|
|
# Fetch NFL information as XML |
|
nflxml = get("http://www.nfl.com/liveupdate/scorestrip/ss.xml?random=1413140448433") |
|
doc = etree.fromstring(nflxml.content) |
|
games = doc.xpath("/ss/gms")[0] |
|
|
|
result["season"] = { |
|
"week": games.attrib["w"], |
|
"year": games.attrib["y"], |
|
"type": NFLLive.translateSeasonType(games.attrib["t"]), # R for regular season, probably P for pre (?) |
|
"gameday": int(games.attrib["gd"]), # 1 or 0 for gameday or not (?) |
|
"bph": games.attrib["bph"] # not sure |
|
} |
|
result["games"] = [] |
|
|
|
for game in games.getchildren(): |
|
gameblob = { |
|
"home": game.attrib["h"], |
|
"home_name": game.attrib["hnn"], |
|
"home_score": game.attrib["hs"], |
|
|
|
"visitor": game.attrib["v"], |
|
"visitor_name": game.attrib["vnn"], |
|
"visitor_score": game.attrib["vs"], |
|
|
|
"gametype": game.attrib["gt"], # REGular season, probably P for preseason (?) |
|
"quarter": game.attrib["q"], # P if not started, 1-4, F is finished |
|
"time": game.attrib["k"] if "k" in game.attrib else None, |
|
"id": game.attrib["eid"], |
|
"gamenum": game.attrib["gsis"], |
|
|
|
"starttime": game.attrib["t"], |
|
"startdate": datetime.strptime(game.attrib["eid"][0:-2] + " " + game.attrib["t"], "%Y%m%d %I:%M") + \ |
|
timedelta(hours=12) # NHL provides a 12 hour EST clock with all times PM. |
|
# Add 12 hours so the datetime obj is PM instead of AM. |
|
} |
|
|
|
# Add 4 more hours to make it GMT |
|
gameblob["startdate_gmt"] = gameblob["startdate"] + timedelta(hours=4) |
|
gameblob["nfl_link"] = "http://www.nfl.com/gamecenter/%s/%s/%s%s/%s@%s" % ( |
|
gameblob["id"], |
|
result["season"]["year"], |
|
gameblob["gametype"], |
|
result["season"]["week"], |
|
gameblob["visitor_name"], |
|
gameblob["home_name"]) |
|
|
|
result["games"].append(gameblob) |
|
return result |
|
|
|
@staticmethod |
|
def translateSeasonType(season): |
|
if season == "R": |
|
return "Regular" |
|
if season == "P": |
|
return "Pre" |
|
return season
|
|
|