diff --git a/jarvis/cogs/dev.py b/jarvis/cogs/dev.py index bff434b..d6ecf01 100644 --- a/jarvis/cogs/dev.py +++ b/jarvis/cogs/dev.py @@ -1,14 +1,43 @@ import jarvis import hashlib +import uuid +import re +import ulid from discord.ext import commands from jarvis.utils import build_embed, convert_bytesize from jarvis.utils.field import Field +from bson import ObjectId supported_hashes = { x for x in hashlib.algorithms_guaranteed if "shake" not in x } +OID_VERIFY = re.compile(r"^([1-9][0-9]{0,3}|0)(\.([1-9][0-9]{0,3}|0)){5,13}$") +URL_VERIFY = re.compile( + r"http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]" + + r"|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+" +) +DN_VERIFY = re.compile( + r"^(?:(?PCN=(?P[^,]*)),)" + + r"?(?:(?P(?:(?:CN|OU)=[^,]+,?)+),)" + + r"?(?P(?:DC=[^,]+,?)+)$" +) +ULID_VERIFY = re.compile(r"^[0-9a-z]{26}$", re.IGNORECASE) +UUID_VERIFY = re.compile( + ( + "[a-f0-9]{8}-" + + "[a-f0-9]{4}-" + + "[1-5]" + + "[a-f0-9]{3}-" + + "[89ab][a-f0-9]{3}-" + + "[a-f0-9]{12}$" + ), + re.IGNORECASE, +) + +UUID_GET = {3: uuid.uuid3, 5: uuid.uuid5} + def hash_obj(hash, data, text: bool = True) -> str: """ @@ -22,9 +51,9 @@ def hash_obj(hash, data, text: bool = True) -> str: BSIZE = 65536 block_idx = 0 while block_idx * BSIZE < len(data): - block = data[BSIZE * block_idx:BSIZE * (block_idx + 1)] - hash.update(block) - block_idx += 1 + block = data[BSIZE * block_idx : BSIZE * (block_idx + 1)] + hash.update(block) + block_idx += 1 return hash.hexdigest() @@ -58,7 +87,7 @@ class DevCog(commands.Cog): description = "Hashed using " + method fields = [ Field("Data Size", data_size, False), - Field("Hash", hex, False), + Field("Hash", f"`{hex}`", False), ] embed = build_embed( @@ -66,6 +95,60 @@ class DevCog(commands.Cog): ) await ctx.send(embed=embed) + @commands.command(name="uuid") + async def _uuid(self, ctx, version: str = None, data: str = None): + if not version: + await ctx.send("Supported UUID versions: 3, 4, 5") + return + if version not in ["3", "4", "5"]: + await ctx.send("Supported UUID versions: 3, 4, 5") + return + version = int(version) + if version in [3, 5] and not data: + await ctx.send(f"UUID{version} requires data.") + return + if version == 4: + await ctx.send(f"UUID4: `{uuid.uuid4()}``") + else: + to_send = None + if OID_VERIFY.match(data): + to_send = UUID_GET[version](uuid.NAMESPACE_OID, data) + elif URL_VERIFY.match(data): + to_send = UUID_GET[version](uuid.NAMESPACE_URL, data) + elif DN_VERIFY.match(data): + to_send = UUID_GET[version](uuid.NAMESPACE_X500, data) + else: + to_send = UUID_GET[version](uuid.NAMESPACE_DNS, data) + await ctx.send(f"UUID{version}: `{to_send}`") + + @commands.command(name="objectid") + async def _objectid(self, ctx: commands.Context): + """Generates new bson.ObjectId""" + await ctx.send(f"ObjectId: `{str(ObjectId())}`") + + @commands.command(name="ulid") + async def _ulid(self, ctx: commands.Context): + """Generates a new ULID""" + await ctx.send(f"ULID: `{ulid.new().str}`") + + @commands.command(name="uuid2ulid") + 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="ulid2uuid") + 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}`") + else: + await ctx.send("Invalid ULID.") + def setup(bot): bot.add_cog(DevCog(bot))