Close #77, also remove standard commands from dev cogs. Use selects for hash, encode, decode, uuid
This commit is contained in:
parent
e83b9064bf
commit
c2475a0ccb
1 changed files with 128 additions and 155 deletions
|
@ -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):
|
||||||
|
|
Loading…
Add table
Reference in a new issue