diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/carbon.py | 40 | ||||
-rw-r--r-- | modules/converters.py | 51 | ||||
-rw-r--r-- | modules/dump.py | 60 |
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: |