class ImageConverter(commands.Converter[objects.Image]): async def convert(self, ctx: custom.Context, argument: str) -> objects.Image: if (check := yarl.URL(argument)) and check.scheme and check.host: return objects.Image(argument) try: member = await commands.MemberConverter().convert(ctx=ctx, argument=argument) except commands.MemberNotFound: pass else: return objects.Image(utils.avatar(member)) try: emoji = await commands.EmojiConverter().convert(ctx=ctx, argument=str(argument)) except commands.EmojiNotFound: pass else: return objects.Image(emoji.url) try: partial_emoji = await commands.PartialEmojiConverter().convert(ctx=ctx, argument=str(argument)) except commands.PartialEmojiConversionFailure: pass else: return objects.Image(partial_emoji.url) url = f"https://twemoji.maxcdn.com/v/latest/72x72/{ord(argument[0]):x}.png" async with ctx.bot.session.get(url=url) as response: if response.status == 200: return objects.Image(url) raise commands.BadArgument(message=argument)
async def on_message(self, message: discord.Message) -> None: if config.ENV == enums.Environment.DEVELOPMENT: return if message.guild or message.is_system(): return content = await utils.safe_content( self.bot.mystbin, message.content) if message.content else "*No content*" embed = discord.Embed( colour=colours.GREEN, title=f"DM from **{message.author}**:", description=content).add_field( name="Info:", value=f"`Channel:` {message.channel} `{message.channel.id}`\n" f"`Author:` {message.author} `{message.author.id}`\n" f"`Time:` {utils.format_datetime(pendulum.now(tz='UTC'))}\n" f"`Jump:` [Click here]({message.jump_url})", ).set_footer(text=f"ID: {message.id}") __log__.info( f"DM from {message.author} ({message.author.id}) | Content: {content}" ) await self.bot.DMS_LOG.send(embed=embed, username=f"{message.author}", avatar_url=utils.avatar(message.author)) await self._log_attachments(webhook=self.bot.DMS_LOG, message=message) await self._log_embeds(webhook=self.bot.DMS_LOG, message=message)
async def _log_embeds(webhook: discord.Webhook, message: discord.Message) -> None: for embed in message.embeds: await webhook.send( content=f"Embed from message with id **{message.id}**:", embed=embed, username=f"{message.author}", avatar_url=utils.avatar(message.author), )
async def handle_traceback(self, ctx: custom.Context, exception: Exception) -> None: embed = utils.embed( colour=colours.RED, emoji=emojis.CROSS, description= f"Something went wrong! Join my [support server]({values.SUPPORT_LINK}) for help.", ) await ctx.reply(embed=embed) message = "".join( traceback.format_exception(type(exception), exception, exception.__traceback__)) __log__.error(f"Traceback:", exc_info=exception) embed = discord.Embed( colour=colours.RED, description=await utils.safe_content(self.bot.mystbin, ctx.message.content, syntax="python", max_characters=2000), ).add_field( name="Info:", value= f"{f'`Guild:` {ctx.guild} `{ctx.guild.id}`{values.NL}' if ctx.guild else ''}" f"`Channel:` {ctx.channel} `{ctx.channel.id}`\n" f"`Author:` {ctx.author} `{ctx.author.id}`\n" f"`Time:` {utils.format_datetime(pendulum.now(tz='UTC'))}", ) message = await utils.safe_content(self.bot.mystbin, f"```py\n{message}```", syntax="python", max_characters=2000) await self.bot.ERROR_LOG.send(embed=embed, username=f"{ctx.author}", avatar_url=utils.avatar(ctx.author)) await self.bot.ERROR_LOG.send(content=message, username=f"{ctx.author}", avatar_url=utils.avatar(ctx.author))
async def _log_attachments(webhook: discord.Webhook, message: discord.Message) -> None: with contextlib.suppress(discord.HTTPException, discord.NotFound, discord.Forbidden): for attachment in message.attachments: await webhook.send( content= f"Attachment from message with id **{message.id}**:", file=await attachment.to_file(use_cached=True), username=f"{message.author}", avatar_url=utils.avatar(message.author), )
async def user_info(self, ctx: custom.Context, *, person: discord.Member | discord.User = utils.MISSING) -> None: """ Displays information about the given person. **person**: The person to get information for. Can be their ID, Username, Nickname or @Mention. Defaults to you. """ user = person or ctx.author description = f"**Created on:** {utils.format_datetime(user.created_at)}\n" \ f"**Created:** {utils.format_difference(user.created_at)} ago\n" \ f"**Badges:** {utils.badge_emojis(user)}\n" \ f"**Bot account:** {str(user.bot).replace('True', 'Yes').replace('False', 'No')}\n" \ f"**System account:** {str(user.system).replace('True', 'Yes').replace('False', 'No')}\n" \ f"**Mutual guilds:** {len(user.mutual_guilds)}\n" if isinstance(user, discord.Member): description += f"**Status:** {user.status.name.replace('dnd', 'Do Not Disturb').title()}{emojis.PHONE if user.is_on_mobile() else ''}\n" \ f"**Activity:**\n{utils.activities(user)}\n" embed = discord.Embed( colour=colours.MAIN, title=f"Information about **{user}**:", description=description ).set_footer( text=f"ID: {user.id}" ).set_thumbnail( url=utils.avatar(user) ) if isinstance(user, discord.Member): embed.add_field( name="Server related information:", value=f"**Nickname:** {user.nick}\n" f"**Joined on:** {utils.format_datetime(user.joined_at)}\n" f"**Joined:** {utils.format_difference(user.joined_at)} ago\n" f"**Join Position:** {sorted(ctx.guild.members, key=lambda m: m.joined_at).index(user) + 1}\n" f"**Top role:** {user.top_role.mention}\n" f"**Role count:** {len(user.roles) - 1}\n", ) await ctx.reply(embed=embed)
async def avatar(self, ctx: custom.Context, *, person: discord.Member | discord.User = utils.MISSING) -> None: """ Display a person's avatar. **person**: The person to get the avatar of. Can be their ID, Username, Nickname or @Mention. Defaults to you. """ user = person or ctx.author description = f"[PNG]({utils.avatar(user, format='png')}) | [JPG]({utils.avatar(user, format='jpg')}) | [WEBP]({utils.avatar(user, format='webp')}) " if user.avatar.is_animated(): description += f" | [GIF]({utils.avatar(user, format='gif')})" embed = discord.Embed( colour=colours.MAIN, title=f"Avatar for **{user}**:", description=description ).set_image( url=utils.avatar(user) ) await ctx.reply(embed=embed)
reference.resolved if isinstance( reference.resolved, discord.Message) else ctx.message) default = None if attachments := message.attachments: default = objects.Image(attachments[0].url) elif embeds := message.embeds: if (image := embeds[0].image) or (image := embeds[0].thumbnail): default = objects.Image(image.url) param = Parameter(name=param.name, kind=param.kind, default=default or objects.Image(utils.avatar(ctx.author)), annotation=param.annotation) return _old_transform(self=self, ctx=ctx, param=param) commands.Command.transform = _new_transform def setup(bot: Life) -> None: bot.add_cog(Images(bot)) class Images(commands.Cog): def __init__(self, bot: Life, /) -> None: self.bot: Life = bot