diff options
Diffstat (limited to '')
| -rw-r--r-- | bot/seasons/evergreen/fun.py | 103 | 
1 files changed, 84 insertions, 19 deletions
| diff --git a/bot/seasons/evergreen/fun.py b/bot/seasons/evergreen/fun.py index 87077f36..9fb338d3 100644 --- a/bot/seasons/evergreen/fun.py +++ b/bot/seasons/evergreen/fun.py @@ -1,6 +1,9 @@ +import functools  import logging  import random +from typing import Callable, Tuple, Union +from discord import Embed, Message  from discord.ext import commands  from discord.ext.commands import Bot, Cog, Context, MessageConverter @@ -13,6 +16,7 @@ UWU_WORDS = {      "fi": "fwi",      "l": "w",      "r": "w", +    "some": "sum",      "th": "d",      "thing": "fing",      "tho": "fo", @@ -43,38 +47,99 @@ class Fun(Cog):      @commands.command(name="uwu", aliases=("uwuwize", "uwuify",))      async def uwu_command(self, ctx: Context, *, text: str) -> None: -        """Converts a given `text` into it's uwu equivalent.""" -        text = await Fun.get_discord_message(ctx, text) -        converted = utils.replace_many(text, UWU_WORDS, ignore_case=True, match_case=True) -        await ctx.send(f">>> {converted}") +        """ +        Converts a given `text` into it's uwu equivalent. + +        Also accepts a valid discord Message ID or link. +        """ +        conversion_func = functools.partial( +            utils.replace_many, replacements=UWU_WORDS, ignore_case=True, match_case=True +        ) +        text, embed = await Fun._get_text_and_embed(ctx, text) +        # Convert embed if it exists +        if embed is not None: +            embed = Fun._convert_embed(conversion_func, embed) +        converted_text = conversion_func(text) +        # Don't put >>> if only embed present +        if converted_text: +            converted_text = f">>> {converted_text.lstrip('> ')}" +        await ctx.send(content=converted_text, embed=embed)      @commands.command(name="randomcase", aliases=("rcase", "randomcaps", "rcaps",))      async def randomcase_command(self, ctx: Context, *, text: str) -> None: -        """Randomly converts the casing of a given `text`.""" -        text = await Fun.get_discord_message(ctx, text) -        converted = ( -            char.upper() if round(random.random()) else char.lower() for char in text -        ) -        await ctx.send(f">>> {''.join(converted)}") +        """ +        Randomly converts the casing of a given `text`. + +        Also accepts a valid discord Message ID or link. +        """ +        def conversion_func(text): +            """Randomly converts the casing of a given string""" +            return "".join( +                char.upper() if round(random.random()) else char.lower() for char in text +            ) +        text, embed = await Fun._get_text_and_embed(ctx, text) +        # Convert embed if it exists +        if embed is not None: +            embed = Fun._convert_embed(conversion_func, embed) +        converted_text = conversion_func(text) +        # Don't put >>> if only embed present +        if converted_text: +            converted_text = f">>> {converted_text.lstrip('> ')}" +        await ctx.send(content=converted_text, embed=embed)      @staticmethod -    async def get_discord_message(ctx: Context, text: str) -> str: +    async def _get_text_and_embed(ctx: Context, text: str) -> Tuple[str, Union[Embed, None]]:          """ -        Attempts to convert a given `text` to a discord Message object, then return the contents. +        Attempts to extract the text and embed from a possible link to a discord Message. -        Useful if the user enters a link or an id to a valid Discord message, because the contents -        of the message get returned. +        Returns a tuple of: +            str: If `text` is a valid discord Message, the contents of the message, else `text`. +            Union[Embed, None]: The embed if found in the valid Message, else None +        """ +        embed = None +        message = await Fun._get_discord_message(ctx, text) +        if isinstance(message, Message): +            text = message.content +            # Take first embed because we can't send multiple embeds +            if message.embeds: +                embed = message.embeds[0] +        return (text, embed) +    @staticmethod +    async def _get_discord_message(ctx: Context, text: str) -> Union[Message, str]: +        """ +        Attempts to convert a given `text` to a discord Message object and return it. + +        Conversion will succeed if given a discord Message ID or link.          Returns `text` if the conversion fails.          """          try: -            message = await MessageConverter().convert(ctx, text) +            text = await MessageConverter().convert(ctx, text)          except commands.BadArgument:              log.debug(f"Input '{text:.20}...' is not a valid Discord Message") -        else: -            text = message.content -        finally: -            return text +        return text + +    @staticmethod +    def _convert_embed(func: Callable[[str, ], str], embed: Embed) -> Embed: +        """ +        Converts the text in an embed using a given conversion function, then return the embed. + +        Only modifies the following fields: title, description, footer, fields +        """ +        embed_dict = embed.to_dict() + +        embed_dict["title"] = func(embed_dict.get("title", "")) +        embed_dict["description"] = func(embed_dict.get("description", "")) + +        if "footer" in embed_dict: +            embed_dict["footer"]["text"] = func(embed_dict["footer"].get("text", "")) + +        if "fields" in embed_dict: +            for field in embed_dict["fields"]: +                field["name"] = func(field.get("name", "")) +                field["value"] = func(field.get("value", "")) + +        return Embed.from_dict(embed_dict)  def setup(bot) -> None: | 
