diff --git a/jarvis/cogs/dev.py b/jarvis/cogs/dev.py index 9ab06be..18194f3 100644 --- a/jarvis/cogs/dev.py +++ b/jarvis/cogs/dev.py @@ -5,8 +5,11 @@ import re import ulid import base64 import subprocess -import traceback -import inspect +from inspect import getsource +import discord +import time +import sys +import os from discord.ext import commands from jarvis.utils import build_embed, convert_bytesize from jarvis.utils.field import Field @@ -238,15 +241,70 @@ class DevCog(commands.Cog): output = subprocess.check_output(["cloc", "."]).decode("UTF-8") await ctx.send(f"```\n{output}\n```") - @commands.command(name="eval") + def resolve_variable(self, variable): + if hasattr(variable, "__iter__"): + var_length = len(list(variable)) + if (var_length > 100) and (not isinstance(variable, str)): + return f"" + elif not var_length: + return f"" + + if (not variable) and (not isinstance(variable, bool)): + return f"" + return ( + variable + if (len(f"{variable}") <= 1000) + else f"" + ) + + def prepare(self, string): + arr = ( + string.strip("```") + .replace("py\n", "") + .replace("python\n", "") + .split("\n") + ) + if not arr[::-1][0].replace(" ", "").startswith("return"): + arr[len(arr) - 1] = "return " + arr[::-1][0] + return "".join(f"\n\t{i}" for i in arr) + + @commands.command(pass_context=True, aliases=["eval", "exec", "evaluate"]) @commands.is_owner() async def _eval(self, ctx, *, code: str): - code = f"async def fn():{code}" + silent = "-s" in code + + code = self.prepare(code.replace("-s", "")) + args = { + "discord": discord, + "sauce": getsource, + "sys": sys, + "os": os, + "imp": __import__, + "this": self, + "ctx": ctx, + } + try: - output = exec(code, globals(), locals()) - except Exception: - output = traceback.format_exc() - await ctx.send(f"```{output}```") + exec(f"async def func():{code}", args) + a = time() + response = await eval("func()", args) + if ( + silent + or (response is None) + or isinstance(response, discord.Message) + ): + del args, code + return + + await ctx.send( + f"```py\n{self.resolve_variable(response)}````{type(response).__name__} | {(time() - a) / 1000} ms`" + ) + except Exception as e: + await ctx.send( + f"Error occurred:```\n{type(e).__name__}: {str(e)}```" + ) + + del args, code, silent def setup(bot):