diff --git a/jarvis/__init__.py b/jarvis/__init__.py index 40e7dbe..b67872e 100644 --- a/jarvis/__init__.py +++ b/jarvis/__init__.py @@ -44,7 +44,7 @@ jarvis = commands.Bot( ) slash = SlashCommand(jarvis, sync_commands=True, sync_on_cog_reload=True) jarvis_self = Process() -__version__ = "1.5.8" +__version__ = "1.6.0" db = DBManager(get_config().mongo).mongo diff --git a/jarvis/cogs/rolegiver.py b/jarvis/cogs/rolegiver.py new file mode 100644 index 0000000..47aa7b9 --- /dev/null +++ b/jarvis/cogs/rolegiver.py @@ -0,0 +1,281 @@ +from discord import Role +from discord.ext import commands +from discord_slash import SlashContext, cog_ext +from discord_slash.utils.manage_commands import create_option + +from jarvis.db.types import Setting +from jarvis.utils import build_embed +from jarvis.utils.field import Field + + +class RolegiverCog(commands.Cog): + def __init__(self, bot): + self.bot = bot + + @cog_ext.cog_subcommand( + base="rolegiver", + name="add", + description="Add a role to rolegiver", + options=[ + create_option( + name="role", + description="Role to add", + option_type=8, + required=True, + ) + ], + ) + @commands.has_permissions(administrator=True) + async def _rolegiver_add(self, ctx: SlashContext, role: Role): + setting = Setting.get(guild=ctx.guild.id, setting="rolegiver") + if setting and role.id in setting.value: + await ctx.send("Role already in rolegiver", hidden=True) + return + + if not setting: + setting = Setting( + guild=ctx.guild.id, setting="rolegiver", value=[] + ) + + roles = [] + for role_id in setting.value: + e_role = ctx.guild.get_role(role_id) + roles.append(e_role) + + value = "\n".join([r.mention for r in roles]) if roles else "None" + fields = [ + Field(name="New Role", value=f"{role.mention}"), + Field(name="Existing Role(s)", value=value), + ] + setting.value.append(role.id) + setting.update() + + embed = build_embed( + title="Rolegiver Updated", + description="New role added to rolegiver", + fields=fields, + ) + + embed.set_thumbnail(url=ctx.guild.icon_url) + embed.set_author( + name=ctx.author.nick if ctx.author.nick else ctx.author.name, + icon_url=ctx.author.avatar_url, + ) + + embed.set_footer( + text=f"{ctx.author.name}#{ctx.author.discriminator} " + + f"| {ctx.author.id}" + ) + + await ctx.send(embed=embed) + + @cog_ext.cog_subcommand( + base="rolegiver", + name="remove", + description="Remove a role from rolegiver", + options=[ + create_option( + name="role", + description="Role to add", + option_type=8, + required=True, + ) + ], + ) + @commands.has_permissions(administrator=True) + async def _rolegiver_remove(self, ctx: SlashContext, role: Role): + setting = Setting.get(guild=ctx.guild.id, setting="rolegiver") + if not setting or (setting and not setting.value): + await ctx.send("Rolegiver has no roles", hidden=True) + return + elif role.id not in setting.value: + await ctx.send("Role not in rolegiver", hidden=True) + return + + setting.value.remove(role.id) + setting.update() + + roles = [] + for role_id in setting.value: + e_role = ctx.guild.get_role(role_id) + roles.append(e_role) + + value = "\n".join([r.mention for r in roles]) if roles else "None" + fields = [ + Field(name="Removed Role", value=f"{role.mention}"), + Field(name="Remaining Role(s)", value=value), + ] + + embed = build_embed( + title="Rolegiver Updated", + description="Role removed from rolegiver", + fields=fields, + ) + + embed.set_thumbnail(url=ctx.guild.icon_url) + embed.set_author( + name=ctx.author.nick if ctx.author.nick else ctx.author.name, + icon_url=ctx.author.avatar_url, + ) + + embed.set_footer( + text=f"{ctx.author.name}#{ctx.author.discriminator} " + + f"| {ctx.author.id}" + ) + + await ctx.send(embed=embed) + + @cog_ext.cog_subcommand( + base="rolegiver", + name="list", + description="List roles rolegiver", + ) + async def _rolegiver_list(self, ctx: SlashContext): + setting = Setting.get(guild=ctx.guild.id, setting="rolegiver") + if not setting or (setting and not setting.value): + await ctx.send("Rolegiver has no roles", hidden=True) + return + + roles = [] + for role_id in setting.value: + e_role = ctx.guild.get_role(role_id) + roles.append(e_role) + + value = "\n".join([r.mention for r in roles]) if roles else "None" + + embed = build_embed( + title="Rolegiver Updated", + description=f"Available roles:\n{value}", + fields=[], + ) + + embed.set_thumbnail(url=ctx.guild.icon_url) + embed.set_author( + name=ctx.author.nick if ctx.author.nick else ctx.author.name, + icon_url=ctx.author.avatar_url, + ) + + embed.set_footer( + text=f"{ctx.author.name}#{ctx.author.discriminator} " + + f"| {ctx.author.id}" + ) + + await ctx.send(embed=embed) + + @cog_ext.cog_subcommand( + base="role", + name="get", + description="Get a role from rolegiver", + options=[ + create_option( + name="role", + description="Role to add", + option_type=8, + required=True, + ) + ], + ) + @commands.cooldown(1, 10, commands.BucketType.user) + async def _role_get(self, ctx: SlashContext, role: Role): + setting = Setting.get(guild=ctx.guild.id, setting="rolegiver") + if not setting or (setting and not setting.value): + await ctx.send("Rolegiver has no roles", hidden=True) + return + elif role.id not in setting.value: + await ctx.send("Role not in rolegiver", hidden=True) + return + elif role in ctx.author.roles: + await ctx.send("You already have that role", hidden=True) + return + + await ctx.author.add_roles(role, reason="Rolegiver") + + value = ( + "\n".join([r.mention for r in ctx.author.roles]) + if ctx.author.roles + else "None" + ) + fields = [ + Field(name="Added Role", value=f"{role.mention}"), + Field(name="Prior Role(s)", value=value), + ] + + embed = build_embed( + title="User Given Role", + description=f"{role.mention} given to {ctx.author.mention}", + fields=fields, + ) + + embed.set_thumbnail(url=ctx.guild.icon_url) + embed.set_author( + name=ctx.author.nick if ctx.author.nick else ctx.author.name, + icon_url=ctx.author.avatar_url, + ) + + embed.set_footer( + text=f"{ctx.author.name}#{ctx.author.discriminator} " + + f"| {ctx.author.id}" + ) + + await ctx.send(embed=embed) + + @cog_ext.cog_subcommand( + base="role", + name="forfeit", + description="Have rolegiver take away role", + options=[ + create_option( + name="role", + description="Role to remove", + option_type=8, + required=True, + ) + ], + ) + @commands.cooldown(1, 10, commands.BucketType.user) + async def _role_forfeit(self, ctx: SlashContext, role: Role): + setting = Setting.get(guild=ctx.guild.id, setting="rolegiver") + if not setting or (setting and not setting.value): + await ctx.send("Rolegiver has no roles", hidden=True) + return + elif role.id not in setting.value: + await ctx.send("Role not in rolegiver", hidden=True) + return + elif role not in ctx.author.roles: + await ctx.send("You do not have that role", hidden=True) + return + + await ctx.author.remove_roles(role, reason="Rolegiver") + + value = ( + "\n".join([r.mention for r in ctx.author.roles if r.id != role.id]) + if ctx.author.roles + else "None" + ) + fields = [ + Field(name="Taken Role", value=f"{role.mention}"), + Field(name="Remaining Role(s)", value=value), + ] + + embed = build_embed( + title="User Forfeited Role", + description=f"{role.mention} taken from {ctx.author.mention}", + fields=fields, + ) + + embed.set_thumbnail(url=ctx.guild.icon_url) + embed.set_author( + name=ctx.author.nick if ctx.author.nick else ctx.author.name, + icon_url=ctx.author.avatar_url, + ) + + embed.set_footer( + text=f"{ctx.author.name}#{ctx.author.discriminator} " + + f"| {ctx.author.id}" + ) + + await ctx.send(embed=embed) + + +def setup(bot): + bot.add_cog(RolegiverCog(bot)) diff --git a/jarvis/cogs/util.py b/jarvis/cogs/util.py index 809791f..6c44b73 100644 --- a/jarvis/cogs/util.py +++ b/jarvis/cogs/util.py @@ -1,9 +1,11 @@ import re +from io import BytesIO -from discord import User +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 @@ -118,6 +120,111 @@ class UtilCog(commands.Cog): ) await ctx.send(embed=embed) + @cog_ext.cog_slash( + name="roleinfo", + description="Get role info", + 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", + 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))