Close #77, also remove standard commands from dev cogs. Use selects for hash, encode, decode, uuid

This commit is contained in:
Zeva Rose 2021-08-05 16:55:48 -06:00
parent e83b9064bf
commit c2475a0ccb

View file

@ -2,12 +2,13 @@ import base64
import hashlib import hashlib
import re import re
import subprocess import subprocess
import uuid import uuid as uuidpy
import ulid import ulid as ulidpy
from bson import ObjectId from bson import ObjectId
from discord.ext import commands from discord.ext import commands
from discord_slash import cog_ext 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 import build_embed, convert_bytesize
from jarvis.utils.field import Field from jarvis.utils.field import Field
@ -39,7 +40,12 @@ UUID_VERIFY = re.compile(
re.IGNORECASE, 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: def hash_obj(hash, data, text: bool = True) -> str:
@ -64,24 +70,36 @@ class DevCog(commands.Cog):
def __init__(self, bot): def __init__(self, bot):
self.bot = bot self.bot = bot
async def _hash(self, ctx, method: str, *, data: str = None): @cog_ext.cog_slash(
if method not in supported_hashes: name="hash",
algo_txt = ", ".join(f"`{x}`" for x in supported_hashes) 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( await ctx.send(
"Unsupported hash algorithm. Supported:\n" + algo_txt, "No data to hash",
hidden=True, hidden=True,
) )
return 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 text = True
if len(ctx.message.attachments) > 0:
text = False
data = await ctx.message.attachments[0].read()
# Default to sha256, just in case # Default to sha256, just in case
hash = getattr(hashlib, method, hashlib.sha256)() hash = getattr(hashlib, method, hashlib.sha256)()
hex = hash_obj(hash, data, text) hex = hash_obj(hash, data, text)
@ -98,206 +116,161 @@ class DevCog(commands.Cog):
) )
await ctx.send(embed=embed) 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( @cog_ext.cog_slash(
name="hash", name="uuid",
description="Hash some data", 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 _uuid(self, ctx, version: str, data: str = None):
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
version = int(version) version = int(version)
if version in [3, 5] and not data: if version in [3, 5] and not data:
await ctx.send(f"UUID{version} requires data.", hidden=True) await ctx.send(f"UUID{version} requires data.", hidden=True)
return return
if version == 4: if version == 4:
await ctx.send(f"UUID4: `{uuid.uuid4()}`") await ctx.send(f"UUID4: `{uuidpy.uuid4()}`")
else: else:
to_send = None to_send = None
if OID_VERIFY.match(data): 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): 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): elif DN_VERIFY.match(data):
to_send = UUID_GET[version](uuid.NAMESPACE_X500, data) to_send = UUID_GET[version](uuidpy.NAMESPACE_X500, data)
else: 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}`") 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( @cog_ext.cog_slash(
name="objectid", name="objectid",
description="Generate an ObjectID", description="Generate an ObjectID",
) )
@commands.cooldown(1, 2, commands.BucketType.user) @commands.cooldown(1, 2, commands.BucketType.user)
async def _objectid_slash(self, ctx): async def _objectid(self, ctx):
await self._objectid(ctx) """Generates new bson.ObjectId"""
await ctx.send(f"ObjectId: `{str(ObjectId())}`")
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)
@cog_ext.cog_slash( @cog_ext.cog_slash(
name="ulid", name="ulid",
description="Generate a ULID", description="Generate a ULID",
) )
@commands.cooldown(1, 2, commands.BucketType.user) @commands.cooldown(1, 2, commands.BucketType.user)
async def _ulid_slash(self, ctx): async def _ulid(self, ctx):
await self._ulid(ctx) """Generates a new ULID"""
await ctx.send(f"ULID: `{ulidpy.new().str}`")
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)
@cog_ext.cog_slash( @cog_ext.cog_slash(
name="uuid2ulid", name="uuid2ulid",
description="Convert a UUID to a ULID", description="Convert a UUID to a ULID",
) )
@commands.cooldown(1, 2, commands.BucketType.user) @commands.cooldown(1, 2, commands.BucketType.user)
async def _uuid2ulid_slash(self, ctx, u: str): async def _uuid2ulid(self, ctx: commands.Context, uuid):
await self._uuid2ulid(ctx, u) """Converts a UUID to a ULID"""
if UUID_VERIFY.match(uuid):
async def _ulid2uuid(self, ctx: commands.Context, u): u = ulidpy.parse(uuid)
"""Converts a ULID to a UUID""" await ctx.send(f"ULID: `{u.str}`")
if ULID_VERIFY.match(u):
u = ulid.parse(u)
await ctx.send(f"UUID: `{u.uuid}`")
else: else:
await ctx.send("Invalid ULID.") await ctx.send("Invalid UUID")
@commands.command(name="ulid2uuid")
@commands.cooldown(1, 2, commands.BucketType.user)
async def _ulid2uuid_pref(self, ctx, u):
await self._ulid2uuid(ctx, u)
@cog_ext.cog_slash( @cog_ext.cog_slash(
name="ulid2uuid", name="ulid2uuid",
description="Convert a ULID to a UUID", description="Convert a ULID to a UUID",
) )
@commands.cooldown(1, 2, commands.BucketType.user) @commands.cooldown(1, 2, commands.BucketType.user)
async def _ulid2uuid_slash(self, ctx, u): async def _ulid2uuid(self, ctx: commands.Context, ulid):
await self._ulid2uuid(ctx, u) """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"] 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): async def _encode(self, ctx, method: str, data: str):
"""Encodes text with specified encoding method""" """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 <method> <data>\nSupported methods:\n"
+ methods,
hidden=True,
)
return
method = getattr(base64, method + "encode") method = getattr(base64, method + "encode")
await ctx.send(f"`{method(data.encode('UTF-8')).decode('UTF-8')}`") 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( @cog_ext.cog_slash(
name="encode", name="decode",
description="Encode using the base64 module", 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): async def _decode(self, ctx, method: str, data: str):
"""Decodes text with specified encoding method""" """Decodes text with specified encoding method"""
if method not in self.base64_methods: method = getattr(base64, method + "decode")
methods = ", ".join(f"`{x}`" for x in self.base64_methods) decoded = method(data.encode("UTF-8")).decode("UTF-8")
if invites.search(decoded):
await ctx.send( await ctx.send(
"Usage: decode <method> <data>\nSupported methods:\n" "Please don't use this to bypass invite restrictions",
+ methods,
hidden=True, hidden=True,
) )
return return
method = getattr(base64, method + "decode") await ctx.send(f"`{decoded}`")
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)
@cog_ext.cog_slash( @cog_ext.cog_slash(
name="cloc", name="cloc",
description="Get J.A.R.V.I.S. lines of code", description="Get J.A.R.V.I.S. lines of code",
) )
@commands.cooldown(1, 30, commands.BucketType.channel) @commands.cooldown(1, 30, commands.BucketType.channel)
async def _cloc_slash(self, ctx): async def _cloc(self, ctx):
await ctx.defer() output = subprocess.check_output(
await self._cloc(ctx) ["tokei", "-C", "--sort", "code"]
).decode("UTF-8")
await ctx.send(f"```\n{output}\n```")
def setup(bot): def setup(bot):