aboutsummaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/carbon.py40
-rw-r--r--modules/converters.py51
-rw-r--r--modules/dump.py60
3 files changed, 150 insertions, 1 deletions
diff --git a/modules/carbon.py b/modules/carbon.py
new file mode 100644
index 0000000..1031586
--- /dev/null
+++ b/modules/carbon.py
@@ -0,0 +1,40 @@
+import re
+from pathlib import Path
+from subprocess import Popen, PIPE
+from typing import Pattern
+
+from discord import File
+from discord.ext.commands import Bot, command, Context
+
+from .converters import CodeBlock
+
+TEMP_DIR: Path = (Path(__file__).parent / '..' / 'carbon-temp').resolve()
+TEMP_DIR.mkdir(parents=True, exist_ok=True)
+regex: Pattern = re.compile(b" (/[^ ]+) ")
+
+
+class Carbon(object):
+ def __init__(self, bot: Bot):
+ self.bot: Bot = bot
+
+ @command()
+ async def carbon(self, ctx: Context, *, code_block: CodeBlock):
+ print('carbon thingies..')
+ temp_file: Path = (TEMP_DIR / ('carbon.' + code_block.extension))
+ with temp_file.open('w') as cf:
+ cf.write(code_block.source)
+ proc = Popen(['carbon-now', '-p', 'notaselfbot', '-l', str(TEMP_DIR), str(temp_file)], stdout=PIPE)
+ proc.wait()
+ stdout, _ = proc.communicate()
+ match = None
+ for match in regex.finditer(stdout):
+ pass
+ if not match:
+ return await ctx.react('❌')
+ path = match.group(1).decode('ascii')
+ with open(path, 'br') as fp:
+ await ctx.send(file=File(fp, 'carbon.png'))
+
+
+def setup(bot: Bot):
+ bot.add_cog(Carbon(bot))
diff --git a/modules/converters.py b/modules/converters.py
index f86ff59..a84a03e 100644
--- a/modules/converters.py
+++ b/modules/converters.py
@@ -1,8 +1,59 @@
from string import digits
from discord import TextChannel
+from discord.ext import commands
from discord.ext.commands import Converter, Context, Bot, BadArgument, converter
+LANGUAGES = {
+ 'python': ['py', 'py3'],
+ 'javascript': ['js'],
+ 'c': ['c'],
+ 'cpp': ['c++', 'cpp', 'cxx'],
+ 'go': ['go'],
+ 'bash': [],
+ 'xml': [],
+ 'html': [],
+}
+
+LANGUAGES_INV = {
+ **{v: k for k, v in LANGUAGES.items() for v in v},
+ **{k: k for k in LANGUAGES.keys()},
+}
+
+EXTENSIONS = dict(
+ python='py',
+ c='c',
+ cpp='cpp',
+ bash='sh',
+ javascript='js',
+)
+
+
+class CodeBlock:
+ missing_error = 'Missing code block. Please use the following markdown\n\\`\\`\\`language\ncode here\n\\`\\`\\`'
+
+ def __init__(self, argument):
+ try:
+ block, code = argument.split('\n', 1)
+ except ValueError:
+ raise commands.BadArgument(self.missing_error)
+
+ if not block.startswith('```') and not code.endswith('```'):
+ raise commands.BadArgument(self.missing_error)
+
+ language = block[3:]
+ self.language = self._get_language(language.lower())
+ self.source = code.rstrip('`')
+ self.extension = self._get_extension(self.language)
+
+ @staticmethod
+ def _get_extension(language):
+ return EXTENSIONS[language]
+
+ @staticmethod
+ def _get_language(language):
+ return LANGUAGES_INV.get(language)
+
def is_int(text):
return all(map(digits.__contains__, text))
diff --git a/modules/dump.py b/modules/dump.py
index 5281d7d..05d10a9 100644
--- a/modules/dump.py
+++ b/modules/dump.py
@@ -1,6 +1,9 @@
+import re
+from asyncio import sleep
+from functools import wraps
from typing import List
-from discord import User, Embed, Profile, Guild, Member, Permissions, Message
+from discord import User, Embed, Profile, Guild, Member, Permissions, Message, Role, Emoji, TextChannel
from discord.ext.commands import Bot, command, Context as CommandContext, Context
@@ -20,6 +23,17 @@ def dump_perms(permissions: Permissions):
return ', '.join(perm_names())
+def then_delete(cmd):
+ @wraps(cmd)
+ async def func(*args, **kwargs):
+ mes = await cmd(*args, **kwargs)
+ if mes and hasattr(mes, 'delete'):
+ await sleep(30)
+ await mes.delete()
+
+ return func
+
+
class DumpCog(object):
def __init__(self, bot: Bot):
self.bot = bot
@@ -31,6 +45,50 @@ class DumpCog(object):
await ctx.send(content=f'```\n{escaped}\n```')
await ctx.react('✅')
+ @command(aliases=['resolve'])
+ @then_delete
+ async def resolve_id(self, ctx: CommandContext, snowflake):
+ snowflake = re.sub(r'[^0-9]', '', snowflake)
+ if not snowflake:
+ return await ctx.send("No id")
+ snowflake = int(snowflake)
+ if snowflake <= 0:
+ return await ctx.send("Invalid id")
+ when = (snowflake >> 22) + 1420070400000
+ worker = (snowflake & 0x3E0000) >> 17
+ process = (snowflake & 0x1F000) >> 12
+ increment = snowflake & 0xFFF
+
+ channel: TextChannel = self.bot.get_channel(snowflake)
+ user: User = self.bot.get_user(snowflake)
+ guild: Guild = self.bot.get_guild(snowflake)
+ emoji: Emoji = self.bot.get_emoji(snowflake)
+ roles: List[Role] = [role for guild in self.bot.guilds for role in guild.roles if role.id == snowflake]
+ role: Role = roles[0] if len(roles) > 0 else None
+
+ embed = Embed(title=f"ID: {snowflake}")
+ embed.add_field(name="When", value=str(when))
+ embed.add_field(name="Worker", value=str(worker))
+ embed.add_field(name="Process", value=str(process))
+ embed.add_field(name="Increment", value=str(increment))
+
+ def add_if(name, thing, note=''):
+ if thing:
+ embed.add_field(name="Type", value=name)
+ embed.add_field(name="Data", value=f"```\n{thing!r}\n```{note}")
+ return True
+ return False
+
+ if not any(x for x in [
+ add_if("Guild", guild, "This may also be the default channel of the @everyone role of that server"),
+ add_if("Channel", channel),
+ add_if("User", user),
+ add_if("Role", role),
+ add_if("Emoji", emoji),
+ ]):
+ embed.add_field(name="Type", value="Not found.")
+ await ctx.send(embed=embed)
+
@command()
async def user(self, ctx: CommandContext, user: User, guild: Guild = None):
if guild is None and ctx.guild is not None: