Example #1
0
    async def jumbo(self, ctx, emojis: commands.Greedy[discord.PartialEmoji]):
        """
        Return an emoji's full-size image.

        :param ctx: context
        :param emojis: an emoji or list of emojis to get the image for
        :return: N/A
        """

        # no emojis provided
        if len(emojis) == 0:
            raise CustomCommandError(
                "You need to input at least one custom emoji.")
        elif len(emojis) > 3:
            raise CustomCommandError("This command is limited to 3 emojis.")

        # embed
        embed = discord.Embed(colour=Colours.success)

        for emoji in emojis:
            # add image
            embed.set_image(url=emoji.url)

            # send embed
            await ctx.message.channel.send(embed=embed)
Example #2
0
    async def delete_emoji(self, ctx,
                           emojis_to_delete: commands.Greedy[discord.Emoji]):
        """
        Delete an emoji, or a list of emojis. Requires text confirmation.

        :param ctx: context
        :param emojis_to_delete: a list of emojis to be deleted
        :return: N/A
        """

        # no emojis provided
        if len(emojis_to_delete) == 0:
            raise CustomCommandError(
                "You need to add at least one emoji to delete.")

        # make sure the user wants to delete the emojis
        msg_to_edit, result = await self.get_confirmation(ctx)

        # user doesn't want to delete
        if not result:
            raise CustomCommandError("Deletion cancelled.")

        # delete the emojis
        for emoji in emojis_to_delete:

            # emoji is from another guild
            if emoji.guild != ctx.message.guild:
                raise CustomCommandError(
                    f"I can't find the emoji {emoji} in this server.")

            # delete
            await emoji.delete(
                reason=f"Deleted by {ctx.message.author.display_name}")

        # only one emoji deleted
        if len(emojis_to_delete) == 1:
            embed = discord.Embed(
                title="Emoji deleted",
                colour=Colours.success,
                description=f"`:{emojis_to_delete[0].name}:`")

            embed.set_thumbnail(url=emojis_to_delete[0].url)

        # multiple emojis deleted; different embed required
        else:
            embed = discord.Embed(
                title=f"{len(emojis_to_delete)} emojis deleted",
                colour=Colours.success,
                description=
                f"`:{':`, `:'.join([emoji.name for emoji in emojis_to_delete])}:`"
            )

        # send success message
        await msg_to_edit.edit(embed=embed)
Example #3
0
    async def emojify(self, ctx, *, sentence=None):
        await self.has_voted(ctx)
        """
        Convert a sentence to emojis.
        :param ctx: context
        :param sentence: the sentence to convert
        :return: N/A
        """

        # no sentence
        if sentence is None:
            raise CustomCommandError(
                f"You need to enter a sentence to convert to emojis. "
                f"Check out `{ctx.prefix}help emojify` for more information.")

        # remove non-accepted characters
        sentence = list(
            filter(
                lambda letter_: letter_.isalpha() or letter_ in
                ACCEPTED_LETTERS, list(sentence)))

        string_to_send = ""

        for letter in sentence:
            # A-Z
            if letter.isalpha():
                string_to_send += ":regional_indicator_{}:".format(
                    letter.lower())
            # not A-Z, but is an acceptable character
            else:
                string_to_send += ACCEPTED_LETTERS[letter]

            string_to_send += " "  # add a space between letters

        # no accepted characters
        if len(string_to_send) == 0:
            raise CustomCommandError(
                f"Make sure your sentence includes some A-Z characters.")

        # too long
        elif len(string_to_send) > 2000:
            raise CustomCommandError(
                f"Your sentence is too long when converted to emojis ({len(string_to_send)} > 2000)."
            )

        # just right
        else:
            await ctx.send(string_to_send)
Example #4
0
 async def queue(self, ctx):
     if ctx.invoked_subcommand is None:
         raise CustomCommandError(
             f"You need to enter a sub-command.\n\n"
             f"**Sub-commands:** `"
             f"{'` `'.join(sorted([command.name for command in self.queue.commands]))}`"
         )
Example #5
0
    async def craft(self, ctx, base, eyes, mouth, brows=None, extras=None):
        try:
            # convert arguments to files
            base = Image.open(f"./data/emoji_crafting/bases/{base}.png"
                              ).convert("RGBA").resize((100, 100))
            eyes = Image.open(f"./data/emoji_crafting/eyes/{eyes}.png"
                              ).convert("RGBA").resize((100, 100))
            mouth = Image.open(f"./data/emoji_crafting/mouths/{mouth}.png"
                               ).convert("RGBA").resize((100, 100))

            # combine images
            emoji = await combine_images(base, mouth)
            emoji = await combine_images(emoji, eyes)

            # save image
            emoji.save(f"./data/emoji_crafting/creations/{ctx.message.id}.png")

            # convert to discord file
            with open(f"./data/emoji_crafting/creations/{ctx.message.id}.png",
                      "rb") as file:
                to_send = discord.File(file)

        # one of the numbers is out of range
        except FileNotFoundError:
            raise CustomCommandError(
                "One of your options is out of the valid range.\n\n"
                "**Required values:**\n"
                "**Base:** 1-33\n"
                "**Eyes:** 1-59\n"
                "**Mouth:** 1-66")

        # send file
        await ctx.send(file=to_send)
Example #6
0
    async def has_voted(self, ctx):
        voted = await self.DBL_CLIENT.get_user_vote(ctx.message.author.id)

        if voted:
            return True
        else:
            raise CustomCommandError(
                "**[Please vote to use that command.](https://top.gg/bot/749301838859337799/vote)** "
                "Your vote will take a few minutes to register.")
Example #7
0
    async def clap(self, ctx, *, args):
        """
        Replace spaces with the clap emoji.
        :param ctx: context
        :param args: the sentence to modify
        :return: N/A
        """

        if len(args) == 0:
            raise CustomCommandError("You need to submit a message.")

        clapped = "👏" + "👏".join(args.split()) + "👏"

        if len(clapped) > 2000:
            raise CustomCommandError(
                f"Your message needs to be shorter than 2000 characters (current length: {len(clapped)})."
            )

        await ctx.send(clapped)
Example #8
0
    async def rename(self, ctx, emoji_to_rename: discord.Emoji, *, args):
        """
        Rename an emoji.

        :param ctx: context
        :param emoji_to_rename: the emoji to be renamed. Must be part of the guild specified in ctx
        :param args: the name for the new emoji
        :return: N/A
        """

        # no emoji
        if emoji_to_rename.guild != ctx.message.guild:
            raise CustomCommandError(
                "Couldn't find that emoji in this server.")

        old_name = emoji_to_rename.name

        # remove symbols and spaces
        new_name = "".join(
            [re.sub(r"[^\w]", "", word.replace("\"", "")) for word in args])

        if new_name == "":
            raise CustomCommandError(
                "You need to include at least one alphanumeric character in the emoji's name."
            )

        # rename
        await emoji_to_rename.edit(name=new_name)

        # send success
        embed = discord.Embed(
            title="Emoji renamed",
            colour=Colours.success,
            description=f"`:{old_name}:` -> `:{new_name}:`",
        )

        embed.set_thumbnail(url=emoji_to_rename.url)

        # send
        await ctx.message.channel.send(embed=embed)
Example #9
0
    async def link(self, ctx, emojis: commands.Greedy[discord.PartialEmoji]):
        """
        Get the URL for the image of an emoji, or a list of emojis.

        :param ctx: context
        :param emojis: the list of emojis
        :return:
        """
        if len(emojis) == 0:
            raise CustomCommandError("You need to input at least one emoji .")

        embed = discord.Embed(colour=Colours.success, description="")

        for emoji in emojis:
            embed.description = str(embed.description) + str(emoji.url) + "\n"

        embed.set_thumbnail(url=emojis[0].url)

        await ctx.send(embed=embed)
Example #10
0
    async def get_emoji_info(self, ctx, emoji: discord.PartialEmoji):
        """
        Get information on an emoji from the current server.

        :param ctx: context
        :param emoji: the emoji to get information on. must be a custom emoji from the current server
        :return: N/A
        """

        # required to get user who made emoji
        try:
            emoji = await ctx.guild.fetch_emoji(emoji.id)
        except Exception:
            raise CustomCommandError(
                f"I can't find that emoji. Make sure it's from **this** server "
                f"({ctx.guild.name}).")

        # setup
        emoji_details_embed = discord.Embed(title=emoji.name,
                                            colour=Colours.base)
        emoji_details_embed.set_thumbnail(url=emoji.url)

        # fields
        emoji_details_embed.add_field(name="ID", value=emoji.id, inline=True)
        emoji_details_embed.add_field(name="Usage",
                                      value=f"`:{emoji.name}:`",
                                      inline=True)
        emoji_details_embed.add_field(name="Created at",
                                      value=emoji.created_at,
                                      inline=True)
        emoji_details_embed.add_field(name="Created by",
                                      value=emoji.user,
                                      inline=True)
        emoji_details_embed.add_field(name="URL",
                                      value=f"[Link]({emoji.url})",
                                      inline=True)
        emoji_details_embed.add_field(name="Animated",
                                      value=emoji.animated,
                                      inline=True)

        # send
        await ctx.channel.send(embed=emoji_details_embed)
Example #11
0
    async def create_help_embed(self, ctx, help_category):
        """Create a help embed based on the specified parameter."""

        # create embed
        help_embed = discord.Embed(
            title=f"Help for {help_category.capitalize()}",
            colour=Colours.base)
        # help_embed.set_footer(text=help_message, icon_url=self.bot.user.avatar_url)

        # if parameter is a category, list all commands in the category
        if help_category.capitalize() in self.bot.cogs:
            if help_category.lower(
            ) == "developer" and ctx.message.author.id != 554275447710548018:
                return
            else:
                help_embed.add_field(
                    name="Commands",
                    value=
                    f"`{'` `'.join(sorted([command.name for command in commands.Cog.get_commands(self.bot.cogs[help_category.capitalize()])]))}`\n\n"
                    f"Type `{ctx.prefix}help [command]` (e.g. `{ctx.prefix}help {choice(commands.Cog.get_commands(self.bot.cogs[help_category.capitalize()])).name}`)"
                    f" for specific help on a command.")

        # not a category
        elif help_category.lower() in bot_commands.keys():

            # add -- if they exist -- details of selected command (parameter) to embed
            for key, value in bot_commands[help_category.lower()].items():
                if len(value) > 0:
                    help_embed.add_field(name=key,
                                         value=value.replace(
                                             "[BOT_PREFIX]", ctx.prefix),
                                         inline=False)

        # doesnt exist
        else:
            raise CustomCommandError(
                f"Couldn't find the command \"{help_category}\". You can view a list of commands with `{ctx.prefix}help`."
            )

        # return the help embed
        return help_embed
Example #12
0
    async def browse_for_emojis(
            self,
            ctx,
            emoji_list,
            start_at_index=0,
            existing_search_message: discord.Message = None):
        accepted_reactions = ["⬅", "👍", "➡", "🔀"]
        sent_message = None

        def reaction_check(added_reaction):
            return added_reaction.member == ctx.message.author \
                and added_reaction.message_id == sent_message.id \
                and str(added_reaction.emoji.name) in accepted_reactions

        try:
            # pick the emoji to show
            emoji = emoji_list[start_at_index]

        except IndexError:  # emoji doesn't exist

            # search already exists, which means the user reached the end of the search results
            if existing_search_message:
                await existing_search_message.edit(embed=discord.Embed(
                    colour=Colours.fail,
                    description=
                    "<:redticksmall:736197216900874240> You reached the end of the search results."
                ))
                # remove control reactions
                await existing_search_message.clear_reactions()
                return

            # this is a new search, which means 0 results were found
            else:
                raise CustomCommandError("No results found.")

        # create the embed used in the search
        embed = discord.Embed(
            title=emoji.name,
            description="React below to add this emoji to your server.",
            colour=Colours.base)

        # add a footer to the embed that shows the current page number
        embed.set_footer(
            text=f"Page {start_at_index + 1} of {len(emoji_list)}",
            icon_url=ctx.message.author.avatar_url)

        # add a preview of the emoji
        embed.set_thumbnail(url=emoji.url)

        # add fields that show details about the target emoji
        embed.add_field(name="Name", value=f"`{emoji.name}`", inline=True)
        embed.add_field(name="Animated",
                        value=str(emoji.animated),
                        inline=True)
        embed.add_field(name="URL", value=f"[link]({emoji.url})", inline=True)

        # the message already exists
        if existing_search_message:
            sent_message = existing_search_message

            # remove any existing control reactions from the author
            await mass_remove_reactions(sent_message, accepted_reactions,
                                        ctx.message.author)

            # edit the message to show the new embed
            await existing_search_message.edit(embed=embed)

        else:
            # send the new embed to the channel
            sent_message = await ctx.send(embed=embed)

        # add control reactions if they don't already exist
        await mass_add_reactions(sent_message, accepted_reactions)

        while 1:
            try:
                # wait for the author to add a control reaction
                reaction = await self.bot.wait_for("raw_reaction_add",
                                                   timeout=30.0,
                                                   check=reaction_check)

            # search timed out
            except asyncio.TimeoutError:

                # edit embed to show error message
                await sent_message.edit(embed=discord.Embed(
                    colour=Colours.fail,
                    description=
                    "<:redticksmall:736197216900874240> This search timed out."
                ))

                # remove control reactions
                await sent_message.clear_reactions()
                return
            else:
                # left arrow added; go to the previous page in the search
                if reaction.emoji.name == "⬅":
                    await self.browse_for_emojis(
                        ctx=ctx,
                        emoji_list=emoji_list,
                        start_at_index=start_at_index - 1,
                        existing_search_message=sent_message)
                    return

                # thumbs up added; install the current emoji
                elif reaction.emoji.name == "👍":
                    await install_emoji(
                        ctx=ctx,
                        emoji_json={
                            "image": emoji.url,
                            "title": emoji.name
                        },
                        success_message="Emoji installed from search")

                # right arrow added; go to the next page in the search
                elif reaction.emoji.name == "➡":
                    await self.browse_for_emojis(
                        ctx=ctx,
                        emoji_list=emoji_list,
                        start_at_index=start_at_index + 1,
                        existing_search_message=sent_message)
                    return

                # shuffle added; go to a random page in the search
                elif reaction.emoji.name == "🔀":
                    await self.browse_for_emojis(
                        ctx=ctx,
                        emoji_list=emoji_list,
                        start_at_index=randint(0,
                                               len(emoji_list) - 1),
                        existing_search_message=sent_message)
                    return