diff --git a/README.md b/README.md index a913bdb028..3803b8dce6 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ TrustyJAID's Cogs for [Red-DiscordBot](https://github.com/Cog-Creators/Red-Disc | ExtendedModLog | 2.12.3 |
ExtendedModLog, track changes made in the server.Log changes within the server using extended modlogs, an extension of RedBot cores modlog.
| RePulsR and TrustyJAID | | Fenrir | 1.2.0 |
Give users the option to kick, ban, or insult themselves via reactions.Create reaction messages to kick or ban users! https://tenor.com/view/order66-gif-9116581
| TrustyJAID | | Fun | 1.3.0 |
Various fun commands like react, textflip, and regionalAll sorts of commands that users may find fun or useful
| Appu and TrustyJAID | -| Hockey | 3.4.1 |
Hockey commandsA cog to gather hockey scores, schedules, player data and more!
| TrustyJAID | +| Hockey | 3.4.2 |
Hockey commandsA cog to gather hockey scores, schedules, player data and more!
| TrustyJAID | | Hue | 1.3.0 |
Control your philips hue lights with redbot!Lets you control your philips hue lights with redbot.
| TrustyJAID | | Imagemaker | 1.6.0 |
Create your own feels!Show how you really feel. Make someone beautiful. Make something illegal.
| TrustyJAID, Ivan Seidel (isnowillegal.com), Bruno Lemos (isnowillegal.com), and Joćo Pedro (isnowillegal.com) | | Imgflip | 3.0.0 |
Recreation of Red v1 meme generatorRecreation of Red v1 meme generator
| Twentysix and TrustyJAID | diff --git a/hockey/helper.py b/hockey/helper.py index c1f5643f45..1a2f76960c 100644 --- a/hockey/helper.py +++ b/hockey/helper.py @@ -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) diff --git a/hockey/hockey.py b/hockey/hockey.py index 80e1d73713..716870f335 100644 --- a/hockey/hockey.py +++ b/hockey/hockey.py @@ -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): diff --git a/hockey/hockeyset.py b/hockey/hockeyset.py index 58a7eec414..2cf7da0827 100644 --- a/hockey/hockeyset.py +++ b/hockey/hockeyset.py @@ -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 @@ -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): diff --git a/hockey/standings.py b/hockey/standings.py index deabe38f72..3915dc2cd1 100644 --- a/hockey/standings.py +++ b/hockey/standings.py @@ -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: