Skip to content

Commit

Permalink
[Hockey] 3.4.2 Create scheduled events for scheduled games!
Browse files Browse the repository at this point in the history
- Add new commands under `[p]hockeyevents` to setup scheduled events in a server for all games from a season for one team.
 - This process can take a while ~1 minute per 5 games.
- Fix division by zero errors in some standings data.
- Fix an issue where some names weren't correctly being filtered in areas causing unexpected results.
  • Loading branch information
TrustyJAID committed Oct 14, 2023
1 parent b6464f7 commit a5089c9
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 10 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ TrustyJAID's Cogs for [Red-DiscordBot](https://github.com/Cog-Creators/Red-Disc
| ExtendedModLog | 2.12.3 | <details><summary>ExtendedModLog, track changes made in the server.</summary>Log changes within the server using extended modlogs, an extension of RedBot cores modlog.</details> | RePulsR and TrustyJAID |
| Fenrir | 1.2.0 | <details><summary>Give users the option to kick, ban, or insult themselves via reactions.</summary>Create reaction messages to kick or ban users! https://tenor.com/view/order66-gif-9116581</details> | TrustyJAID |
| Fun | 1.3.0 | <details><summary>Various fun commands like react, textflip, and regional</summary>All sorts of commands that users may find fun or useful</details> | Appu and TrustyJAID |
| Hockey | 3.4.1 | <details><summary>Hockey commands</summary>A cog to gather hockey scores, schedules, player data and more!</details> | TrustyJAID |
| Hockey | 3.4.2 | <details><summary>Hockey commands</summary>A cog to gather hockey scores, schedules, player data and more!</details> | TrustyJAID |
| Hue | 1.3.0 | <details><summary>Control your philips hue lights with redbot!</summary>Lets you control your philips hue lights with redbot.</details> | TrustyJAID |
| Imagemaker | 1.6.0 | <details><summary>Create your own feels!</summary>Show how you really feel. Make someone beautiful. Make something illegal.</details> | TrustyJAID, Ivan Seidel (isnowillegal.com), Bruno Lemos (isnowillegal.com), and João Pedro (isnowillegal.com) |
| Imgflip | 3.0.0 | <details><summary>Recreation of Red v1 meme generator</summary>Recreation of Red v1 meme generator</details> | Twentysix and TrustyJAID |
Expand Down
13 changes: 8 additions & 5 deletions hockey/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,14 @@

TIMEZONE_RE = re.compile(r"|".join(re.escape(zone) for zone in pytz.common_timezones), flags=re.I)

ACTIVE_TEAM_RE_STR = r"|".join(
rf"{team}|{data['tri_code']}|{'|'.join(n for n in data['nickname'])}"
for team, data in TEAMS.items()
if data["active"]
)

ACTIVE_TEAM_RE_STR = r""
for team, data in TEAMS.items():
if not data["active"]:
continue
nicks = "|".join(f"\b{n}\b" for n in data["nickname"])
ACTIVE_TEAM_RE_STR += rf"\b{team}\b|\b{data['tri_code']}\b|{nicks}"

ACTIVE_TEAM_RE = re.compile(ACTIVE_TEAM_RE_STR, flags=re.I)

