Skip to content

Commit

Permalink
Update Standings for new API.
Browse files Browse the repository at this point in the history
Make schedule and games command work. These might require more work in the future.
Allow api schedule commands to specify a date.
  • Loading branch information
TrustyJAID committed Nov 13, 2023
1 parent 99e134b commit 6ee8ddf
Show file tree
Hide file tree
Showing 6 changed files with 160 additions and 66 deletions.
28 changes: 23 additions & 5 deletions hockey/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from .constants import TEAMS
from .game import Game, GameState, GameType
from .goal import Goal
from .standings import Standings

TEAM_IDS = {v["id"]: k for k, v in TEAMS.items()}

Expand Down Expand Up @@ -713,23 +714,35 @@ async def club_schedule_season(self, team: str) -> Schedule:
data = await resp.json()
return Schedule.from_nhle(data)

async def club_schedule_week(self, team: str) -> Schedule:
async def club_schedule_week(self, team: str, date: Optional[datetime] = None) -> Schedule:
team_abr = self.team_to_abbrev(team)
date_str = "now"
if date is not None:
date_str = date.strftime("%Y-%M-%d")
if team_abr is None:
raise HockeyAPIError("An unknown team name was provided")
async with self.session.get(f"{self.base_url}/club-schedule/{team_abr}/week/now") as resp:
async with self.session.get(
f"{self.base_url}/club-schedule/{team_abr}/week/{date_str}"
) as resp:
if resp.status != 200:
log.error("Error accessing the Club Schedule for the week. %s", resp.status)
raise HockeyAPIError("There was an error accessing the API.")

data = await resp.json()
return Schedule.from_nhle(data)

async def club_schedule_month(self, team: str) -> Schedule:
async def club_schedule_month(self, team: str, date: Optional[datetime] = None) -> Schedule:
team_abr = self.team_to_abbrev(team)

if team_abr is None:
raise HockeyAPIError("An unknown team name was provided")
async with self.session.get(f"{self.base_url}/club-schedule/{team_abr}/month/now") as resp:

date_str = "now"
if date is not None:
date_str = date.strftime("%Y-%M")
async with self.session.get(
f"{self.base_url}/club-schedule/{team_abr}/month/{date_str}"
) as resp:
if resp.status != 200:
log.error("Error accessing the Club Schedule for the month. %s", resp.status)
raise HockeyAPIError("There was an error accessing the API.")
Expand Down Expand Up @@ -781,12 +794,16 @@ async def get_schedule(
) -> Schedule:
if team:
if start_date is not None:
return await self.club_schedule_week(team)
return await self.club_schedule_week(team, start_date)
return await self.club_schedule_season(team)
if start_date is not None:
return await self.schedule(start_date)
return await self.schedule_now()

async def get_standings(self) -> Standings:
data = await self.standings_now()
return Standings.from_nhle(data)

async def get_games_list(
self,
team: Optional[str] = None,
Expand Down Expand Up @@ -884,5 +901,6 @@ async def to_game(self, data: dict, content: Optional[dict] = None) -> Game:
game_type=game_type,
season=data.get("season", 0),
recap_url=None,
api=self,
# data=data,
)
18 changes: 6 additions & 12 deletions hockey/game.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,17 @@
from enum import Enum
from typing import TYPE_CHECKING, Dict, List, Literal, Optional, Tuple, Union

import aiohttp
import discord
from red_commons.logging import getLogger
from redbot.core.bot import Red
from redbot.core.i18n import Translator
from redbot.core.utils import AsyncIter
from redbot.core.utils.chat_formatting import pagify

from .constants import BASE_URL, CONTENT_URL, TEAMS
from .constants import TEAMS
from .goal import Goal
from .helper import (
check_to_post,
get_channel_obj,
get_team,
get_team_role,
utc_to_local,
)
from .standings import LeagueRecord, Playoffs, Standings
from .helper import check_to_post, get_channel_obj, get_team, get_team_role
from .standings import LeagueRecord, Playoffs

if TYPE_CHECKING:
from .api import GameData
Expand Down Expand Up @@ -323,6 +316,7 @@ def __init__(self, **kwargs):
self.season = kwargs.get("season")
self._recap_url: Optional[str] = kwargs.get("recap_url", None)
self.data = kwargs.get("data", {})
self.api = kwargs.get("api", None)

