1 import os
2 import os.path as path
3 import gzip
4 import json
5 import sys
6 import urllib2
7
8 from nflgame import OrderedDict
9 import nflgame.player as player
10
11 _jsonf = path.join(path.split(__file__)[0], 'gamecenter-json', '%s.json.gz')
12 _json_base_url = "http://www.nfl.com/liveupdate/game-center/%s/%s_gtd.json"
13
14
16 """
17 Game represents a single pre- or regular-season game. It provides a window
18 into the statistics of every player that played into the game, along with
19 the winner of the game, the score and a list of all the scoring plays.
20 """
21
23
24 rawData = _get_json_data(eid)
25 if rawData is None or rawData.strip() == '{}':
26 return None
27 game = object.__new__(cls)
28 game.rawData = rawData
29 return game
30
32 """
33 Creates a new Game instance given a game identifier.
34
35 The game identifier is used by NFL.com's GameCenter live update web
36 pages. It is used to construct a URL to download JSON data for the
37 game.
38
39 If the game has been completed, the JSON data will be cached to disk
40 so that subsequent accesses will not re-download the data but instead
41 read it from disk.
42
43 When the JSON data is written to disk, it is compressed using gzip.
44 """
45
46 self.eid = eid
47 self.data = json.loads(self.rawData)[self.eid]
48
49 self.__load_all_players(self.data)
50 self.players = player.Players(self.__players)
51
52
53 self.qtr = self.data['qtr']
54 self.clock = self.data['clock']
55 self.home = self.data['home']['abbr']
56 self.away = self.data['away']['abbr']
57 self.score_home = int(self.data['home']['score']['T'])
58 self.score_away = int(self.data['away']['score']['T'])
59 for q in (1, 2, 3, 4, 5):
60 for team in ('home', 'away'):
61 score = self.data[team]['score'][str(q)]
62 self.__dict__['score_%s_q%d' % (team, q)] = int(score)
63
64 if not self.game_over():
65 self.winner = None
66 else:
67 if self.score_home > self.score_away:
68 self.winner = self.home
69 self.loser = self.away
70 elif self.score_away > self.score_home:
71 self.winner = self.away
72 self.loser = self.home
73 else:
74 self.winner = '%s/%s' % (self.home, self.away)
75 self.loser = '%s/%s' % (self.home, self.away)
76
77
78 self.scores = []
79 for k in sorted(map(int, self.data['scrsummary'])):
80 play = self.data['scrsummary'][str(k)]
81 s = '%s - Q%d - %s - %s' \
82 % (play['team'], play['qtr'], play['type'], play['desc'])
83 self.scores.append(s)
84
85 fpath = _jsonf % eid
86 if self.game_over() and not os.access(fpath, os.R_OK):
87 try:
88 print >> gzip.open(fpath, 'w+'), self.rawData,
89 except IOError:
90 print >> sys.stderr, "Could not cache JSON data. Please " \
91 "make '%s' writable." \
92 % os.path.dirname(fpath)
93
95 """game_over returns true if the game is no longer being played."""
96 return self.qtr == 'Final'
97
99 """playing returns true if the game is currently being played."""
100 return self.qtr != 'Pregame' and self.qtr != 'Final'
101
103 """
104 Returns a nicely formatted string indicating the current time of the
105 game. Examples include "Q1 10:52", "Q4 1:25", "Pregame", "Halftime"
106 and "Final".
107 """
108 try:
109 q = int(self.qtr)
110 return 'Q%d %s' % (q, self.clock)
111 except ValueError:
112 return self.qtr
113
115 self.__players = OrderedDict()
116 for team in ("home", "away"):
117 for category in player.categories:
118 if category not in gameData[team]["stats"]:
119 continue
120 catplayers = gameData[team]["stats"][category]
121 for playerid, stats in catplayers.iteritems():
122 p = self.__get_or_add_player(playerid, stats["name"],
123 team == "home")
124 p._add_stats(category, stats)
125
132
133
135 """
136 Returns the JSON data corresponding to the game represented by eid.
137
138 If the JSON data is already on disk, it is read, decompressed and returned.
139
140 Otherwise, the JSON data is downloaded from the NFL web site. If the data
141 doesn't exist yet or there was an error, _get_json_data returns None.
142 """
143 fpath = _jsonf % eid
144 if os.access(fpath, os.R_OK):
145 return gzip.open(fpath).read()
146 try:
147 return urllib2.urlopen(_json_base_url % (eid, eid)).read()
148 except urllib2.HTTPError:
149 pass
150 return None
151