Skip to content

Commit

Permalink
[Hockey] Fix detection of Overtime and Shootout periods
Browse files Browse the repository at this point in the history
- Add situation checks for shootout
- Add missing event type to goals
- Reorganize description construction for goals so there shouldn't be a trailing comma
- Fix poststandings command to use the new API
- Add commit info to version command
  • Loading branch information
TrustyJAID committed Nov 29, 2023
1 parent 9fdf803 commit 5e889e8
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 22 deletions.
64 changes: 57 additions & 7 deletions hockey/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@ class GameEventTypeCode(Enum):
DELAYED_PENALTY = 535
FAILED_SHOT_ATTEMPT = 537

def __str__(self):
return self.name.title().replace("_", " ")


class Situation:
def __init__(self, code: str):
Expand Down Expand Up @@ -140,9 +143,13 @@ def strength(self, home: bool) -> str:
if self.home_skaters == self.away_skaters == 3:
return _("3v3")
if home and self.home_skaters > self.away_skaters:
if self.away_skaters == 0:
return _("Shootout")
return _("Power Play")
if not home and self.home_skaters > self.away_skaters:
return _("Shorthanded Goal")
if self.away_skaters == 0:
return _("Shootout")
return _("Shorthanded")

def empty_net(self, home: bool) -> str:
"""
Expand All @@ -158,6 +165,35 @@ def empty_net(self, home: bool) -> str:
return ""


@dataclass
class Player:
teamId: int
playerId: int
firstName: dict
lastName: dict
sweaterNumber: int
positionCode: str
headshot: str

@property
def name(self) -> str:
first = self.firstName.get("default", _("Unknown"))
last = self.lastName.get("default", _("Unknown"))
return f"{first} {last}"

@classmethod
def from_json(cls, data: dict) -> Player:
return cls(
teamId=data.get("teamId"),
playerId=data.get("playerId"),
firstName=data.get("firstName"),
lastName=data.get("lastName"),
sweaterNumber=data.get("sweaterNumber", 0),
positionCode=data.get("positionCode"),
headshot=data.get("headshot"),
)


@dataclass
class Event:
id: int
Expand Down Expand Up @@ -211,22 +247,22 @@ def description(self, data: dict) -> str:
first_name = player.get("firstName", {}).get("default", "")
last_name = player.get("lastName", {}).get("default", "")
total = self.details.get("scoringPlayerTotal", 0)
description += f"{first_name} {last_name} ({total}) {shot_type}, "
description += f"{first_name} {last_name} ({total}) {shot_type}"

if key == "assist1PlayerId":
player = self.get_player(value, data)
first_name = player.get("firstName", {}).get("default", "")
last_name = player.get("lastName", {}).get("default", "")
total = self.details.get("assist1PlayerTotal", 0)
description += _("assists: {first_name} {last_name} ({total}), ").format(
description += _(" assists: {first_name} {last_name} ({total})").format(
first_name=first_name, last_name=last_name, total=total
)
if key == "assist2PlayerId":
player = self.get_player(value, data)
first_name = player.get("firstName", {}).get("default", "")
last_name = player.get("lastName", {}).get("default", "")
total = self.details.get("assist1PlayerTotal", 0)
description += _("{first_name} {last_name} ({total})").format(
description += _(", {first_name} {last_name} ({total})").format(
first_name=first_name, last_name=last_name, total=total
)

Expand Down Expand Up @@ -273,7 +309,7 @@ def to_goal(self, data: dict, content: Optional[dict] = None) -> Goal:
strength=self.situation.strength(home),
strength_code=self.situation.code,
empty_net=self.situation.empty_net(home),
event="",
event=str(self.type_code),
link=self.get_highlight(content),
)

Expand Down Expand Up @@ -366,6 +402,9 @@ async def close(self):
async def get_game_content(self, game_id: int):
raise NotImplementedError()

async def get_standings(self) -> Standings:
raise NotImplementedError

async def get_schedule(
self,
team: Optional[str] = None,
Expand Down Expand Up @@ -915,14 +954,25 @@ async def to_game(self, data: dict, content: Optional[dict] = None) -> Game:
game_start = data["startTimeUTC"]

period_ord = ORDINALS.get(period, "")
period_descriptor = data.get("periodDescriptor", {}).get("periodType", "REG")
if period_descriptor != "REG":
period_ord = period_descriptor
events = [Event.from_json(i) for i in data["plays"]]
goals = [
e.to_goal(data, content=content)
for e in events
if e.type_code is GameEventTypeCode.GOAL
]
home_roster = [p for p in data["rosterSpots"] if p["teamId"] == home_id]
away_roster = [p for p in data["rosterSpots"] if p["teamId"] == away_id]
home_roster = {
p["playerId"]: Player.from_json(p)
for p in data["rosterSpots"]
if p["teamId"] == home_id
}
away_roster = {
p["playerId"]: Player.from_json(p)
for p in data["rosterSpots"]
if p["teamId"] == away_id
}
game_type = GameType.from_int(data["gameType"])
first_star = None
second_star = None
Expand Down
10 changes: 5 additions & 5 deletions hockey/game.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from .standings import LeagueRecord, Playoffs

if TYPE_CHECKING:
from .api import GameData
from .api import GameData, Player

_ = Translator("Hockey", __file__)

Expand Down Expand Up @@ -263,8 +263,8 @@ class Game:
first_star: Optional[str]
second_star: Optional[str]
third_star: Optional[str]
away_roster: Optional[dict]
home_roster: Optional[dict]
away_roster: Dict[int, Player]
home_roster: Dict[int, Player]
link: Optional[str]

def __init__(self, **kwargs):
Expand Down Expand Up @@ -313,8 +313,8 @@ def __init__(self, **kwargs):
self.first_star = kwargs.get("first_star")
self.second_star = kwargs.get("second_star")
self.third_star = kwargs.get("third_star")
self.away_roster = kwargs.get("away_roster")
self.home_roster = kwargs.get("home_roster")
self.away_roster = kwargs.get("away_roster", {})
self.home_roster = kwargs.get("home_roster", {})
self.game_type: GameType = kwargs.get("game_type", GameType.unknown)
self.link = kwargs.get("link")
self.season = kwargs.get("season")
Expand Down
11 changes: 5 additions & 6 deletions hockey/goal.py
Original file line number Diff line number Diff line change
Expand Up @@ -458,15 +458,14 @@ async def get_shootout_display(self, game: Game) -> Tuple[str, str]:
away_msg = ""
score = "☑ {scorer}\n"
miss = "❌ {scorer}\n"
players = game.home_roster
players.update(game.away_roster)

for goal in game.home_goals:
scorer = ""
scorer_num = ""
if goal.time > self.time:
break
if f"ID{goal.scorer_id}" in players:
scorer = players[f"ID{goal.scorer_id}"]["person"]["fullName"]
if goal.scorer_id in game.home_roster:
scorer = game.home_roster[goal.scorer_id].name
if goal.event in ["Shot", "Missed Shot"] and goal.period_ord == "SO":
home_msg += miss.format(scorer=scorer)
if goal.event in ["Goal"] and goal.period_ord == "SO":
Expand All @@ -479,8 +478,8 @@ async def get_shootout_display(self, game: Game) -> Tuple[str, str]:
# is in the shootout and we reach a goal that happened *after*
# this goal object, we break for a cleaner looking shootout display.
break
if f"ID{goal.scorer_id}" in players:
scorer = players[f"ID{goal.scorer_id}"]["person"]["fullName"]
if goal.scorer_id in game.away_roster:
scorer = game.away_roster[goal.scorer_id].name
if goal.event in ["Shot", "Missed Shot"] and goal.period_ord == "SO":
away_msg += miss.format(scorer=scorer)
if goal.event in ["Goal"] and goal.period_ord == "SO":
Expand Down
5 changes: 4 additions & 1 deletion hockey/hockey_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@ async def version(self, ctx: commands.Context) -> None:
"""
Display the current version
"""
await ctx.send(_("Hockey version ") + self.__version__)
ret = _("Hockey version ") + self.__version__
if self._commit:
ret += f"\n- Commit: [{self._commit[:9]}]({self._repo}/tree/{self._commit})"
await ctx.send(ret)

@commands.command()
async def hockeyhub(self, ctx: commands.Context, *, search: str) -> None:
Expand Down
2 changes: 1 addition & 1 deletion hockey/hockeyset.py
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,7 @@ async def post_standings(
await ctx.send(msg)
return
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
4 changes: 2 additions & 2 deletions hockey/pickems.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,9 +194,9 @@ def add_vote(self, user_id: int, team: discord.Emoji) -> None:
time_now = datetime.now(timezone.utc)

team_choice = None
if str(team.id) in self.home_emoji:
if str(team.id) in str(self.home_emoji):
team_choice = self.home_team
if str(team.id) in self.away_emoji:
if str(team.id) in str(self.away_emoji):
team_choice = self.away_team
if team_choice is None:
raise NotAValidTeamError()
Expand Down

0 comments on commit 5e889e8

Please sign in to comment.