async def check_team_goals(self, bot: Red) -> None: """ Checks to see if a goal needs to be posted """ team_data = { self.home_team: await get_team(bot, self.home_team), self.away_team: await get_team(bot, self.away_team), } # home_team_data = await get_team(bot, self.home_team) # away_team_data = await get_team(bot, self.away_team) # all_data = await get_team("all") team_list = await bot.get_cog("Hockey").config.teams() # post_state = ["all", self.home_team, self.away_team] # home_goal_ids = [goal.goal_id for goal in self.home_goals] # away_goal_ids = [goal.goal_id for goal in self.away_goals] home_goal_list = list(team_data[self.home_team]["goal_id"]) away_goal_list = list(team_data[self.away_team]["goal_id"]) for goal in self.goals: # goal_id = str(goal["result"]["eventCode"]) # team = goal["team"]["name"] # team_data = await get_team(bot, goal.team_name) if goal.goal_id not in team_data[goal.team_name]["goal_id"]: # attempts to post the goal if there is a new goal bot.dispatch("hockey_goal", self, goal) goal.home_shots = self.home_shots goal.away_shots = self.away_shots msg_list = await goal.post_team_goal(bot, self) team_list.remove(team_data[goal.team_name]) team_data[goal.team_name]["goal_id"][goal.goal_id] = { "goal": goal.to_json(), "messages": msg_list, } team_list.append(team_data[goal.team_name]) await bot.get_cog("Hockey").config.teams.set(team_list) continue if goal.goal_id in team_data[goal.team_name]["goal_id"]: # attempts to edit the goal if the scorers have changed old_goal = Goal(**team_data[goal.team_name]["goal_id"][goal.goal_id]["goal"]) if goal.description != old_goal.description or goal.link != old_goal.link: goal.home_shots = old_goal.home_shots goal.away_shots = old_goal.away_shots # This is to keep shots consistent between edits # Shots should not update as the game continues bot.dispatch("hockey_goal_edit", self, goal) old_msgs = team_data[goal.team_name]["goal_id"][goal.goal_id]["messages"] team_list.remove(team_data[goal.team_name]) team_data[goal.team_name]["goal_id"][goal.goal_id]["goal"] = goal.to_json() team_list.append(team_data[goal.team_name]) await bot.get_cog("Hockey").config.teams.set(team_list) await goal.edit_team_goal(bot, self, old_msgs) # attempts to delete the goal if it was called back for goal_str in home_goal_list: await Goal.remove_goal_post(bot, goal_str, self.home_team, self) for goal_str in away_goal_list: await Goal.remove_goal_post(bot, goal_str, self.away_team, self)
async def post_game_state(self, bot: Red) -> None: """ When a game state has changed this is called to create the embed and post in all channels """ post_state = ["all", self.home_team, self.away_team] state_embed = await self.game_state_embed() state_text = await self.game_state_text() tasks = [] all_channels = await bot.get_cog("Hockey").config.all_channels() async for channel_id, data in AsyncIter(all_channels.items(), steps=100): channel = await get_channel_obj(bot, channel_id, data) if not channel: continue should_post = await check_to_post(bot, channel, data, post_state, self.game_state) if should_post: tasks.append(self.actually_post_state(bot, channel, state_embed, state_text)) previews = await bounded_gather(*tasks) for preview in previews: if preview is None: continue else: bot.dispatch("hockey_preview_message", preview[0], preview[1], self)
async def actually_post_state( self, bot: Red, channel: discord.TextChannel, state_embed: discord.Embed, state_text: str ) -> Optional[Tuple[discord.TextChannel, discord.Message]]: guild = channel.guild if not channel.permissions_for(guild.me).send_messages: log.debug("No permission to send messages in %s", repr(channel)) return None config = bot.get_cog("Hockey").config guild_settings = await config.guild(guild).all() channel_settings = await config.channel(channel).all() game_day_channels = guild_settings["gdc"] can_embed = channel.permissions_for(guild.me).embed_links publish_states = [] # await config.channel(channel).publish_states() # can_manage_webhooks = False # channel.permissions_for(guild.me).manage_webhooks if self.game_state == "Live": guild_notifications = guild_settings["game_state_notifications"] channel_notifications = channel_settings["game_state_notifications"] state_notifications = guild_notifications or channel_notifications # TODO: Something with these I can't remember what now # guild_start = guild_settings["start_notifications"] # channel_start = channel_settings["start_notifications"] # start_notifications = guild_start or channel_start # heh inclusive or allowed_mentions = {} home_role, away_role = await get_team_role(guild, self.home_team, self.away_team) if version_info >= VersionInfo.from_str("3.4.0"): if state_notifications: allowed_mentions = {"allowed_mentions": discord.AllowedMentions(roles=True)} else: allowed_mentions = {"allowed_mentions": discord.AllowedMentions(roles=False)} if self.game_type == "R" and "OT" in self.period_ord: if not guild_settings["ot_notifications"]: if version_info >= VersionInfo.from_str("3.4.0"): allowed_mentions = { "allowed_mentions": discord.AllowedMentions(roles=False) } else: allowed_mentions = {} if "SO" in self.period_ord: if not guild_settings["so_notifications"]: if version_info >= VersionInfo.from_str("3.4.0"): allowed_mentions = { "allowed_mentions": discord.AllowedMentions(roles=False) } else: allowed_mentions = {} if game_day_channels is not None: # We don't want to ping people in the game day channels twice if channel.id in game_day_channels: home_role, away_role = self.home_team, self.away_team msg = _("**{period} Period starting {away_role} at {home_role}**").format( period=self.period_ord, away_role=away_role, home_role=home_role ) try: if not can_embed: msg = await channel.send(msg + "\n{}".format(state_text), **allowed_mentions) else: msg = await channel.send(msg, embed=state_embed, **allowed_mentions) if self.game_state in publish_states: try: if channel.is_news(): # allows backwards compatibility still # await msg.publish() pass except Exception: pass except Exception: log.exception("Could not post goal in %s", repr(channel)) else: if self.game_state == "Preview": if game_day_channels is not None: # Don't post the preview message twice in the channel if channel.id in game_day_channels: return None try: if not can_embed: preview_msg = await channel.send(state_text) else: preview_msg = await channel.send(embed=state_embed) if self.game_state in publish_states: try: if channel.is_news(): # allows backwards compatibility still # await preview_msg.publish() pass except Exception: pass # Create new pickems object for the game if self.game_state == "Preview": bot.dispatch("hockey_preview_message", channel, preview_msg, self) if channel.permissions_for(guild.me).add_reactions: try: await preview_msg.add_reaction(self.away_emoji[2:-1]) await preview_msg.add_reaction(self.home_emoji[2:-1]) except Exception: log.debug("Could not add reactions") return channel, preview_msg except Exception: log.exception("Could not post goal in %s", repr(channel)) return None
async def check_game_state(self, bot: Red, count: int = 0) -> bool: # post_state = ["all", self.home_team, self.away_team] home = await get_team(bot, self.home_team) # away = await get_team(self.away_team) # team_list = await self.config.teams() # Home team checking end_first = self.period_time_left == "END" and self.period == 1 end_second = self.period_time_left == "END" and self.period == 2 end_third = self.period_time_left == "END" and self.period == 3 if self.game_state == "Preview": """Checks if the the game state has changes from Final to Preview Could be unnecessary since after Game Final it will check for next game """ time_now = datetime.now(tz=timezone.utc) # game_time = datetime.strptime(data.game_start, "%Y-%m-%dT%H:%M:%SZ") game_start = (self.game_start - time_now).total_seconds() / 60 if "Preview" not in home["game_state"]: await self.post_game_state(bot) await self.save_game_state(bot) bot.dispatch("hockey_preview", self) if game_start < 60 and game_start > 30 and home["game_state"] != "Preview60": # Post 60 minutes until game start await self.post_time_to_game_start(bot, "60") await self.save_game_state(bot, "60") bot.dispatch("hockey_preview", self) if game_start < 30 and game_start > 10 and home["game_state"] != "Preview30": # Post 30 minutes until game start await self.post_time_to_game_start(bot, "30") await self.save_game_state(bot, "30") bot.dispatch("hockey_preview", self) if game_start < 10 and game_start > 0 and home["game_state"] != "Preview10": # Post 10 minutes until game start await self.post_time_to_game_start(bot, "10") await self.save_game_state(bot, "10") bot.dispatch("hockey_preview", self) # Create channel and look for game day thread if self.game_state == "Live": # Checks what the period is and posts the game is starting in the appropriate channel if home["period"] != self.period or "Preview" in home["game_state"]: log.debug( "**%s Period starting %s at %s**", self.period_ord, self.away_team, self.home_team, ) await self.post_game_state(bot) await self.save_game_state(bot) bot.dispatch("hockey_period_start", self) if (self.home_score + self.away_score) != 0: # Check if there's goals only if there are goals await self.check_team_goals(bot) if end_first and home["game_state"] != "LiveEND1st": log.debug("End of the first period") await self.period_recap(bot, "1st") await self.save_game_state(bot, "END1st") if end_second and home["game_state"] != "LiveEND2nd": log.debug("End of the second period") await self.period_recap(bot, "2nd") await self.save_game_state(bot, "END2nd") if end_third and home["game_state"] not in ["LiveEND3rd", "FinalEND3rd"]: log.debug("End of the third period") await self.period_recap(bot, "3rd") await self.save_game_state(bot, "END3rd") if self.game_state == "Final": if end_third and home["game_state"] not in ["LiveEND3rd", "FinalEND3rd"]: log.debug("End of the third period") await self.period_recap(bot, "3rd") await self.save_game_state(bot, "END3rd") if self.game_state == "Final" and (self.first_star is not None or count >= 10): """Final game state checks""" if (self.home_score + self.away_score) != 0: # Check for goal before posting game final, happens with OT games await self.check_team_goals(bot) log.debug("Checking team goals for the last time") if home["game_state"] != self.game_state and home["game_state"] != "Null": # Post game final data and check for next game log.debug("Game Final %s @ %s", self.away_team, self.home_team) await self.post_game_state(bot) await self.save_game_state(bot) bot.dispatch("hockey_final", self) log.debug("Saving final") return True return False