def __repr__(self):
return "<Hockey Game home={0.home_team} away={0.away_team} state={0.game_state}>".format(
Expand Down Expand Up @@ -631,12 +625,12 @@ async def get_stats_msg(self) -> Tuple[str, str, Optional[str]]:
home_str = _("GP:**0** W:**0** L:**0\n**OT:**0** PTS:**0** S:**0**\n")
away_str = _("GP:**0** W:**0** L:**0\n**OT:**0** PTS:**0** S:**0**\n")
desc = None
if self.game_type is GameType.playoffs:
if self.game_type is not GameType.playoffs:
msg = _(
"GP:**{gp}** W:**{wins}** L:**{losses}\n**OT:**{ot}** PTS:**{pts}** S:**{streak}**\n"
)
try:
standings = await Standings.get_team_standings()
standings = await self.api.get_standings()
for name, record in standings.all_records.items():
if record.team.name == self.away_team:
away_str = msg.format(
Expand Down
3 changes: 0 additions & 3 deletions hockey/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -611,7 +611,6 @@ async def get_team(bot: Red, team: str, game_start: str, game_id: int = 0) -> di
game_start=game_start,
game_id=game_id,
)
log.info("This should be unreachable")
team_list.append(team_entry.to_json())
await config.teams.set(team_list)
for teams in team_list:
Expand All @@ -620,7 +619,6 @@ async def get_team(bot: Red, team: str, game_start: str, game_id: int = 0) -> di
and game_start == teams["game_start"]
and game_id == teams["game_id"]
):
log.info("Returing already created Team Entry")
return teams
# Add unknown teams to the config to track stats
return_team = TeamEntry(
Expand All @@ -633,7 +631,6 @@ async def get_team(bot: Red, team: str, game_start: str, game_id: int = 0) -> di
game_start=game_start,
game_id=game_id,
)
log.info("Returing new team entry")
team_list.append(return_team.to_json())
await config.teams.set(team_list)
return return_team.to_json()
Expand Down
6 changes: 3 additions & 3 deletions hockey/hockey_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from .menu import BaseMenu, GamesMenu, LeaderboardPages, PlayerPages, SimplePages
from .player import SimplePlayer
from .schedule import Schedule, ScheduleList
from .standings import PlayoffsView, Standings, StandingsMenu
from .standings import PlayoffsView, StandingsMenu
from .stats import LeaderCategories, LeaderView

