From c2475a0ccba7cad68e2384f11ea26d29b6c83420 Mon Sep 17 00:00:00 2001 From: Zevaryx Date: Thu, 5 Aug 2021 16:55:48 -0600 Subject: [PATCH] Close #77, also remove standard commands from dev cogs. Use selects for hash, encode, decode, uuid --- jarvis/cogs/dev.py | 283 ++++++++++++++++++++------------------------- 1 file changed, 128 insertions(+), 155 deletions(-) diff --git a/jarvis/cogs/dev.py b/jarvis/cogs/dev.py index 88a1c08..a65c55f 100644 --- a/jarvis/cogs/dev.py +++ b/jarvis/cogs/dev.py @@ -2,12 +2,13 @@ import base64 import hashlib import re import subprocess -import uuid +import uuid as uuidpy -import ulid +import ulid as ulidpy from bson import ObjectId from discord.ext import commands from discord_slash import cog_ext +from discord_slash.utils.manage_commands import create_choice, create_option from jarvis.utils import build_embed, convert_bytesize from jarvis.utils.field import Field @@ -39,7 +40,12 @@ UUID_VERIFY = re.compile( re.IGNORECASE, ) -UUID_GET = {3: uuid.uuid3, 5: uuid.uuid5} +invites = re.compile( + r"(?:https?://)?(?:www.)?(?:discord.(?:gg|io|me|li)|discord(?:app)?.com/invite)/([^\s/]+?)(?=\b)", + flags=re.IGNORECASE, +) + +UUID_GET = {3: uuidpy.uuid3, 5: uuidpy.uuid5} def hash_obj(hash, data, text: bool = True) -> str: @@ -64,24 +70,36 @@ class DevCog(commands.Cog): def __init__(self, bot): self.bot = bot - async def _hash(self, ctx, method: str, *, data: str = None): - if method not in supported_hashes: - algo_txt = ", ".join(f"`{x}`" for x in supported_hashes) + @cog_ext.cog_slash( + name="hash", + description="Hash some data", + options=[ + create_option( + name="method", + description="Hash method", + option_type=3, + required=True, + choices=[ + create_choice(name=x, value=x) for x in supported_hashes + ], + ), + create_option( + name="data", + description="Data to hash", + option_type=3, + required=True, + ), + ], + ) + @commands.cooldown(1, 2, commands.BucketType.user) + async def _hash(self, ctx, method: str, data: str): + if not data: await ctx.send( - "Unsupported hash algorithm. Supported:\n" + algo_txt, + "No data to hash", hidden=True, ) return - if not data and len(ctx.message.attachments) == 0: - await ctx.send( - "No data to hash. Either attach a file or send text to hash" - ) - return text = True - if len(ctx.message.attachments) > 0: - text = False - data = await ctx.message.attachments[0].read() - # Default to sha256, just in case hash = getattr(hashlib, method, hashlib.sha256)() hex = hash_obj(hash, data, text) @@ -98,206 +116,161 @@ class DevCog(commands.Cog): ) await ctx.send(embed=embed) - @commands.command(name="hash") - @commands.cooldown(1, 2, commands.BucketType.user) - async def _hash_pref(self, ctx, method: str, *, data: str = None): - await self._hash(ctx, method, data=data) - @cog_ext.cog_slash( - name="hash", - description="Hash some data", + name="uuid", + description="Generate a UUID", + options=[ + create_option( + name="version", + description="UUID version", + option_type=3, + required=True, + choices=[ + create_choice(name=x, value=x) for x in ["3", "4", "5"] + ], + ), + create_option( + name="data", + description="Data for UUID version 3,5", + option_type=3, + required=False, + ), + ], ) - @commands.cooldown(1, 2, commands.BucketType.user) - async def _hash_slash(self, ctx, method: str, *, data: str = None): - await self._hash(ctx, method, data=data) - - async def _uuid(self, ctx, version: str = None, data: str = None): - if not version: - await ctx.send("Supported UUID versions: 3, 4, 5", hidden=True) - return - if version not in ["3", "4", "5"]: - await ctx.send("Supported UUID versions: 3, 4, 5", hidden=True) - return + async def _uuid(self, ctx, version: str, data: str = None): version = int(version) if version in [3, 5] and not data: await ctx.send(f"UUID{version} requires data.", hidden=True) return if version == 4: - await ctx.send(f"UUID4: `{uuid.uuid4()}`") + await ctx.send(f"UUID4: `{uuidpy.uuid4()}`") else: to_send = None if OID_VERIFY.match(data): - to_send = UUID_GET[version](uuid.NAMESPACE_OID, data) + to_send = UUID_GET[version](uuidpy.NAMESPACE_OID, data) elif URL_VERIFY.match(data): - to_send = UUID_GET[version](uuid.NAMESPACE_URL, data) + to_send = UUID_GET[version](uuidpy.NAMESPACE_URL, data) elif DN_VERIFY.match(data): - to_send = UUID_GET[version](uuid.NAMESPACE_X500, data) + to_send = UUID_GET[version](uuidpy.NAMESPACE_X500, data) else: - to_send = UUID_GET[version](uuid.NAMESPACE_DNS, data) + to_send = UUID_GET[version](uuidpy.NAMESPACE_DNS, data) await ctx.send(f"UUID{version}: `{to_send}`") - @commands.command(name="uuid") - @commands.cooldown(1, 2, commands.BucketType.user) - async def _uuid_pref(self, ctx, version: str = None, data: str = None): - await self._uuid(ctx, version, data) - - @cog_ext.cog_slash( - name="uuid", - description="Generate a UUID", - ) - @commands.cooldown(1, 2, commands.BucketType.user) - async def _uuid_slash(self, ctx, version: str = None, data: str = None): - await self._uuid(ctx, version, data) - - async def _objectid(self, ctx): - """Generates new bson.ObjectId""" - await ctx.send(f"ObjectId: `{str(ObjectId())}`") - - @commands.command(name="objectid") - @commands.cooldown(1, 2, commands.BucketType.user) - async def _objectid_pref(self, ctx): - await self._objectid(ctx) - @cog_ext.cog_slash( name="objectid", description="Generate an ObjectID", ) @commands.cooldown(1, 2, commands.BucketType.user) - async def _objectid_slash(self, ctx): - await self._objectid(ctx) - - async def _ulid(self, ctx): - """Generates a new ULID""" - await ctx.send(f"ULID: `{ulid.new().str}`") - - @commands.command(name="ulid") - @commands.cooldown(1, 2, commands.BucketType.user) - async def _ulid_pref(self, ctx): - await self._ulid(ctx) + async def _objectid(self, ctx): + """Generates new bson.ObjectId""" + await ctx.send(f"ObjectId: `{str(ObjectId())}`") @cog_ext.cog_slash( name="ulid", description="Generate a ULID", ) @commands.cooldown(1, 2, commands.BucketType.user) - async def _ulid_slash(self, ctx): - await self._ulid(ctx) - - async def _uuid2ulid(self, ctx: commands.Context, u): - """Converts a UUID to a ULID""" - if UUID_VERIFY.match(u): - u = ulid.parse(u) - await ctx.send(f"ULID: `{u.str}`") - else: - await ctx.send("Invalid UUID") - - @commands.command(name="uuid2ulid") - @commands.cooldown(1, 2, commands.BucketType.user) - async def _uuid2ulid_pref(self, ctx, u: str): - await self._uuid2ulid(ctx, u) + async def _ulid(self, ctx): + """Generates a new ULID""" + await ctx.send(f"ULID: `{ulidpy.new().str}`") @cog_ext.cog_slash( name="uuid2ulid", description="Convert a UUID to a ULID", ) @commands.cooldown(1, 2, commands.BucketType.user) - async def _uuid2ulid_slash(self, ctx, u: str): - await self._uuid2ulid(ctx, u) - - async def _ulid2uuid(self, ctx: commands.Context, u): - """Converts a ULID to a UUID""" - if ULID_VERIFY.match(u): - u = ulid.parse(u) - await ctx.send(f"UUID: `{u.uuid}`") + async def _uuid2ulid(self, ctx: commands.Context, uuid): + """Converts a UUID to a ULID""" + if UUID_VERIFY.match(uuid): + u = ulidpy.parse(uuid) + await ctx.send(f"ULID: `{u.str}`") else: - await ctx.send("Invalid ULID.") - - @commands.command(name="ulid2uuid") - @commands.cooldown(1, 2, commands.BucketType.user) - async def _ulid2uuid_pref(self, ctx, u): - await self._ulid2uuid(ctx, u) + await ctx.send("Invalid UUID") @cog_ext.cog_slash( name="ulid2uuid", description="Convert a ULID to a UUID", ) @commands.cooldown(1, 2, commands.BucketType.user) - async def _ulid2uuid_slash(self, ctx, u): - await self._ulid2uuid(ctx, u) + async def _ulid2uuid(self, ctx: commands.Context, ulid): + """Converts a ULID to a UUID""" + if ULID_VERIFY.match(ulid): + ulid = ulidpy.parse(ulid) + await ctx.send(f"UUID: `{ulid.uuid}`") + else: + await ctx.send("Invalid ULID.") base64_methods = ["b64", "b16", "b32", "a85", "b85"] + @cog_ext.cog_slash( + name="encode", + description="Encode some data", + options=[ + create_option( + name="method", + description="Encode method", + option_type=3, + required=True, + choices=[ + create_choice(name=x, value=x) for x in base64_methods + ], + ), + create_option( + name="data", + description="Data to encode", + option_type=3, + required=True, + ), + ], + ) async def _encode(self, ctx, method: str, data: str): """Encodes text with specified encoding method""" - if method not in self.base64_methods: - methods = ", ".join(f"`{x}`" for x in self.base64_methods) - await ctx.send( - "Usage: encode \nSupported methods:\n" - + methods, - hidden=True, - ) - return method = getattr(base64, method + "encode") await ctx.send(f"`{method(data.encode('UTF-8')).decode('UTF-8')}`") - @commands.command(name="encode") - @commands.cooldown(1, 2, commands.BucketType.user) - async def _encode_pref(self, ctx, method: str, *, data: str): - await self._encode(ctx, method, data) - @cog_ext.cog_slash( - name="encode", - description="Encode using the base64 module", + name="decode", + description="Decode some data", + options=[ + create_option( + name="method", + description="Decode method", + option_type=3, + required=True, + choices=[ + create_choice(name=x, value=x) for x in base64_methods + ], + ), + create_option( + name="data", + description="Data to encode", + option_type=3, + required=True, + ), + ], ) - @commands.cooldown(1, 2, commands.BucketType.user) - async def _encode_slash(self, ctx, method: str, *, data: str): - await self._encode(ctx, method, data) - async def _decode(self, ctx, method: str, data: str): """Decodes text with specified encoding method""" - if method not in self.base64_methods: - methods = ", ".join(f"`{x}`" for x in self.base64_methods) + method = getattr(base64, method + "decode") + decoded = method(data.encode("UTF-8")).decode("UTF-8") + if invites.search(decoded): await ctx.send( - "Usage: decode \nSupported methods:\n" - + methods, + "Please don't use this to bypass invite restrictions", hidden=True, ) return - method = getattr(base64, method + "decode") - await ctx.send(f"`{method(data.encode('UTF-8')).decode('UTF-8')}`") - - @commands.command(name="decode") - @commands.cooldown(1, 2, commands.BucketType.user) - async def _decode_pref(self, ctx, method: str, *, data: str): - await self._decode(ctx, method, data) - - @cog_ext.cog_slash( - name="decode", - description="Decode using the base64 module", - ) - @commands.cooldown(1, 2, commands.BucketType.user) - async def _decode_slash(self, ctx, method: str, *, data: str): - await self._decode(ctx, method, data) - - async def _cloc(self, ctx): - output = subprocess.check_output( - ["tokei", "-C", "--sort", "code"] - ).decode("UTF-8") - await ctx.send(f"```\n{output}\n```") - - @commands.command(name="cloc", help="Get J.A.R.V.I.S. lines of code") - @commands.cooldown(1, 30, commands.BucketType.channel) - async def _cloc_pref(self, ctx): - await self._cloc(ctx) + await ctx.send(f"`{decoded}`") @cog_ext.cog_slash( name="cloc", description="Get J.A.R.V.I.S. lines of code", ) @commands.cooldown(1, 30, commands.BucketType.channel) - async def _cloc_slash(self, ctx): - await ctx.defer() - await self._cloc(ctx) + async def _cloc(self, ctx): + output = subprocess.check_output( + ["tokei", "-C", "--sort", "code"] + ).decode("UTF-8") + await ctx.send(f"```\n{output}\n```") def setup(bot):