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)
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)
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)
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]))}`" )
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)
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.")
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)
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)
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)
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)
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
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