def __init__(self, app, ctx, row, game): BaseDisplay.__init__(self, app, ctx, row) self.game = game data = utils.request( Url.GAME, {'game_id': self.game.game_id} ) # This display requires players to initialized. self.game.init_players(data) # call to update self.game.update_data(data) team_stats = execute_constant( self.app.db_conn, db_const.TEAM_RANKED_SELECT.format( utils.get_season_number(arrow.now()) ) ) self.home_stats = TeamSeasonStats( self.game.home.team_id, self.app.db_conn, team_stats[const.TEAM_INDEX[self.game.home.team_id]] ) self.away_stats = TeamSeasonStats( self.game.away.team_id, self.app.db_conn, team_stats[const.TEAM_INDEX[self.game.away.team_id]] ) widget = self.build_display() urwid.WidgetWrap.__init__(self, widget)
def __init__(self, db_conn, game_id, data=None): if not data: data = request(Url.GAME, url_mods={'game_id': game_id}) super().__init__(db_conn=db_conn, game_id=game_id, data=data, _class=GameStatsTeam) # noqa
def update(self): data = utils.request( Url.GAME, {'game_id': self.game.game_id} ) self.game.update_data(data) # this is the internal attribute widget self._w = self.build_display()
def update_data(self, game_info=None): if not game_info: game_info = request(Url.GAME, url_mods={'game_id': game_id}) parsed_data = parser.teams_skater_stats(game_info, self.team_type, False) for key, val in parsed_data.items(): if hasattr(self, key): setattr(self, key, val) else: raise AttributeError(f'Update received an attribute {key} \ that has not been set.')
def create_players(self, data=None): """Utility method so we can have control on when to call the expensive create logic.""" if self.players: return if not data: data = utils.request( Url.GAME, {'game_id': self.team.game.game_id} ) # cant use isinstance of. if self._class == GamePlayer: data_copy = data['liveData']['boxscore']['teams'][self.team.team_type]['players'] # noqa else: data_copy = data # this should always hit # unless no changes were deemed necessary at init if self.need_to_update: self.replace_players() index = 0 for player in self.player_ids: # strip off the ID part player_data = data_copy['ID' + str(player)] # parse and create player pd = parser.player_stats_game(player_data) player_obj = self._class(self.db_conn, player, pd) # if a player is scratched parser returns None if pd is not None: # keep index pointers for each player object in self.players if player_obj.position == 'G': self.goalies.append(index) elif player_obj.position == 'D': self.defense.append(index) else: self.forwards.append(index) else: self.not_playing.append(index) # increment index and add the player_obj index += 1 self.players.append(player_obj)
def team_standings_stats(team_id, division, season, parsed_data): """Queries the Standings endpoint for Regulation Wins""" from puck.utils import request from puck.urls import Url data = request(Url.STANDINGS, params={ 'expand': 'standings.record', 'season': (season) }) # maps division to an index that Url.Standings returns divisions = {18: 0, 17: 1, 16: 2, 15: 3} data = data['records'][divisions[division]]['teamRecords'] for i in data: if i['team']['id'] == team_id: # tie breaker parsed_data['reg_ot_wins'] = i['row'] # streak of wins, losses, or OTL parsed_data['streak'] = i['streak']['streakCode'] game_splits = i['records']['overallRecords'] # last ten games last_ten = map(str, [ game_splits[3]['wins'], game_splits[3]['losses'], game_splits[3]['ot'] ]) parsed_data['last_ten'] = '-'.join(last_ten) # home split home_record = map(str, [ game_splits[0]['wins'], game_splits[0]['losses'], game_splits[0]['ot'] ]) parsed_data['home_record'] = '-'.join(home_record) # away split away_record = map(str, [ game_splits[1]['wins'], game_splits[1]['losses'], game_splits[1]['ot'] ]) parsed_data['away_record'] = '-'.join(away_record) return
def __init__(self, game, game_id, team_type, game_info=None): """Constructor for BannerTeam Args: game (BannerGame): Any game that inherits BannerGame game_id (int): API Game ID team_type (str): Either "home" or "away" game_info (dict, optional): JSON API response represented as a dictionary. Defaults to None. Raises: InvalidTeamType: If 'home' or 'away' is not supplied creation will fail. """ # housekeeping team_type = team_type.lower() if team_type == 'home' or team_type == 'away': self.team_type = team_type else: raise InvalidTeamType # check if game data was passed if not game_info: game_info = request(Url.GAME, url_mods={'game_id': game_id}) # get the teams id number team_id = game_info['gameData']['teams'][team_type]['id'] # call parent class constructor super().__init__(team_id, game.db_conn) self.game = game self.game_id = game_id # parse the game data parsed_data = parser.teams_skater_stats(game_info, self.team_type, False) # set attributes (goals in this case) for key, val in parsed_data.items(): setattr(self, key, val)
def update_data(self, data=None): """Updates an object using fresh data. Args: data (dict, optional): JSON API response represented as a dictionary. Defaults to None. """ if not data: data = request(Url.GAME, url_mods={'game_id': game_id}) _status_code = int(data['gameData']['status']['statusCode']) # NOTE: This check could fail if the game status code # is updated before this. if _status_code in const.GAME_STATUS[ 'Preview'] and self.game.game_status in const.GAME_STATUS[ 'Preview']: # noqa return parsed_data = parser.teams_skater_stats(data, self.team_type, True) for key, val in parsed_data.items(): if hasattr(self, key): setattr(self, key, val) else: raise AttributeError(f'Update received an attribute {key} \ that has not been set.') # we protect against this case in players.update_data # but no need to waste computation if self.players: self.players.update_data(data) self.periods.update_data(data['liveData']['linescore']['periods'], self.team_type) if data['liveData']['linescore']['hasShootout']: self.shootout.goals = data['liveData']['linescore'][ 'shootoutInfo'][team_type]['scores'] # noqa self.shootout.attempts = data['liveData']['linescore'][ 'shootoutInfo'][team_type]['attempts'] # noqa
def __init__(self, app, ctx, row, game): BaseDisplay.__init__(self, app, ctx, row) self.game = game data = utils.request( Url.GAME, {'game_id': self.game.game_id} ) # This display requires players to initialized. # if this display is swapped with SingleGamePreviewDisplay, # the game object has it's player's initialized self.game.init_players(data) # call to update self.game.update_data(data) widget = self.build_display() urwid.WidgetWrap.__init__(self, widget)
def __init__(self, db_conn, game_id, data=None, _class=BannerTeam): """ Args: db_conn (psycopg2.Connection): database connection game_id (int): Game ID data (dict, optional): JSON rep of the game. Defaults to None. _class (BaseTeam, optional): Team object to create. Defaults to BannerTeam. """ super().__init__(db_conn, game_id) if not data: data = request(Url.GAME, url_mods={'game_id': game_id}) parsed_data = parser.game(data) for key, val in parsed_data.items(): setattr(self, key, val) self.home = _class(self, game_id, 'home', data) self.away = _class(self, game_id, 'away', data)
def update_data(self, data=None): """ This class method updates a game object. NOTE: Does not use game as we only need to update small subset of data. """ # TODO CLEAN UP UPDATE # If the game is already finished, no need to request info if self.is_final: return if not data: data = request(Url.GAME, url_mods={'game_id': self.game_id}) _status_code = int(data['gameData']['status']['statusCode']) # game status hasn't changed if _status_code in const.GAME_STATUS[ 'Preview'] and self.is_preview: # noqa self.game_status = _status_code return parsed_data = parser.game(data) for key, val in parsed_data.items(): if hasattr(self, key): setattr(self, key, val) else: raise AttributeError( f'Game.update_data received an attribute {key} \ that has not been set.') # this will call update no matter the Team Class type self.home.update_data(data) self.away.update_data(data)
def get_game_ids(url_mods=None, params=None): """ Return a list of game ids based on specific url parameters. Args: url_mods (dict, optional): Certain urls are required to be formatted params (dict, optional): Misc. url parameters that alter the query. Returns: list: returns list of game ids for selected query """ game_info = request(Url.SCHEDULE, url_mods=url_mods, params=params) ids = [] # dates is a list of all days requested # if this key does not exist an empty list will be returned for day in game_info.get('dates', []): # games is a list of all games in a day for game in day.get('games', []): ids.append(game['gamePk']) return ids
def __init__(self, game, game_id, team_type, data=None): """Constructor for GameStatsTeam Args: game (BannerGame or FullGame): The Container object. Any object that inherits BannerGame game_id (int): API Game ID team_type (str): Either 'home' or 'away' data (dict, optional): JSON API response represented as a dictionary Raises: InvalidTeamType: If 'home' or 'away' is not supplied creation will fail. """ # housekeeping check team_type = team_type.lower() if team_type == 'home' or team_type == 'away': self.team_type = team_type else: raise InvalidTeamType # if the game data was passed to the constructor use that if not data: # request the game data data = request(Url.GAME, url_mods={'game_id': game_id}) # get the teams id number team_id = data['gameData']['teams'][team_type]['id'] # Call the parent class constructor super().__init__(team_id, game.db_conn) # holds reference to the Game "container" self.game = game self.game_id = game_id # parse the data parsed_data = parser.teams_skater_stats(data, self.team_type, True) # set attributes for key, val in parsed_data.items(): setattr(self, key, val) # PeriodStats object for easier referencing self.periods = self.PeriodStats( data['liveData']['linescore']['periods'], team_type) # ShootOutStats object for easier referencing if data['liveData']['linescore']['hasShootout']: self.shootout = self.ShootoutStats( goals=data['liveData']['linescore']['shootoutInfo'][team_type] ['scores'], # noqa attempts=data['liveData']['linescore']['shootoutInfo'] [team_type]['attempts'] # noqa ) else: self.shootout = self.ShootoutStats() # collect all player ids self.id_list = data['liveData']['boxscore']['teams'][team_type][ 'goalies'] # noqa self.id_list.extend(data['liveData']['boxscore']['teams'][team_type] ['skaters']) # noqa self.id_list.extend(data['liveData']['boxscore']['teams'][team_type] ['scratches']) # noqa # wait to create the actual player objects self.players = None