Example #1
0
    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
Example #2
0
    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)
Example #3
0
    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)
Example #4
0
    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
Example #5
0
    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)
Example #6
0
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)