async def jumbo(self, ctx, emoji): """Send the full-size image of an emoji.""" await send_warning( ctx, "This command is still in development; you might encounter some bugs." ) # convert to emoji try: conv = commands.PartialEmojiConverter() emoji = await conv.convert(ctx=ctx, argument=emoji) except: raise CustomCommandError( "This command requires that you submit a custom emoji. Use the emoji itself, " "not just its name.") emoji_int = emoji.id emoji_int = int(emoji_int) if emoji.animated: # animated; get gif url = f"https://cdn.discordapp.com/emojis/{emoji_int}.gif" else: # static; get png url = f"https://cdn.discordapp.com/emojis/{emoji_int}.png" jumbo_embed = discord.Embed(colour=Colours.success) jumbo_embed.set_image(url=url) # send await ctx.message.channel.send(embed=jumbo_embed)
async def _add_emoji_to_react_list(self, ctx, name, emoji): """ Do '!add_emoji_to_react_list <name> <emoji>' For example: `!add_emoji_to_react_list blaseball, :ballclark:` (don't include the <> or [] when running the command) (don't use a comma in this command!) Also works with '!aerl' """ if not self.has_role(ctx, self.allowed_role): return await ctx.message.delete() rl_name = f"{ctx.guild.id}_{name.strip()}" if rl_name not in self.word_reacts.keys(): await ctx.send(f"No react list named {name} found.", delete_after=10) return await ctx.message.add_reaction(self.bot.failed_react) converter = commands.PartialEmojiConverter() done = False try: emoji_to_add = await converter.convert(ctx, emoji) await ctx.message.add_reaction(emoji_to_add) self.word_reacts[rl_name]["emoji_list"].append(emoji_to_add) done = True except: try: await ctx.message.add_reaction(emoji) emoji_to_add = emoji self.word_reacts[rl_name]["emoji_list"].append(emoji_to_add) done = True except: pass self.save_word_reacts() if not done: await ctx.message.add_reaction(self.bot.failed_react) return await ctx.send(f"Could not find emoji {emoji}.", delete_after=10)
async def add_react_list(self, ctx, *, info): """ Do '!add_react_list <name>, <emoji>, <channel_id>, <word1>[,<word2>, <word3>]' For example: `!add_react_list snivy, :snivy:, 103110311031103110, snivy` Use 'none' instead of a channel id to apply this react list to all channels. (don't include the <> or [] when running the command) Also works with '!arl' """ info = re.split(r',\s+', info) if len(info) < 4: await ctx.message.add_reaction(self.bot.failed_react) return await ctx.send( "Must provide at least a name for the list, a reaction emoji, channel, and a list of at least 1 listen word.", delete_after=10) name, emoji, channel_raw, words = info[0], info[1], info[2], info[3:] rl_name = f"{ctx.guild.id}_{name}" if rl_name in self.react_lists.keys(): await ctx.message.add_reaction(self.bot.failed_react) return await ctx.send( f"A reaction list already exists for {name}. To add a word to its list, use the " f"`!add_word_to_react_list/!awrl` command", delete_after=20) utilities_cog = self.bot.cogs.get('Utilities') channel_id = "none" if channel_raw != "none": channel = await utilities_cog.get_channel_by_name_or_id( ctx, channel_raw) if not channel: await ctx.message.add_reaction(self.bot.failed_react) return await ctx.send(f"Could not find channel {channel_raw}", delete_after=10) channel_id = channel.id converter = commands.PartialEmojiConverter() badge_emoji = None try: badge_emoji = await converter.convert(ctx, info[1].strip()) emoji = badge_emoji await ctx.message.add_reaction(emoji) except: pass try: await ctx.message.add_reaction(info[1].strip()) badge_emoji = info[1].strip() emoji = badge_emoji except: pass if not badge_emoji: await ctx.message.add_reaction(self.bot.failed_react) return await ctx.send("Could not find that emoji.", delete_after=10) self.react_lists[rl_name] = { "name": name, "emoji": emoji, "channel_id": channel_id, "guild_id": ctx.guild.id, "words": words } await ctx.message.add_reaction(self.bot.success_react)
async def _add_word_react(self, ctx, *, info): """ Do '!add_react_list <name>, <emoji>, <channel_id>, <word1>[,<word2>, <word3>]' For example: `!add_react_list snivy, :snivy:, 103110311031103110, snivy` Use 'none' instead of a channel id to apply this react list to all channels. (don't include the <> or [] when running the command) Also works with '!arl' """ if not self.has_role(ctx, self.allowed_role): return await ctx.message.delete() info = re.split(r',\s+', info) if len(info) < 2: await ctx.message.add_reaction(self.bot.failed_react) return await ctx.send( "Must provide at least a word and 1 reaction emoji.", delete_after=10) name = info[0] rl_name = f"{ctx.guild.id}_{name}" if rl_name in self.word_reacts.keys(): await ctx.message.add_reaction(self.bot.failed_react) return await ctx.send( f"A reaction already exists for {name}. To add an emoji to its reaction list, use the " f"`!add_emoji_to_react_list/!aerl` command", delete_after=20) converter = commands.PartialEmojiConverter() emoji_list = [] for i in info[1:]: emoji_to_add = None emoji = i.strip() try: emoji_to_add = await converter.convert(ctx, emoji) await ctx.message.add_reaction(emoji_to_add) emoji_list.append(emoji_to_add) except: pass try: await ctx.message.add_reaction(emoji) emoji_to_add = emoji emoji_list.append(emoji_to_add) except: pass if not emoji_to_add: await ctx.message.add_reaction(self.bot.failed_react) return await ctx.send(f"Could not find emoji {i}.", delete_after=10) self.word_reacts[rl_name] = { "name": name, "emoji_list": emoji_list, "guild_id": ctx.guild.id } self.save_word_reacts() await ctx.message.add_reaction(self.bot.success_react)
async def get_count(self, ctx, emoji): converter = commands.PartialEmojiConverter() try: react_emoji = await converter.convert(ctx, emoji.strip()) except: await ctx.message.add_reaction(self.bot.failed_react) return await ctx.send("Could not find that emoji.", delete_after=10) if str(react_emoji.id) not in self.counts: await ctx.message.add_reaction(self.bot.failed_react) return await ctx.send("No react counter found with that emoji.", delete_after=10) react_count = self.counts[str(react_emoji.id)] await ctx.send(f"I have counted {react_count['count']} {react_count['message']}")
async def _add(self, ctx, *, info): """**Usage**: `!badge add <emoji>, <badge name>, [<badge description], [create in pokenav]` **Aliases**: `create, cr, new` Emoji and name are required with a comma between each. Description is optional Optionally can provide "false/no" to prevent badge from being created in Pokenav as well. By default, badge will be created on both bots """ info = re.split(r',\s+', info) if len(info) < 2: await ctx.message.add_reaction(self.bot.failed_react) self.bot.help_logger.info(f"User: {ctx.author.name}, channel: {ctx.channel}, error: Insufficient badge info: {info}.") return await ctx.send("Must provide at least an emoji and badge name, and optionally badge description.", delete_after=10) converter = commands.PartialEmojiConverter() try: badge_emoji = await converter.convert(ctx, info[0].strip()) except: badge_emoji = None if not badge_emoji: await ctx.message.add_reaction(self.bot.failed_react) self.bot.help_logger.info(f"User: {ctx.author.name}, channel: {ctx.channel}, error: No emoji found: {info[0]}.") return await ctx.send("Could not find that emoji.", delete_after=10) badge_name = info[1] badge_desc = '' create_in_pokenav = True if len(info) > 2: badge_desc = info[2] if len(info) > 3: if info[3].lower() == 'false' or info[3].lower() == 'no': create_in_pokenav = False try: new_badge, __ = BadgeTable.get_or_create(name=badge_name, description=badge_desc, emoji=badge_emoji.id, active=True) if new_badge: send_emoji = self.bot.get_emoji(badge_emoji.id) message = f"{send_emoji} {badge_name} (#{new_badge.id}) successfully created!" colour = discord.Colour.green() reaction = self.bot.success_react quick_badge_config = self.bot.guild_dict[ctx.guild.id]['configure_dict'].get('quick_badge', None) if create_in_pokenav and quick_badge_config is not None: pokenav_channel_id = quick_badge_config['pokenav_channel'] pokenav_channel = self.bot.get_channel(pokenav_channel_id) await pokenav_channel.send(f'$create badge {badge_emoji} "{badge_name}" "{badge_desc}"') else: message = "Failed to create badge. Please try again." colour = discord.Colour.red() reaction = self.bot.failed_react except peewee.IntegrityError: message = f"""A badge already exists with the same name, description, and emoji.""" colour = discord.Colour.red() reaction = self.bot.failed_react await ctx.message.add_reaction(reaction) await ctx.channel.send(embed=discord.Embed(colour=colour, description=message))
async def _add(self, ctx, *, info): info = re.split(r',\s+', info) if len(info) < 2: await ctx.message.add_reaction(self.bot.failed_react) self.bot.help_logger( f"User: {ctx.author.name}, channel: {ctx.channel}, error: Insufficient badge info: {info}." ) return await ctx.send( "Must provide at least an emoji and badge name, and optionally badge description.", delete_after=10) converter = commands.PartialEmojiConverter() try: badge_emoji = await converter.convert(ctx, info[0]) except: badge_emoji = None if not badge_emoji: await ctx.message.add_reaction(self.bot.failed_react) self.bot.help_logger( f"User: {ctx.author.name}, channel: {ctx.channel}, error: No emoji found: {info[0]}." ) return await ctx.send("Could not find that emoji.", delete_after=10) badge_name = info[1] badge_desc = '' if len(info) > 2: badge_desc = info[2] try: new_badge, __ = BadgeTable.get_or_create(name=badge_name, description=badge_desc, emoji=badge_emoji.id, active=True) if new_badge: send_emoji = self.bot.get_emoji(badge_emoji.id) message = f"{send_emoji} {badge_name} (#{new_badge.id}) successfully created!" colour = discord.Colour.green() reaction = self.bot.success_react else: message = "Failed to create badge. Please try again." colour = discord.Colour.red() reaction = self.bot.failed_react except peewee.IntegrityError: message = f"""A badge already exists with the same name, description, and emoji.""" colour = discord.Colour.red() reaction = self.bot.failed_react await ctx.message.add_reaction(reaction) response = await ctx.channel.send(embed=discord.Embed( colour=colour, description=message), delete_after=12)
async def emojibig(ctx, *, emote): emoji_converter = commands.PartialEmojiConverter() emoji = await emoji_converter.convert(ctx, emote) emotestring = str(emote) colon1 = emotestring.find(':') colon2 = emotestring.rfind(':') filename = emotestring[colon1 + 1:colon2] filepath = 'assets/Emotes/' + filename if emotestring[1] == "a": filepath += ".gif" else: filepath += ".jpg" with open(os.path.join(filepath), "wb+") as f: await emoji.url.save(filepath) await ctx.send(file=discord.File(filepath)) os.remove(filepath)
async def zipemojis(self, ctx: commands.Context, *messages: discord.Message): async with ctx.typing(): regex = r"<(a?):([a-zA-Z0-9\_]+):([0-9]+)>" emojis = [] for m in messages: for em in re.finditer(regex, m.content): try: pec = commands.PartialEmojiConverter() em = await pec.convert(ctx=ctx, argument=em.group(0)) emojis.append(em) except PartialEmojiConversionFailure: pass if len(emojis) == 0: await ctx.reply("No emojis found.") return await self.partial_emoji_list_to_uploaded_zip(ctx, emojis)
async def add_react_counter(self, ctx, *, info): info = re.split(r',\s+', info) if len(info) < 4: await ctx.message.add_reaction(self.bot.failed_react) return await ctx.send("Must provide at least an emoji, counter name, target user, counter message, optionally channel id(s).", delete_after=10) converter = commands.PartialEmojiConverter() try: badge_emoji = await converter.convert(ctx, info[0].strip()) except: await ctx.message.add_reaction(self.bot.failed_react) return await ctx.send("Could not find that emoji.", delete_after=10) if str(badge_emoji.id) in self.counts.keys(): await ctx.message.add_reaction(self.bot.failed_react) return await ctx.send("React counter already exists with that emoji.", delete_after=10) converter = commands.MemberConverter() try: member = await converter.convert(ctx, info[2]) except: await ctx.message.add_reaction(self.bot.failed_react) return await ctx.send(f"Could not find user {info[2]}.", delete_after=10) counter_name = info[1] channel_ids = [] counter_message = info[3] if len(info) > 4: channel_ids_raw = info[4:] for c_id in channel_ids_raw: utilities_cog = self.bot.cogs.get('Utilities') channel = await utilities_cog.get_channel_by_name_or_id(ctx, c_id) if channel: channel_ids.append(channel.id) self.counts[badge_emoji.id] = { "name": counter_name, "emoji_id": badge_emoji.id, "channel_ids": channel_ids, "user": member.id, "message": counter_message, "count": 0 } await ctx.message.add_reaction(self.bot.success_react) success_msg = f"Counter '**{counter_name}**' added with emoji {badge_emoji}." if len(channel_ids) > 0: success_msg += f" Active in {len(channel_ids)} channels." self.save_react_counts() return await ctx.send(success_msg, delete_after=10)
async def convert(self, ctx: utils.CustomContext, argument: str): converters = { commands.TextChannelConverter(): "Text Channel", commands.VoiceChannelConverter(): "Voice Channel", commands.MemberConverter(): "Server Member", commands.UserConverter(): "Discord User", commands.PartialEmojiConverter(): "Emoji", utils.RoleConverter(): "Server Role", } for converter, title in converters.items(): try: convert = await converter.convert(ctx, argument) return convert.id, title except Exception as e: continue raise commands.BadArgument("Couldn't find anything that matches that.")
async def convert(self, ctx: utils.CustomContext, argument: str): try: member_converter = commands.MemberConverter() member = await member_converter.convert(ctx, argument) asset = member.avatar_url_as(static_format="png", format="png", size=512) image = await asset.read() return image except (commands.MemberNotFound, TypeError): url_regex = r"http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*(),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+" try: emoji_regex = r"<(?P<animated>a?):(?P<name>[a-zA-Z0-9_]{2,32}):(?P<id>[0-9]{18,22})>" url = await twemoji_parser.emoji_to_url(argument, include_check=True) if re.match(url_regex, url): async with ctx.bot.session.get(url) as response: image_bytes = await response.read() return image_bytes if re.match(url_regex, argument): async with ctx.bot.session.get(argument) as response: image = await response.read() return image elif re.match(emoji_regex, argument): emoji_converter = commands.PartialEmojiConverter() emoji = await emoji_converter.convert(ctx, argument) asset = emoji.url image = await asset.read() return image except TypeError: return None return None
async def convert(self, ctx, argument): if self.check_embed and url_regex.fullmatch(argument) is not None: if ctx.message.embeds: embed = ctx.message.embeds[0] else: def check(_, message): return message.id == ctx.message.id and message.embeds try: _, message = await ctx.bot.wait_for('message_edit', timeout=2, check=check) except asyncio.TimeoutError: raise commands.BadArgument embed = message.embeds[0] if embed.type != 'image': raise commands.CheckFailure return embed.thumbnail.proxy_url if self.check_member: converter = commands.MemberConverter() try: member = await converter.convert(ctx, argument) except commands.BadArgument: pass else: return member.avatar_url if self.check_emoji: converter = commands.PartialEmojiConverter() try: emoji = await converter.convert(ctx, argument) except commands.BadArgument: pass else: return emoji.url raise commands.BadArgument
async def convert(self, ctx, argument): find_member = lambda s: self.re_member.findall(s) find_emoji = lambda s: self.re_emoji.findall(s) converters = ( (find_member, commands.MemberConverter(), 0), (find_emoji, commands.PartialEmojiConverter(), 1), ) args = argument.replace(", ", ",").replace(" ,", ",").split(",") if not isinstance(args, list): args = [args] args = args[:self.n] if self.require and len(args) != self.n: raise commands.UserInputError() parsed = [] for arg in args: added = 0 for pack in converters: search, converter, i = pack found = search(arg) if found and (arg.strip() == found[0]): obj = await converter.convert(ctx=ctx, argument=found[0]) if obj: parsed.append(obj) added = 1 break if not added: parsed.append(await commands.clean_content( use_nicknames=True, fix_channel_mentions=True).convert(ctx, arg)) return parsed[:self.n]
def __init__(self, bot): self.bot = bot self.client = bot.client self.table = self.client['Giveaways'] self.codes = self.table['codes'] self.channel_converter = commands.TextChannelConverter() self.emoji_converter = commands.PartialEmojiConverter() ## Using partial so i can accept default emoji's as well self.giveaways = {} self.questions = ( 'Which channel would you like to set this giveaway up in?', 'How many winners would you like for this giveaway', 'How long will this giveaway last for? Please use the format of `<TIME>[s/m/h/d/w]`, default is set to seconds.', 'Are there any requirements? (y/n)', 'What is the prize for this giveaway?', 'Would you like a custom emoji in place of the default option "🎉", if not simply respond with `no`. Else send the emoji below. Warning: If using a discord custom emoji, please ensure the bot is in the server that has the emoji.' ) self.scopes = { ## 'message': 2, ## 'invite': 3, ## Adding the message and invite option later when I get them done. 'guild': { 'scope': 1, 'aliases': ['guilds'] }, 'server': { 'scope': 1, 'aliases': ['servers'] }, ## This is for the reverse search. 'role': { 'scope': 2, 'aliases': ['roles'] }, 'creation-date': { 'scope': 3, 'aliases': ['creation'] }, 'join-date': { 'scope': 4, 'aliases': ['join'] }, 'exit': { 'scope': 5, 'aliases': [] }, } self.aliase_to_scope = {} for key, value in self.scopes.items(): for aliase in value['aliases']: self.aliase_to_scope.update({aliase: key}) self.scales = { 's': 1, 'm': 60, 'h': (60 * 60), 'd': ((60 * 60) * 24), 'w': (((60 * 60) * 24) * 7) } self.marks = { 's': 'second(s)', 'm': 'minutes(s)', 'h': 'hour(s)', 'd': 'day(s)', 'w': 'week(s)' } self.listed_scopes = '' for scope in self.scopes: self.listed_scopes += '%s|' % scope for aliase in self.scopes[scope]['aliases']: self.listed_scopes += '%s|' % aliase self.listed_scopes = self.listed_scopes[:-1].split('|') for guild in bot.guilds: self.giveaways[guild.id] = {} bot.loop.create_task(self.load_giveaways())
async def init(self, ctx): """ Initialize role message for current channel :param ctx: Context :return: """ async with session_lock: with Session() as session: db_server = get_create_ctx(ctx, session, server_crud) embed = Embed() embed.title = f"Assignable roles for **{ctx.guild.name}**" embed.description = "Use reactions inorder to get " \ "roles assigned to you, or use " \ "`!role add roleName`" converter = commands.EmojiConverter() pconverter = commands.PartialEmojiConverter() # Get all roles on the server roles = role_crud.get_multi_by_server_uuid( session, get_create_ctx(ctx, session, server_crud).uuid ) # Gather all used emojis for future reactions emojis = [] for r in roles: emoji = emoji_crud.get_by_role( session, r.uuid ) if emoji is not None: try: # Convert into actual emoji e = await converter.convert( ctx, emoji.identifier ) except commands.EmojiNotFound: # Try partial emoji instead try: e = await pconverter.convert( ctx, emoji.identifier ) except commands.PartialEmojiConversionFailure: # Assume that it is an unicode emoji e = emoji.identifier # Add to message embed.add_field( name=f"{str(e)} == {r.name}", value=r.description, inline=False ) emojis.append(e) # Send message role_message = await ctx.send(embed=embed) # Add reaction to message with all used emojis for e in emojis: await role_message.add_reaction(e) # Update server object to include role message data server_update = UpdateServer(**{ "role_message": str(role_message.id), "role_channel": str(ctx.channel.id) }) server_crud.update( session, db_obj=db_server, obj_in=server_update )
async def create( self, ctx, discord_id: int, description: str, emoji: str = None ): """ Create assignable role :param ctx: Context :param discord_id: Role Discord ID :param description: Description of role usage :param emoji: Emoji for assignment via reactions :return: """ embed = Embed() embed.set_author(name=self.__bot.user.name, url=settings.URL, icon_url=self.__bot.user.avatar_url) async with session_lock: with Session() as session: d_role = ctx.guild.get_role(discord_id) db_role = role_crud.get_by_discord(session, discord_id) # TODO Add emoji parsing if d_role is None: embed.title = "Role not found." embed.colour = Colors.error elif db_role is not None: embed.title = "Role already exists!" embed.colour = Colors.other else: role = CreateRole(**{ "discord_id": discord_id, "name": d_role.name, "description": description, "server_uuid": get_create_ctx( ctx, session, server_crud ).uuid }) db_role = role_crud.create(session, obj_in=role) if emoji is not None: converter = commands.EmojiConverter() pconverter = commands.PartialEmojiConverter() try: # Convert into actual emoji e = await converter.convert( ctx, emoji ) except commands.EmojiNotFound: # Try partial emoji instead try: e = await pconverter.convert( ctx, emoji ) except commands.PartialEmojiConversionFailure: # Assume that it is an unicode emoji e = emoji else: e = None if e is not None and not isinstance(e, discord.partial_emoji.PartialEmoji): if hasattr(e, 'name'): e = e.name db_e = CreateRoleEmoji(**{ "identifier": e, "role_uuid": db_role.uuid }) emoji_crud.create(session, obj_in=db_e) elif isinstance(emoji, discord.partial_emoji.PartialEmoji): embed.description = "**Note**: Role was created" \ " without an emoji, because the bot " \ "cannot use provided emoji..." else: embed.description = "**Note**: Role was created" \ " without an emoji, so it " \ "cannot be assigned with " \ "reactions!" embed.title = f"Role *{db_role.name}* created." embed.colour = Colors.success embed.timestamp = datetime.utcnow() await ctx.send(embed=embed)
async def role_update(self): """ Update roles stored every 30 minutes :return: """ await self.__bot.wait_until_ready() logger.info("Updating role messages...") async with session_lock: with Session() as session: # Go through all visible guilds for guild in self.__bot.guilds: server = server_crud.get_by_discord(session, guild.id) # Skip if server is not found if server is None: continue # Get all roles for server roles = role_crud.get_multi_by_server_uuid( session, server.uuid ) temp_roles = {} for r in roles: temp_roles[r.discord_id] = r # Go through all roles of a guild for r in guild.roles: # Skip roles that are default or premium if r.is_default or r.is_premium_subscriber: continue # Check that role is registered, otherwise skip if r.id not in temp_roles: continue # If the name is the same, then skip if r.name == temp_roles[r.id].name: continue role_update = UpdateRole(**{ "name": r.name }) # Update role role_crud.update( session, temp_roles[r.id], role_update ) # Update role message if it exists if server.role_message is not None and \ server.role_channel is not None: channel = self.__bot.get_channel( int(server.role_channel) ) # Continue if channel wasn't found if channel is None: logger.info(f"No channel found for {server.name}.") continue # Channel must not be bloated with messages message = utils.find( lambda m: (m.id == int(server.role_message)), await channel.history(limit=10).flatten() ) # Continue if message wasn't found if message is None: logger.info(f"No message found for {server.name}.") continue # Get context ctx = await self.__bot.get_context(message) embed = Embed() embed.title = f"Assignable roles for " \ f"**{message.guild.name}**" embed.description = "Use reactions inorder to get " \ "roles assigned to you, or use " \ "`!role add roleName`" converter = commands.EmojiConverter() pconverter = commands.PartialEmojiConverter() # Get all roles of a server roles = role_crud.get_multi_by_server_uuid( session, server.uuid ) # Gather all used emojis for future reactions emojis = [] for ro in roles: emoji = emoji_crud.get_by_role(session, ro.uuid) try: # Convert into actual emoji e = await converter.convert( ctx, emoji.identifier ) except commands.EmojiNotFound: # Try partial emoji instead try: e = await pconverter.convert( ctx, emoji.identifier ) except commands.PartialEmojiConversionFailure: # Assume that it is an unicode emoji e = emoji.identifier # Add to message embed.add_field( name=f"{str(e)} == {ro.name}", value=ro.description, inline=False ) emojis.append(e) await message.edit(embed=embed) # Check old reactions old_emojis = [] for r in message.reactions: old_emojis.append(r.emoji) # Add new reactions to message for e in emojis: if isinstance(e, discord.partial_emoji.PartialEmoji): logger.error(f"Emoji not cannot be used! Emoji: {e}") elif e not in old_emojis: await message.add_reaction(e) logger.info(f"Message updated for {server.name}.")
# API stuff BOTS_GG_TOKEN: str = "" # Colors used in the Bot class Colours: base: Color = Color(16562199) success: Color = Color(3066993) fail: Color = Color(15742004) warn: Color = Color(16707936) # Custom logging class (can be modified to send Discord alerts etc.) class DiscordLogger(logging.Logger): channel: TextChannel def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) def log(self, *args, **kwargs): # TODO: add Discord alerts super().log(*args, **kwargs) # Logger LOGGER = DiscordLogger(__name__) # Converters EMOJI_CONVERTER = commands.EmojiConverter() PARTIAL_EMOJI_CONVERTER = commands.PartialEmojiConverter()
type_to_converter = { # Builtins bool: commands.core._convert_to_bool, int: built_in_converter(int), str: str, # Discord objects Role: commands.RoleConverter(), User: commands.UserConverter(), Member: commands.MemberConverter(), Color: commands.ColorConverter(), Invite: commands.InviteConverter(), Emoji: commands.EmojiConverter(), Message: commands.MessageConverter(), PartialEmoji: commands.PartialEmojiConverter(), TextChannel: commands.TextChannelConverter(), VoiceChannel: commands.VoiceChannelConverter(), CategoryChannel: commands.CategoryChannelConverter(), } _to_str = { Message: lambda m: f"Message with id {m.id} in {m.channel.mention}", } def to_str(argument: UserInputable) -> str: _type = type(argument) if issubclass(_type, Enum): return argument.name.capitalize().replace("_", " ") if _type is Reaction: