diff options
| author | 2018-11-03 12:51:52 -0400 | |
|---|---|---|
| committer | 2018-11-03 12:51:52 -0400 | |
| commit | 73b64c7f875ee16d1187522840b3ae54619e7322 (patch) | |
| tree | 47a48918239ee7e3b958f3b4b9e6bb9547e8933e | |
| parent | Fixed eval to allow ```python in messages. (diff) | |
Add "superstarify" replacement for "hiphopify"
| -rw-r--r-- | bot/__main__.py | 2 | ||||
| -rw-r--r-- | bot/cogs/superstarify.py | 195 | ||||
| -rw-r--r-- | bot/constants.py | 2 | ||||
| -rw-r--r-- | config-default.yml | 2 | 
4 files changed, 198 insertions, 3 deletions
diff --git a/bot/__main__.py b/bot/__main__.py index f74b3545c..ab66492bb 100644 --- a/bot/__main__.py +++ b/bot/__main__.py @@ -61,7 +61,7 @@ bot.load_extension("bot.cogs.deployment")  bot.load_extension("bot.cogs.defcon")  bot.load_extension("bot.cogs.eval")  bot.load_extension("bot.cogs.fun") -bot.load_extension("bot.cogs.hiphopify") +bot.load_extension("bot.cogs.superstarify")  bot.load_extension("bot.cogs.information")  bot.load_extension("bot.cogs.moderation")  bot.load_extension("bot.cogs.off_topic_names") diff --git a/bot/cogs/superstarify.py b/bot/cogs/superstarify.py new file mode 100644 index 000000000..e1cfcc184 --- /dev/null +++ b/bot/cogs/superstarify.py @@ -0,0 +1,195 @@ +import logging +import random + +from discord import Colour, Embed, Member +from discord.errors import Forbidden +from discord.ext.commands import Bot, Context, command + +from bot.constants import ( +    Channels, Keys, +    NEGATIVE_REPLIES, POSITIVE_REPLIES, +    Roles, URLs +) +from bot.decorators import with_role + + +log = logging.getLogger(__name__) + + +class Superstarify: +    """ +    A set of commands to moderate terrible nicknames. +    """ + +    def __init__(self, bot: Bot): +        self.bot = bot +        self.headers = {"X-API-KEY": Keys.site_api} + +    async def on_member_update(self, before, after): +        """ +        This event will trigger when someone changes their name. +        At this point we will look up the user in our database and check +        whether they are allowed to change their names, or if they are in +        superstar-prison. If they are not allowed, we will change it back. +        :return: +        """ + +        if before.display_name == after.display_name: +            return  # User didn't change their nickname. Abort! + +        log.debug( +            f"{before.display_name} is trying to change their nickname to {after.display_name}. " +            "Checking if the user is in superstar-prison..." +        ) + +        response = await self.bot.http_session.get( +            URLs.site_superstarify_api, +            headers=self.headers, +            params={"user_id": str(before.id)} +        ) + +        response = await response.json() + +        if response and response.get("end_timestamp") and not response.get("error_code"): +            if after.display_name == response.get("forced_nick"): +                return  # Nick change was triggered by this event. Ignore. + +            log.debug( +                f"{after.display_name} is currently in superstar-prison. " +                f"Changing the nick back to {before.display_name}." +            ) +            await after.edit(nick=response.get("forced_nick")) +            try: +                await after.send( +                    "You have tried to change your nickname on the **Python Discord** server " +                    f"from **{before.display_name}** to **{after.display_name}**, but as you " +                    "are currently in superstar-prison, you do not have permission to do so. " +                    "You will be allowed to change your nickname again at the following time:\n\n" +                    f"**{response.get('end_timestamp')}**." +                ) +            except Forbidden: +                log.warning( +                    "The user tried to change their nickname while in superstar-prison. " +                    "This led to the bot trying to DM the user to let them know they cannot do that, " +                    "but the user had either blocked the bot or disabled DMs, so it was not possible " +                    "to DM them, and a discord.errors.Forbidden error was incurred." +                ) + +    @command(name='superstarify', aliases=('force_nick', 'ss')) +    @with_role(Roles.admin, Roles.owner, Roles.moderator) +    async def superstarify(self, ctx: Context, member: Member, duration: str, *, forced_nick: str = None): +        """ +        This command will force a random superstar name (like Taylor Swift) to be the user's +        nickname for a specified duration. If a forced_nick is provided, it will use that instead. + +        :param ctx: Discord message context +        :param ta: +        If provided, this function shows data for that specific tag. +        If not provided, this function shows the caller a list of all tags. +        """ + +        log.debug( +            f"Attempting to superstarify {member.display_name} for {duration}. " +            f"forced_nick is set to {forced_nick}." +        ) + +        embed = Embed() +        embed.colour = Colour.blurple() + +        params = { +            "user_id": str(member.id), +            "duration": duration +        } + +        if forced_nick: +            params["forced_nick"] = forced_nick + +        response = await self.bot.http_session.post( +            URLs.site_superstarify_api, +            headers=self.headers, +            json=params +        ) + +        response = await response.json() + +        if "error_message" in response: +            log.warning( +                "Encountered the following error when trying to superstarify the user:\n" +                f"{response.get('error_message')}" +            ) +            embed.colour = Colour.red() +            embed.title = random.choice(NEGATIVE_REPLIES) +            embed.description = response.get("error_message") +            return await ctx.send(embed=embed) + +        else: +            forced_nick = response.get('forced_nick') +            end_time = response.get("end_timestamp") +            image_url = response.get("image_url") + +            embed.title = "Congratulations!" +            embed.description = ( +                f"Your previous nickname, **{member.display_name}**, was so bad that we have decided to change it. " +                f"Your new nickname will be **{forced_nick}**.\n\n" +                f"You will be unable to change your nickname until \n**{end_time}**.\n\n" +                "If you're confused by this, please read our " +                "[official nickname policy](https://pythondiscord.com/about/rules#nickname-policy)." +            ) +            embed.set_image(url=image_url) + +            # Log to the mod_log channel +            log.trace("Logging to the #mod-log channel. This could fail because of channel permissions.") +            mod_log = self.bot.get_channel(Channels.modlog) +            await mod_log.send( +                f":middle_finger: {member.name}#{member.discriminator} (`{member.id}`) " +                f"has been superstarified by **{ctx.author.name}**. Their new nickname is `{forced_nick}`. " +                f"They will not be able to change their nickname again until **{end_time}**" +            ) + +            # Change the nick and return the embed +            log.debug("Changing the users nickname and sending the embed.") +            await member.edit(nick=forced_nick) +            await ctx.send(embed=embed) + +    @command(name='unsuperstarify', aliases=('release_nick', 'uss')) +    @with_role(Roles.admin, Roles.owner, Roles.moderator) +    async def unsuperstarify(self, ctx: Context, member: Member): +        """ +        This command will remove the entry from our database, allowing the user +        to once again change their nickname. + +        :param ctx: Discord message context +        :param member: The member to unsuperstarify +        """ + +        log.debug(f"Attempting to unsuperstarify the following user: {member.display_name}") + +        embed = Embed() +        embed.colour = Colour.blurple() + +        response = await self.bot.http_session.delete( +            URLs.site_superstarify_api, +            headers=self.headers, +            json={"user_id": str(member.id)} +        ) + +        response = await response.json() +        embed.description = "User has been released from superstar-prison." +        embed.title = random.choice(POSITIVE_REPLIES) + +        if "error_message" in response: +            embed.colour = Colour.red() +            embed.title = random.choice(NEGATIVE_REPLIES) +            embed.description = response.get("error_message") +            log.warning( +                f"Error encountered when trying to unsuperstarify {member.display_name}:\n" +                f"{response}" +            ) + +        log.debug(f"{member.display_name} was successfully released from superstar-prison.") +        await ctx.send(embed=embed) + + +def setup(bot): +    bot.add_cog(Superstarify(bot)) +    log.info("Cog loaded: Superstarify") diff --git a/bot/constants.py b/bot/constants.py index 145dc4700..43f03d7bf 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -395,7 +395,7 @@ class URLs(metaclass=YAMLGetter):      site_api: str      site_facts_api: str      site_clean_api: str -    site_hiphopify_api: str +    site_superstarify_api: str      site_idioms_api: str      site_logs_api: str      site_logs_view: str diff --git a/config-default.yml b/config-default.yml index 15f1a143a..046c1ea56 100644 --- a/config-default.yml +++ b/config-default.yml @@ -218,7 +218,7 @@ urls:      site_bigbrother_api:                !JOIN [*SCHEMA, *API, "/bot/bigbrother"]      site_docs_api:                      !JOIN [*SCHEMA, *API, "/bot/docs"]      site_facts_api:                     !JOIN [*SCHEMA, *API, "/bot/snake_facts"] -    site_hiphopify_api:                 !JOIN [*SCHEMA, *API, "/bot/hiphopify"] +    site_superstarify_api:              !JOIN [*SCHEMA, *API, "/bot/superstarify"]      site_idioms_api:                    !JOIN [*SCHEMA, *API, "/bot/snake_idioms"]      site_infractions:                   !JOIN [*SCHEMA, *API, "/bot/infractions"]      site_infractions_user:              !JOIN [*SCHEMA, *API, "/bot/infractions/user/{user_id}"]  |