import re from io import BytesIO from discord import File, Role, User from discord.ext import commands from discord_slash import SlashContext, cog_ext from discord_slash.utils.manage_commands import create_option from PIL import Image, ImageDraw import jarvis from jarvis import config, jarvis_self, logo from jarvis.data.robotcamo import emotes, names from jarvis.utils import build_embed, convert_bytesize, get_repo_hash from jarvis.utils.field import Field guild_ids = [862402786116763668] class UtilCog(commands.Cog): """ Utility functions for J.A.R.V.I.S. Mostly system utility functions, but may change over time """ def __init__(self, bot): self.bot = bot self.config = config.get_config() @cog_ext.cog_slash( name="status", description="Retrieve J.A.R.V.I.S. status", ) @commands.cooldown(1, 30, commands.BucketType.channel) async def _status(self, ctx): title = "J.A.R.V.I.S. Status" desc = "All systems online" color = "#98CCDA" fields = [] with jarvis_self.oneshot(): fields.append(Field("CPU Usage", jarvis_self.cpu_percent())) fields.append( Field( "RAM Usage", convert_bytesize(jarvis_self.memory_info().rss), ) ) fields.append(Field("PID", jarvis_self.pid)) fields.append(Field("Version", jarvis.__version__, False)) fields.append(Field("Git Hash", get_repo_hash(), False)) embed = build_embed( title=title, description=desc, fields=fields, color=color ) await ctx.send(embed=embed) @cog_ext.cog_slash( name="logo", description="Get the current logo", ) @commands.cooldown(1, 30, commands.BucketType.channel) async def _logo(self, ctx): lo = logo.get_logo(self.config.logo) await ctx.send(f"```\n{lo}\n```") @cog_ext.cog_slash( name="rcauto", description="Automates robot camo letters", options=[ create_option( name="text", description="Text to camo-ify", option_type=3, required=True, ) ], ) async def _rcauto(self, ctx: SlashContext, text: str): to_send = "" if len(text) == 1 and not re.match( r"^[A-Z0-9-()$@!?^'#. ]$", text.upper() ): await ctx.send("Please use ASCII characters.", hidden=True) return for letter in text.upper(): if letter == " ": to_send += " " elif re.match(r"^[A-Z0-9-()$@!?^'#.]$", letter): id = emotes[letter] if ctx.author.is_on_mobile(): to_send += f":{names[id]}:" else: to_send += f"<:{names[id]}:{id}>" if len(to_send) > 2000: await ctx.send("Too long.", hidden=True) else: await ctx.send(to_send) @cog_ext.cog_slash( name="avatar", description="Get a user avatar", options=[ create_option( name="user", description="User to view avatar of", option_type=6, required=False, ) ], ) @commands.cooldown(1, 5, commands.BucketType.user) async def _avatar(self, ctx, user: User = None): if not user: user = ctx.author avatar = user.avatar_url embed = build_embed( title="Avatar", description="", fields=[], color="#00FFEE" ) embed.set_image(url=avatar) embed.set_author( name=f"{user.name}#{user.discriminator}", icon_url=avatar ) await ctx.send(embed=embed) @cog_ext.cog_slash( name="roleinfo", description="Get role info", guild_ids=guild_ids, options=[ create_option( name="role", description="Role to get info of", option_type=8, required=True, ) ], ) async def _roleinfo(self, ctx: SlashContext, role: Role): fields = [ Field(name="ID", value=role.id), Field(name="Name", value=role.name), Field(name="Color", value=str(role.color)), Field(name="Mention", value=f"`{role.mention}`"), Field(name="Hoisted", value="Yes" if role.hoist else "No"), Field(name="Position", value=str(role.position)), Field( name="Mentionable", value="Yes" if role.mentionable else "No" ), ] embed = build_embed( title="", description="", fields=fields, color=str(role.color), timestamp=role.created_at, ) embed.set_footer(text="Role Created") embed.set_thumbnail(url="attachment://color_circle.png") im = Image.new("RGBA", size=(200, 200), color=(0, 0, 0, 0)) canvas = ImageDraw.Draw(im) color = role.color.to_rgb() color = list(color) color.append(255) color = tuple(color) canvas.rectangle([(0, 0), (200, 200)], fill=color) del canvas with BytesIO() as image_bytes: im.save(image_bytes, "PNG") image_bytes.seek(0) color_circle = File(image_bytes, filename="color_circle.png") await ctx.send(embed=embed, file=color_circle) @cog_ext.cog_slash( name="userinfo", description="Get user info", guild_ids=guild_ids, options=[ create_option( name="user", description="User to get info of", option_type=6, required=False, ) ], ) async def _userinfo(self, ctx: SlashContext, user: User = None): if not user: user = ctx.author user_roles = user.roles if user_roles: user_roles = sorted(user.roles, key=lambda x: -x.position) _ = user_roles.pop(-1) fields = [ Field( name="Joined", value=user.joined_at.strftime("%a, %b %d, %Y %I:%M %p"), ), Field( name="Registered", value=user.created_at.strftime("%a, %b %d, %Y %I:%M %p"), ), Field( name=f"Roles [{len(user_roles)}]", value=" ".join([x.mention for x in user_roles]) if user_roles else "None", inline=False, ), ] embed = build_embed( title="", description=user.mention, fields=fields, color=str(user_roles[0].color) if user_roles else "#FF0000", ) embed.set_author( name=f"{user.name}#{user.discriminator}", icon_url=user.avatar_url ) embed.set_thumbnail(url=user.avatar_url) embed.set_footer(text=f"ID: {user.id}") await ctx.send(embed=embed) def setup(bot): bot.add_cog(UtilCog(bot))