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
15 """
16 Game represents a single pre- or regular-season game. It provides a window
17 into the statistics of every player that played into the game, along with
18 the winner of the game, the score and a list of all the scoring plays.
19 """
20
22
23 rawData = _get_json_data(eid)
24 if rawData is None or rawData.strip() == '{}':
25 return None
26 game = object.__new__(cls, eid)
27 game.rawData = rawData
28 return game
29
31 """
32 Creates a new Game instance given a game identifier.
33
34 The game identifier is used by NFL.com's GameCenter live update web
35 pages. It is used to construct a URL to download JSON data for the
36 game.
37
38 If the game has been completed, the JSON data will be cached to disk
39 so that subsequent accesses will not re-download the data but instead
40 read it from disk.
41
42 When the JSON data is written to disk, it is compressed using gzip.
43 """
44
45 self.eid = eid
46 self.data = json.loads(self.rawData)[self.eid]
47
48 self.__load_all_players(self.data)
49 self.players = player.Players(self.__players)
50
51
52 self.qtr = self.data['qtr']
53 self.clock = self.data['clock']
54 self.home = self.data['home']['abbr']
55 self.away = self.data['away']['abbr']
56 self.score_home = int(self.data['home']['score']['T'])
57 self.score_away = int(self.data['away']['score']['T'])
58 for q in (1, 2, 3, 4, 5):
59 for team in ('home', 'away'):
60 score = self.data[team]['score'][str(q)]
61 self.__dict__['score_%s_q%d' % (team, q)] = int(score)
62 if self.score_home > self.score_away:
63 self.winner = self.home
64 elif self.score_away > self.score_home:
65 self.winner = self.away
66 else:
67 self.winner = 'TIE'
68
69
70 self.scores = []
71 for k in sorted(map(int, self.data['scrsummary'])):
72 play = self.data['scrsummary'][str(k)]
73 s = '%s - Q%d - %s - %s' \
74 % (play['team'], play['qtr'], play['type'], play['desc'])
75 self.scores.append(s)
76
77 fpath = _jsonf % eid
78 if self.game_over() and not os.access(fpath, os.R_OK):
79 try:
80 print >> gzip.open(fpath, 'w+'), self.rawData,
81 except IOError:
82 print >> sys.stderr, "Could not cache JSON data. Please make " \
83 "'%s' writable." % os.path.dirname(fpath)
84
86 """game_over returns true if the game is no longer being played."""
87 return self.qtr == 'Final'
88
90 """playing returns true if the game is currently being played."""
91 return self.qtr != 'Pregame' and self.qtr != 'Final'
92
94 self.__players = OrderedDict()
95 for team in ("home", "away"):
96 for category in player.categories:
97 if category not in gameData[team]["stats"]:
98 continue
99 catplayers = gameData[team]["stats"][category]
100 for playerid, stats in catplayers.iteritems():
101 p = self.__get_or_add_player(playerid, stats["name"],
102 team == "home")
103 p._add_stats(category, stats)
104
111
113 """
114 Returns the JSON data corresponding to the game represented by eid.
115
116 If the JSON data is already on disk, it is read, decompressed and returned.
117
118 Otherwise, the JSON data is downloaded from the NFL web site. If the data
119 doesn't exist yet or there was an error, _get_json_data returns None.
120 """
121 fpath = _jsonf % eid
122 if os.access(fpath, os.R_OK):
123 return gzip.open(fpath).read()
124 try:
125 return urllib2.urlopen(_json_base_url % (eid, eid)).read()
126 except urllib2.HTTPError:
127 pass
128 return None
129