1 from collections import OrderedDict
2 import os
3 import os.path as path
4 import gzip
5 import json
6 import sys
7 import urllib2
8
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, eid)
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 if self.score_home > self.score_away:
64 self.winner = self.home
65 elif self.score_away > self.score_home:
66 self.winner = self.away
67 else:
68 self.winner = 'TIE'
69
70
71 self.scores = []
72 for k in sorted(map(int, self.data['scrsummary'])):
73 play = self.data['scrsummary'][str(k)]
74 s = '%s - Q%d - %s - %s' \
75 % (play['team'], play['qtr'], play['type'], play['desc'])
76 self.scores.append(s)
77
78 fpath = _jsonf % eid
79 if self.game_over() and not os.access(fpath, os.R_OK):
80 try:
81 print >> gzip.open(fpath, 'w+'), self.rawData,
82 except IOError:
83 print >> sys.stderr, "Could not cache JSON data. Please " \
84 "make '%s' writable." \
85 % os.path.dirname(fpath)
86
88 """game_over returns true if the game is no longer being played."""
89 return self.qtr == 'Final'
90
92 """playing returns true if the game is currently being played."""
93 return self.qtr != 'Pregame' and self.qtr != 'Final'
94
96 """
97 Returns a nicely formatted string indicating the current time of the
98 game. Examples include "Q1 10:52", "Q4 1:25", "Pregame", "Halftime"
99 and "Final".
100 """
101 try:
102 q = int(self.qtr)
103 return 'Q%d %s' % (q, self.clock)
104 except ValueError:
105 return self.qtr
106
108 self.__players = OrderedDict()
109 for team in ("home", "away"):
110 for category in player.categories:
111 if category not in gameData[team]["stats"]:
112 continue
113 catplayers = gameData[team]["stats"][category]
114 for playerid, stats in catplayers.iteritems():
115 p = self.__get_or_add_player(playerid, stats["name"],
116 team == "home")
117 p._add_stats(category, stats)
118
125
126
128 """
129 Returns the JSON data corresponding to the game represented by eid.
130
131 If the JSON data is already on disk, it is read, decompressed and returned.
132
133 Otherwise, the JSON data is downloaded from the NFL web site. If the data
134 doesn't exist yet or there was an error, _get_json_data returns None.
135 """
136 fpath = _jsonf % eid
137 if os.access(fpath, os.R_OK):
138 return gzip.open(fpath).read()
139 try:
140 return urllib2.urlopen(_json_base_url % (eid, eid)).read()
141 except urllib2.HTTPError:
142 pass
143 return None
144