_ = Translator("Hockey", __file__)
Expand Down Expand Up @@ -128,7 +128,7 @@ async def standings(self, ctx: commands.Context, *, search: StandingsFinder = No
"""
await ctx.defer()
try:
standings = await Standings.get_team_standings(session=self.session)
standings = await self.api.get_standings()
except aiohttp.ClientConnectorError:
await ctx.send(
_("There's an issue accessing the NHL API at the moment. Try again later.")
Expand Down Expand Up @@ -216,7 +216,7 @@ async def playoffs(
season_str = int(season.group(1)) - 1
try:
await PlayoffsView(start_date=season_str).start(ctx=ctx)
except aiohttp.ClientConnectorError:
except Exception:
await ctx.send(
_("There's an issue accessing the NHL API at the moment. Try again later.")
)
Expand Down
92 changes: 52 additions & 40 deletions hockey/schedule.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
from datetime import datetime, timedelta, timezone
from typing import List, Optional

import aiohttp
import discord
from red_commons.logging import getLogger
from redbot.core.i18n import Translator
from redbot.core.utils.chat_formatting import humanize_list, pagify
from redbot.vendored.discord.ext import menus

from .api import ScheduledGame
from .constants import TEAMS
from .errors import NoSchedule
from .game import Game
from .game import GameState
from .helper import utc_to_local

_ = Translator("Hockey", __file__)
Expand Down Expand Up @@ -66,7 +66,7 @@ async def get_page(
)
if game_id is not None:
for game in self._cache:
if game["gamePk"] == game_id:
if game.id == game_id:
log.verbose("getting game %s", game_id)
page_number = self._cache.index(game)
log.verbose(
Expand Down Expand Up @@ -94,11 +94,10 @@ async def get_page(
self._last_page = page_number
return page

async def format_page(self, menu: menus.MenuPages, game: dict) -> discord.Embed:
log.trace("%s%s", self.api.base_url, game["link"])
async def format_page(self, menu: menus.MenuPages, game: ScheduledGame) -> discord.Embed:
log.trace("%s/gamecenter/%s/play-by-play", self.api.base_url, game.id)

data = await self.api.get_game_from_id(game["gamePk"])
game_obj = await Game.from_json(data)
game_obj = await self.api.get_game_from_id(game.id)
# return {"content": f"{self.index+1}/{len(self._cache)}", "embed": await game_obj.make_game_embed()}
em = await game_obj.make_game_embed(
include_plays=self.include_plays,
Expand All @@ -111,7 +110,7 @@ async def format_page(self, menu: menus.MenuPages, game: dict) -> discord.Embed:
em.set_image(url=game_obj.gameflow_url(corsi=self.corsi, strength=self.strength))
em.description = f"[Natural Stat Trick]({game_obj.nst_url()})"
if self.show_broadcasts:
broadcasts = game.get("broadcasts", [])
broadcasts = game.broadcasts
broadcast_str = humanize_list([b["name"] for b in broadcasts])
em.add_field(name=_("Broadcasts"), value=broadcast_str)
return em
Expand Down Expand Up @@ -192,38 +191,36 @@ async def _next_batch(
# log.debug("Filling the cache")
# compare_date = datetime.utcnow().strftime("%Y-%m-%d")
if date:
date_str = date.strftime("%Y-%m-%d")
date_timestamp = int(utc_to_local(date, "UTC").timestamp())
end_date_str = (date + timedelta(days=self.search_range)).strftime("%Y-%m-%d")
end_date_timestamp = int(
utc_to_local((date + timedelta(days=self.search_range)), "UTC").timestamp()
)
else:
date_str = self.date.strftime("%Y-%m-%d")
date_timestamp = int(utc_to_local(date, "UTC").timestamp())
end_date_str = (self.date + timedelta(days=self.search_range)).strftime("%Y-%m-%d")
end_date_timestamp = int(
utc_to_local((self.date + timedelta(days=self.search_range)), "UTC").timestamp()
)
# log.debug(url)
self._last_searched = f"<t:{date_timestamp}> to <t:{end_date_timestamp}>"

data = await self.api.get_schedule(self.team, date_str, end_date_str)
games = [game for date in data["dates"] for game in date["games"]]
team = None
if self.team:
team = self.team[0]
data = await self.api.get_schedule(team, date, end_date)
games = data.games
self.select_options = []
# log.debug(games)
for count, game in enumerate(games):
home_team = game["teams"]["home"]["team"]["name"]
home_team = game.home_team
home_abr = home_team
if home_team in TEAMS:
home_abr = TEAMS[home_team]["tri_code"]
away_team = game["teams"]["away"]["team"]["name"]
away_team = game.away_team
away_abr = away_team
if away_team in TEAMS:
away_abr = TEAMS[away_team]["tri_code"]
if self.vs and (home_team not in self.team or away_team not in self.team):
continue
date = utc_to_local(datetime.strptime(game["gameDate"], "%Y-%m-%dT%H:%M:%SZ"))
date = game.game_start
label = f"{away_abr}@{home_abr}-{date.year}-{date.month}-{date.day}"
description = f"{away_team} @ {home_team}"
emoji = None
Expand All @@ -234,7 +231,7 @@ async def _next_batch(
emoji = discord.PartialEmoji.from_str("\N{HOUSE BUILDING}")
self.select_options.append(
discord.SelectOption(
label=label, value=str(game["gamePk"]), description=description, emoji=emoji
label=label, value=str(game.id), description=description, emoji=emoji
)
)
if not games:
Expand Down Expand Up @@ -303,30 +300,31 @@ async def get_page(
self._last_page = page_number
return page

async def format_page(self, menu: menus.MenuPages, games: List[dict]) -> discord.Embed:
async def format_page(
self, menu: menus.MenuPages, games: List[ScheduledGame]
) -> discord.Embed:
states = {
"Preview": "\N{LARGE RED CIRCLE}",
"Live": "\N{LARGE GREEN CIRCLE}",
GameState.preview: "\N{LARGE RED CIRCLE}",
GameState.live: "\N{LARGE GREEN CIRCLE}",
"Intermission": "\N{LARGE YELLOW CIRCLE}",
"Final": "\N{CHEQUERED FLAG}",
GameState.final: "\N{CHEQUERED FLAG}",
}
# log.debug(games)
msg = humanize_list(self.team) + "\n"
day = None
start_time = None
for game in games:
game_start = datetime.strptime(game["gameDate"], "%Y-%m-%dT%H:%M:%SZ")
game_start = game_start.replace(tzinfo=timezone.utc)
home_team = game["teams"]["home"]["team"]["name"]
away_team = game["teams"]["away"]["team"]["name"]
game_start = game.game_start
home_team = game.home_team
away_team = game.away_team
home_emoji = discord.PartialEmoji.from_str("\N{HOUSE BUILDING}")
away_emoji = discord.PartialEmoji.from_str("\N{AIRPLANE}")
home_abr = home_team
away_abr = away_team
broadcast_str = ""
log.verbose("ScheduleList game: %s", game)
if "broadcasts" in game and self.show_broadcasts:
broadcasts = game["broadcasts"]
if game.broadcasts and self.show_broadcasts:
broadcasts = game.broadcasts
if broadcasts:
broadcast_str = (
"- "
Expand All @@ -341,9 +339,9 @@ async def format_page(self, menu: menus.MenuPages, games: List[dict]) -> discord
away_emoji = discord.PartialEmoji.from_str(TEAMS[away_team]["emoji"])
away_abr = TEAMS[away_team]["tri_code"]

postponed = game["status"]["detailedState"] == "Postponed"
postponed = game.schedule_state != "OK"
try:
game_state = states[game["status"]["abstractGameState"]]
game_state = states[game.game_state]
except KeyError:
game_state = "\N{LARGE RED CIRCLE}"
if start_time is None:
Expand All @@ -366,14 +364,18 @@ async def format_page(self, menu: menus.MenuPages, games: List[dict]) -> discord
f"{home_emoji} {home_abr} - {time_str}\n{broadcast_str}\n"
)
elif game_start < datetime.now(timezone.utc):
home_score = game["teams"]["home"]["score"]
away_score = game["teams"]["away"]["score"]
if self.get_recap:
game_recap = await Game.get_game_recap(game["gamePk"], session=self._session)
home_score = game.home_score
away_score = game.away_score
if not self.get_recap:
msg += (
f"[{game_state} - {away_emoji} {away_abr} **{away_score}** - "
f"**{home_score}** {home_emoji} {home_abr}]({game_recap}) \n{broadcast_str}\n"
f"{game_state} - {away_emoji} {away_abr} **{away_score}** - "
f"**{home_score}** {home_emoji} {home_abr} \n{broadcast_str}\n"
)
# game_recap = await Game.get_game_recap(game["gamePk"], session=self._session)
# msg += (
# f"[{game_state} - {away_emoji} {away_abr} **{away_score}** - "
# f"**{home_score}** {home_emoji} {home_abr}]({game_recap}) \n{broadcast_str}\n"
# )
else:
msg += (
f"{game_state} - {away_emoji} {away_abr} **{away_score}** - "
Expand Down Expand Up @@ -505,9 +507,19 @@ async def _next_batch(
utc_to_local((self.date + timedelta(days=days_to_check)), "UTC").timestamp()
)
self._last_searched = f"<t:{date_timestamp}> to <t:{end_date_timestamp}>"

data = await self.api.get_schedule(self.team, date_str, end_date_str)
games = [game for date in data["dates"] for game in date["games"]]
team = None
if self.team:
team = self.team[0]
data = await self.api.get_schedule(team, date, end_date)
days = data.days
if not days:
# log.debug("No schedule, looking for more days")
if self._checks < self.limit:
self._checks += 1
games = await self._next_batch(date=self.date, _next=_next, _prev=_prev)
else:
raise NoSchedule
games = days[0]
if not games:
# log.debug("No schedule, looking for more days")
if self._checks < self.limit:
Expand Down
Loading

0 comments on commit 6ee8ddf

Please sign in to comment.