async def apply_server_icon(self) -> bool: """ Applies the server icon for the current season. Returns True if was successful. """ guild = bot.get_guild(Client.guild) # Track old icon hash for later comparison old_icon = guild.icon # Attempt the change icon, name = await self.get_icon(index=self.index) log.debug(f"Changing server icon to {name}") with contextlib.suppress(discord.HTTPException, asyncio.TimeoutError): async with async_timeout.timeout(5): await guild.edit( icon=icon, reason=f"Seasonbot Season Change: {self.name}") new_icon = bot.get_guild(Client.guild).icon if new_icon != old_icon: log.debug(f"Server icon changed to {name}") return True log.warning(f"Changing server icon failed: {name}") return False
async def announce_season(self) -> None: """ Announces a change in season in the announcement channel. Auto-announcement is configured by the `should_announce` `SeasonBase` attribute """ # Short circuit if the season had disabled automatic announcements if not self.should_announce: log.debug(f"Season changed without announcement: {self.name}") return guild = bot.get_guild(Client.guild) channel = guild.get_channel(Channels.announcements) mention = f"<@&{Roles.announcements}>" # Build cog info output doc = inspect.getdoc(self) announce = "\n\n".join(l.replace("\n", " ") for l in doc.split("\n\n")) # No announcement message found if not doc: return embed = discord.Embed(description=f"{announce}\n\n", colour=self.colour or guild.me.colour) embed.set_author(name=self.greeting) if self.icon: embed.set_image(url=ICON_BASE_URL + self.icon[0]) # Find any seasonal commands cogs = [] for cog in bot.cogs.values(): if "evergreen" in cog.__module__: continue cog_name = type(cog).__name__ if cog_name != "SeasonManager": cogs.append(cog_name) if cogs: def cog_name(cog: commands.Cog) -> str: return type(cog).__name__ cog_info = [] for cog in sorted(cogs, key=cog_name): doc = inspect.getdoc(bot.get_cog(cog)) if doc: cog_info.append(f"**{cog}**\n*{doc}*") else: cog_info.append(f"**{cog}**") cogs_text = "\n".join(cog_info) embed.add_field(name="New Command Categories", value=cogs_text) embed.set_footer( text="To see the new commands, use .help Category") await channel.send(mention, embed=embed)
async def announce_season(self) -> None: """ Announces a change in season in the announcement channel. It will skip the announcement if the current active season is the "evergreen" default season. """ # Don't actually announce if reverting to normal season if self.name in ("evergreen", "wildcard"): log.debug(f"Season Changed: {self.name}") return guild = bot.get_guild(Client.guild) channel = guild.get_channel(Channels.announcements) mention = f"<@&{Roles.announcements}>" # Build cog info output doc = inspect.getdoc(self) announce = "\n\n".join(l.replace("\n", " ") for l in doc.split("\n\n")) # No announcement message found if not doc: return embed = discord.Embed(description=f"{announce}\n\n", colour=self.colour or guild.me.colour) embed.set_author(name=self.greeting) if self.icon: embed.set_image(url=ICON_BASE_URL + self.icon[0]) # Find any seasonal commands cogs = [] for cog in bot.cogs.values(): if "evergreen" in cog.__module__: continue cog_name = type(cog).__name__ if cog_name != "SeasonManager": cogs.append(cog_name) if cogs: def cog_name(cog): return type(cog).__name__ cog_info = [] for cog in sorted(cogs, key=cog_name): doc = inspect.getdoc(bot.get_cog(cog)) if doc: cog_info.append(f"**{cog}**\n*{doc}*") else: cog_info.append(f"**{cog}**") cogs_text = "\n".join(cog_info) embed.add_field(name="New Command Categories", value=cogs_text) embed.set_footer( text="To see the new commands, use .help Category") await channel.send(mention, embed=embed)
async def apply_username(self, *, debug: bool = False) -> Union[bool, None]: """ Applies the username for the current season. Only changes nickname if `bool` is False, otherwise only changes the nickname. Returns True if it successfully changed the username. Returns False if it failed to change the username, falling back to nick. Returns None if `debug` was True and username change wasn't attempted. """ guild = bot.get_guild(Client.guild) result = None # Change only nickname if in debug mode due to ratelimits for user edits if debug: if guild.me.display_name != self.bot_name: log.debug(f"Changing nickname to {self.bot_name}") await guild.me.edit(nick=self.bot_name) else: if bot.user.name != self.bot_name: # Attempt to change user details log.debug(f"Changing username to {self.bot_name}") with contextlib.suppress(discord.HTTPException): await bot.user.edit(username=self.bot_name) # Fallback on nickname if failed due to ratelimit if bot.user.name != self.bot_name: log.warning( f"Username failed to change: Changing nickname to {self.bot_name}" ) await guild.me.edit(nick=self.bot_name) result = False else: result = True # Remove nickname if an old one exists if guild.me.nick and guild.me.nick != self.bot_name: log.debug(f"Clearing old nickname of {guild.me.nick}") await guild.me.edit(nick=None) return result
async def refresh_server_icon(self, ctx: commands.Context) -> None: """Re-applies the server icon for the currently loaded season.""" # Attempt the change is_changed = await self.season.apply_server_icon() if is_changed: colour = ctx.guild.me.colour title = "Server Icon Refreshed" else: colour = discord.Colour.red() title = "Server Icon Failed to Refresh" # Report back details season_name = type(self.season).__name__ embed = discord.Embed( description=f"**Season:** {season_name}\n**Icon:** {self.season.icon}", colour=colour ) embed.set_author(name=title) embed.set_thumbnail(url=bot.get_guild(Client.guild).icon_url_as(format="png")) await ctx.send(embed=embed)
from bot.constants import Channels, Client, Roles as MainRoles from bot.decorators import with_role from .constants import Colours, EggHuntSettings, Emoji, Roles log = logging.getLogger(__name__) DB_PATH = Path("bot/resources/persist/egg_hunt.sqlite") TEAM_MAP = { Roles.white: Emoji.egg_white, Roles.blurple: Emoji.egg_blurple, Emoji.egg_white: Roles.white, Emoji.egg_blurple: Roles.blurple } GUILD = bot.get_guild(Client.guild) MUTED = GUILD.get_role(MainRoles.muted) def get_team_role(user: discord.Member) -> discord.Role: """Helper function to get the team role for a member.""" if Roles.white in user.roles: return Roles.white if Roles.blurple in user.roles: return Roles.blurple async def assign_team(user: discord.Member) -> discord.Member: """Helper function to assign a new team role for a member.""" db = sqlite3.connect(DB_PATH)