예제 #1
0
def get_team_id(team_name):
    """Passes team name to NHL API and returns team ID.

    Args:
        team_name: Valid NHL team name.

    Returns:
        team_id: NHL Team ID
    """

    team_name = team_name.lower()
    endpoint = "/teams"
    response = api.nhl_api(endpoint)

    if not response:
        raise ConnectionError("An invalid response was returned from the NHL Teams API.")

    teams_json = response.json()
    teams = teams_json["teams"]

    team_id = None
    for team in teams:
        if team["name"].lower() == team_name:
            team_id = team["id"]
            break

    if not team_id:
        raise ValueError("{} is not a valid NHL team. Check your configuraiton file!".format(team_name))

    return team_id
예제 #2
0
def get_next_game(today_game_date: datetime, team_id: int) -> dict:
    """Takes today's game date & the team ID to get the next game from the NHL API endpoint.

    Args:
        today_game_date (datetime) - The date of today's game.
        team_id (int) - The unique identifier of the team (from get_team function).

    Returns:
        next_game (dict) - Dictionary of next game attributes.
    """

    game_date = today_game_date.strftime("%Y-%m-%d")
    tomorrow = (today_game_date + timedelta(days=1)).strftime("%Y-%m-%d")
    end_date = (today_game_date + timedelta(days=365)).strftime("%Y-%m-%d")

    logging.info("Checking the schedule API endpoint for the next game.")
    url = f"schedule?teamId={team_id}&startDate={game_date}&endDate={end_date}"

    response = api.nhl_api(url)
    if not response:
        return None

    next_game_json = response.json()
    next_game = next_game_json.get("dates")[1].get("games")[0]

    return next_game
예제 #3
0
def nonroster_player_attr_by_id(player_id, attribute):
    """Returns the attribute of a non-roster player via the NHL People API.

    Args:
        player_id (str): Player unique identifier (IDXXXXXXX)
        attribute (str): Attribute from roster dictionary.

    Returns:
        string: Attribute of the person requested.
    """
    api_player_url = f"/people/{player_id}"
    api_player = api.nhl_api(api_player_url).json()
    player_attr = api_player["people"][0][attribute]
    return player_attr
예제 #4
0
def get_livefeed(game_id):
    """Queries the NHL Live Feed API to determine if there is a game today.

    Args:
        game_id (int) - The unique identifier of the Game.

    Returns:
        response - JSON object of live feed results
    """
    randomnum = random.randint(1000, 9999)
    logging.info("Live Feed requested (random cache - %s)!", randomnum)
    api_endpoint = f"game/{game_id}/feed/live?{randomnum}"
    response = api.nhl_api(api_endpoint).json()
    return response
예제 #5
0
def is_game_today(team_id, date):
    """Queries the NHL Schedule API to determine if there is a game today.

    Args:
        team_id (int) - The unique identifier of the team (from get_team function).

    Returns:
        (bool, games_info)
        bool - True if game today, False if not.
        games_info (dict) - A dictionary from the Schedule API that describes game information.
    """
    args = arguments.get_arguments()

    url = "/schedule?teamId={id}&expand=" "schedule.broadcasts,schedule.teams&date={date:%Y-%m-%d}".format(
        id=team_id, date=date
    )

    response = api.nhl_api(url)
    if response:
        schedule = response.json()
        games_total = schedule["totalItems"]
    else:
        return False, None

    if games_total == 1:
        games_info = schedule["dates"][0]["games"][0]
        return True, games_info

    if games_total == 2:
        if args.split is False:
            logging.info("Split Squad - spawning a second process to pick up second game.")
            game_index = 0
            process.spawn_another_process()
            time.sleep(10)
        else:
            game_index = 1
            logging.info("Split Squad - this is the process to pick up second game (sleep 5 seconds).")
            time.sleep(5)

        games_info = schedule["dates"][0]["games"][game_index]
        return True, games_info

    date_string = date.date() if args.date else "today"
    logging.info("There are no games scheduled for %s, SAD!", date_string)
    return False, schedule
예제 #6
0
def get_content_feed(game_id, milestones=False):
    """ Queries the NHL Content Feed API to get media items (photos, videos, etc)

    Args:
        game_id (int) - The unique identifier of the Game.
        milestones (bool) - Returns only the milestones section

    Returns:
        response - JSON object of live feed results
    """

    logging.info("Content Feed requested (milestones: %s)!", milestones)
    api_endpoint = f"game/{game_id}/content"
    response = api.nhl_api(api_endpoint).json()

    # Calculate milestones if argument is True
    response = response if not milestones else response["media"]["milestones"][
        "items"]
    return response
예제 #7
0
def get_number_games(season: str, team_id: int, game_type_code: str = "R") -> dict:
    """Queries the NHL Schedule API to how many games are in this season.
        This is particularly important in the 2020-2021 shortened season.

    Args:
        season (str) - The 8-digit season code (ex: 20202021).
        team_id (int) - The unique identifier of the team (from get_team function).

    Returns:
        num_games (int) - The number of games played in the regular season.
    """
    args = arguments.get_arguments()

    endpoint = f"/schedule?teamId={team_id}&season={season}&gameType={game_type_code}"
    response = api.nhl_api(endpoint)

    if response:
        schedule = response.json()
        games_total = schedule["totalItems"]
        return games_total

    # If no valid response, just return default number of games (82)
    return 82
예제 #8
0
def get_previous_game(team_id: int) -> dict:
    """Takes a team ID & gets the previous game from the schedule API modified endpoint.

    Args:
        team_id (int) - The unique identifier of the team (from get_team function).

    Returns:
        date (string) - Date of last game
        next_game (dict) - Dictionary of previous game attributes.
    """

    logging.info("Checking the schedule API endpoint for the previous game.")
    url = f"teams/{team_id}?expand=team.schedule.previous"

    response = api.nhl_api(url)
    if not response:
        return None

    prev_game_json = response.json()
    prev_game_sched = prev_game_json.get("teams")[0].get("previousGameSchedule")
    prev_game_date = prev_game_sched.get("dates")[0].get("date")
    prev_game = prev_game_sched.get("dates")[0].get("games")[0]

    return prev_game_date, prev_game
예제 #9
0
def season_series(game_id, pref_team, other_team, last_season=False):
    """Generates season series, points leader & TOI leader.

    Args:
        game_id
        pref_team:
        other_team:

    Returns:
        Tuple: (season_series_str, points_leader_str, toi_leader_str)
        season_series_str: Season Series (w/ records)
        points_leader_str: Points Leader(s)
        toi_leader_str: TOI Leader(s)
    """

    # Init empty dictionaries and lists
    games_against = list()
    pref_toi = dict()
    pref_goals = dict()
    pref_assists = dict()
    pref_points = dict()
    pref_record = {"wins": 0, "losses": 0, "ot": 0}
    roster_player = True

    # If this is the first game of the season, we can set the 'last_season' flag to enable the
    # season series function to check last year's season series between the two teams.
    if not last_season:
        season_start = str(game_id)[0:4]
        season_end = str(int(season_start) + 1)
        yesterday = datetime.now() - timedelta(days=1)
        # yesterday = datetime.now() + timedelta(days=50)
        # schedule_url = (
        #     f"/schedule?teamId={pref_team.team_id}"
        #     f"&expand=schedule.broadcasts,schedule.teams&startDate="
        #     f"{season_start}-08-01&endDate={yesterday:%Y-%m-%d}"
        # )
        schedule_url = (
            f"/schedule?teamId={pref_team.team_id}"
            f"&expand=schedule.broadcasts,schedule.teams"
            f"&season={season_start}{season_end}"
        )
    else:
        season_start = int(str(game_id)[0:4]) - 1
        season_end = str(int(season_start) + 1)
        yesterday = datetime.now() - timedelta(days=1)
        # yesterday = datetime.now() + timedelta(days=50)
        # schedule_url = (
        #     f"/schedule?teamId={pref_team.team_id}"
        #     f"&expand=schedule.broadcasts,schedule.teams&startDate="
        #     f"{season_start}-08-01&endDate={season_end}-06-01"
        # )
        schedule_url = (
            f"/schedule?teamId={pref_team.team_id}"
            f"&expand=schedule.broadcasts,schedule.teams"
            f"&season={season_start}{season_end}"
        )

    schedule = api.nhl_api(schedule_url).json()
    dates = schedule["dates"]

    # Loop through scheduled to get previously played games against
    for date in dates:
        game = date["games"][0]
        game_type = game["gameType"]
        game_id = game["gamePk"]
        game_team_home = game["teams"]["home"]["team"]["name"]
        game_team_away = game["teams"]["away"]["team"]["name"]
        teams = [game_team_away, game_team_home]
        game_status = game["status"]["abstractGameState"]
        if game_type == "R" and game_status == "Final" and other_team.team_name in teams:
            game_feed = f"/game/{game_id}/feed/live"
            games_against.append(game_feed)

    # If the two teams haven't played yet, just exit this function
    if not games_against:
        return None, None, None

    # Loop through newly created games_against list to get each stats
    for feed in games_against:
        game = api.nhl_api(feed).json()
        game_data = game["gameData"]
        home_team_name = game_data["teams"]["home"]["name"]
        pref_homeaway = "home" if home_team_name == pref_team.team_name else "away"
        other_homeaway = "away" if home_team_name == pref_team.team_name else "home"

        # Get season series
        end_period = game["liveData"]["linescore"]["currentPeriod"]
        extra_time = True if end_period > 3 else False
        pref_score = game["liveData"]["linescore"]["teams"][pref_homeaway]["goals"]
        other_score = game["liveData"]["linescore"]["teams"][other_homeaway]["goals"]
        if pref_score > other_score:
            pref_record["wins"] += 1
        elif other_score > pref_score and extra_time:
            pref_record["ot"] += 1
        else:
            pref_record["losses"] += 1

        season_series_str = f"Series: {pref_record['wins']}-" f"{pref_record['losses']}-{pref_record['ot']}"

        # Get stats leaders
        # pref_teamstats = game["liveData"]["boxscore"]["teams"][pref_homeaway]["teamStats"]
        pref_playerstats = game["liveData"]["boxscore"]["teams"][pref_homeaway]["players"]
        for id, player in pref_playerstats.items():
            try:
                # Calculate TOI
                player_toi_str = player["stats"]["skaterStats"]["timeOnIce"]
                player_toi_minutes = int(player_toi_str.split(":")[0])
                player_toi_seconds = int(player_toi_str.split(":")[1])
                player_toi = (player_toi_minutes * 60) + player_toi_seconds
                pref_toi[id] = pref_toi.get(id, 0) + player_toi

                # Point Totals
                player_goal_str = player["stats"]["skaterStats"]["goals"]
                pref_goals[id] = pref_goals.get(id, 0) + int(player_goal_str)
                player_assist_str = player["stats"]["skaterStats"]["assists"]
                pref_assists[id] = pref_assists.get(id, 0) + int(player_assist_str)
                player_points = int(player_goal_str) + int(player_assist_str)
                pref_points[id] = pref_points.get(id, 0) + int(player_points)

            except KeyError:
                pass

    # Calculate Stats Leaders
    sorted_toi = sorted(pref_toi.values(), reverse=True)
    leader_toi = sorted_toi[0]

    sorted_points = sorted(pref_points.values(), reverse=True)
    leader_points = sorted_points[0]

    # Get TOI leader
    for id in pref_toi.keys():
        if pref_toi[id] == leader_toi:
            player_name = roster.player_attr_by_id(pref_team.roster, id, "fullName")
            if player_name is None:
                roster_player = False
                player_id_only = id.replace("ID", "")
                player_name = roster.nonroster_player_attr_by_id(player_id_only, "fullName")
            leader_toi_avg = leader_toi / len(games_against)
            m, s = divmod(leader_toi_avg, 60)
            toi_m = int(m)
            toi_s = int(s)
            toi_s = "0{}".format(toi_s) if toi_s < 10 else toi_s
            toi_avg = "{}:{}".format(toi_m, toi_s)
            player_short_name = f"{player_name[0]}. {' '.join(player_name.split()[1:])}"
            toi_leader_str = "TOI Leader: {} with {} / game.".format(player_short_name, toi_avg)

    # Handle tied points leaders
    point_leaders = list()
    for id in pref_points.keys():
        if pref_points[id] == leader_points:
            point_leaders.append(id)

    if leader_points == 0:
        points_leader_str = "Points Leader: None (all players have 0 points)."

    elif len(point_leaders) == 1:
        leader = point_leaders[0]
        player_name = roster.player_attr_by_id(pref_team.roster, leader, "fullName")
        # If the player is no longer on the team, get their information (change string here?)
        if player_name is None:
            roster_player = False
            player_id_only = leader.replace("ID", "")
            player_name = roster.nonroster_player_attr_by_id(player_id_only, "fullName")
        player_goals = pref_goals[leader]
        player_assists = pref_assists[leader]
        if not roster_player:
            points_leader_str = (
                f"Points Leader: {player_name} with {leader_points} points "
                f"({player_goals}G {player_assists}A) "
            )
        else:
            points_leader_str = "Points Leader: {} with {} ({}G {}A).".format(
                player_name, leader_points, player_goals, player_assists
            )

    elif len(point_leaders) > 3:
        point_leaders_with_attrs = list()
        for leader in point_leaders:
            player_name = roster.player_attr_by_id(pref_team.roster, leader, "fullName")
            if player_name is None:
                player_id_only = leader.replace("ID", "")
                player_name = roster.nonroster_player_attr_by_id(player_id_only, "fullName")
            player_goals = pref_goals[leader]
            player_assists = pref_assists[leader]
            player_short_name = f"{player_name[0]}. {' '.join(player_name.split()[1:])}"
            point_leaders_with_attrs.append(player_short_name)

        point_leaders_joined = ", ".join(point_leaders_with_attrs[0:3])
        leftover_leaders = len(point_leaders) - 3
        points_leader_str = (
            f"Points Leaders: {point_leaders_joined} & {leftover_leaders} others ({leader_points} each)."
        )

    else:
        point_leaders_with_attrs = list()
        for leader in point_leaders:
            player_name = roster.player_attr_by_id(pref_team.roster, leader, "fullName")
            if player_name is None:
                player_id_only = leader.replace("ID", "")
                player_name = roster.nonroster_player_attr_by_id(player_id_only, "fullName")
            player_goals = pref_goals[leader]
            player_assists = pref_assists[leader]
            player_short_name = f"{player_name[0]}. {' '.join(player_name.split()[1:])}"
            player_str = f"{player_short_name} ({player_goals}G {player_assists}A)"
            point_leaders_with_attrs.append(player_str)

        point_leaders_joined = (
            f", ".join(point_leaders_with_attrs[:-1]) + f" & {point_leaders_with_attrs[-1]}"
        )
        points_leader_str = "Points Leaders: {} with {} each.".format(point_leaders_joined, leader_points)

    return season_series_str, points_leader_str, toi_leader_str