VERSUS_RE = re.compile(r"vs\.?|versus", flags=re.I)
Expand Down
2 changes: 1 addition & 1 deletion hockey/hockey.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class Hockey(
Gather information and post goal updates for NHL hockey teams
"""

__version__ = "3.4.1"
__version__ = "3.4.2"
__author__ = ["TrustyJAID"]

def __init__(self, bot):
Expand Down
106 changes: 105 additions & 1 deletion hockey/hockeyset.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import asyncio
import os
import re
from datetime import datetime, timedelta, timezone
from typing import Optional

import discord
from red_commons.logging import getLogger
from redbot.core import commands
from redbot.core.data_manager import cog_data_path
from redbot.core.i18n import Translator
from redbot.core.utils.chat_formatting import humanize_list

from .abc import HockeyMixin
from .constants import TEAMS
from .constants import BASE_URL, TEAMS
from .helper import StandingsFinder, StateFinder, TeamFinder
from .standings import Conferences, Divisions, Standings

Expand Down Expand Up @@ -111,6 +116,105 @@ async def hockey_slash(self, ctx: commands.Context):
"""
pass

@commands.group(name="hockeyevents", aliases=["nhlevents"])
@commands.bot_has_permissions(manage_events=True)
@commands.admin_or_permissions(manage_guild=True)
@commands.guild_only()
async def hockey_events(self, ctx: commands.Context):
"""
Commands for setting up discord guild events
"""

@hockey_events.command(name="set")
@commands.bot_has_permissions(manage_events=True)
@commands.admin_or_permissions(manage_guild=True)
@commands.guild_only()
@commands.max_concurrency(1, commands.BucketType.guild)
async def set_team_events(self, ctx: commands.Context, team: TeamFinder):
"""
Create a scheduled server event for all games in the season for one team.
This command can take a while to complete.
"""
url = f"{BASE_URL}/api/v1/schedule"
start = datetime.now()
end = start + timedelta(days=350)
params = {
"startDate": start.strftime("%Y-%m-%d"),
"endDate": end.strftime("%Y-%m-%d"),
"expand": "schedule.teams,schedule.linescore,schedule.broadcasts",
}
if team not in ["all", None]:
# if a team is provided get just that TEAMS data
params["teamId"] = ",".join(str(TEAMS[t]["id"]) for t in [team])
async with self.session.get(url, params=params) as resp:
data = await resp.json()
number_of_games = str(len(data.get("dates", [])))
await ctx.send(f"Creating events for {number_of_games} games.")
images_path = cog_data_path(self) / "teamlogos"
if not os.path.isdir(images_path):
os.mkdir(images_path)
existing_events = {}
for event in ctx.guild.scheduled_events:
event_id = re.search(r"\n(\d{6,})", event.description)
existing_events[event_id.group(1)] = event
for date in data["dates"]:
for game in date["games"]:
start = datetime.strptime(game["gameDate"], "%Y-%m-%dT%H:%M:%SZ").replace(
tzinfo=timezone.utc
)
end = start + timedelta(hours=3)
away = game["teams"]["away"]["team"]["name"]
home = game["teams"]["home"]["team"]["name"]
image_team = away if team == home else home
image_file = images_path / f"{image_team}.png"
if not os.path.isfile(image_file):
async with self.session.get(TEAMS[image_team]["logo"]) as resp:
image = await resp.read()
with image_file.open("wb") as outfile:
outfile.write(image)
image = open(image_file, "rb")
name = f"{away} @ {home}"
broadcasts = humanize_list(
[b.get("name", "Unknown") for b in game.get("broadcasts", [])]
)
description = name
if broadcasts:
description += f"\nBroadcasts: {broadcasts}"
game_id = str(game["gamePk"])
if game_id in existing_events:
try:
if existing_events[game_id].start_time != start:
await existing_events[game_id].edit(
start_time=start, end_time=end, reason="Start time changed"
)
if existing_events[game_id].description != description:
await existing_events[game_id].edit(
description=description, reason="Description has changed"
)
except Exception:
# I don't care if these don't edit properly
pass
continue
description += f"\n\n{game_id}"
try:
await ctx.guild.create_scheduled_event(
name=f"{away} @ {home}",
description=description,
start_time=start,
location=game.get("venue", {}).get("name", "Unknown place"),
end_time=end,
entity_type=discord.EntityType.external,
image=image.read(),
privacy_level=discord.PrivacyLevel.guild_only,
)
except Exception:
log.exception(
"Error creating scheduled event in %s for team %s", ctx.guild.id, team
)
image.close()
await asyncio.sleep(1)

@hockey_slash.command(name="global")
@commands.is_owner()
async def hockey_global_slash(self, ctx: commands.Context):
Expand Down
10 changes: 8 additions & 2 deletions hockey/standings.py
Original file line number Diff line number Diff line change
Expand Up @@ -423,11 +423,17 @@ def __str__(self) -> str:

@property
def gaa(self):
return self.goals_against / self.games_played
try:
return self.goals_against / self.games_played
except ZeroDivisionError:
return 0.0

@property
def gpg(self):
return self.goals_scored / self.games_played
try:
return self.goals_scored / self.games_played
except ZeroDivisionError:
return 0.0

@classmethod
def from_json(cls, data: dict, division: Division, conference: Conference) -> TeamRecord:
Expand Down

0 comments on commit a5089c9

Please sign in to comment.