Spaces:
Paused
Paused
Update plugins/devtools.py
Browse files- plugins/devtools.py +98 -145
plugins/devtools.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
| 2 |
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
#
|
| 4 |
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
-
#
|
| 6 |
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
|
| 8 |
from . import get_help
|
|
@@ -12,130 +12,40 @@ __doc__ = get_help("help_devtools")
|
|
| 12 |
import inspect
|
| 13 |
import sys
|
| 14 |
import traceback
|
| 15 |
-
import time
|
| 16 |
-
import json
|
| 17 |
from io import BytesIO, StringIO
|
| 18 |
from os import remove
|
| 19 |
from pprint import pprint
|
| 20 |
-
from random import choice
|
| 21 |
-
from html import escape
|
| 22 |
|
| 23 |
from telethon.utils import get_display_name
|
| 24 |
-
from telethon.tl import functions
|
| 25 |
|
| 26 |
-
# project imports (assumed available in Ultroid context)
|
| 27 |
from pyUltroid import _ignore_eval
|
| 28 |
-
from . import * # noqa: F401,F403
|
| 29 |
-
from . import upload_file as uf # upload helper used to upload Carbon images
|
| 30 |
|
| 31 |
-
|
|
|
|
|
|
|
| 32 |
try:
|
| 33 |
import black
|
| 34 |
-
except
|
| 35 |
black = None
|
|
|
|
| 36 |
|
| 37 |
try:
|
| 38 |
from yaml import safe_load
|
| 39 |
-
except
|
| 40 |
-
from pyUltroid.fns.tools import safe_load
|
| 41 |
-
|
| 42 |
-
fn = functions
|
| 43 |
-
|
| 44 |
-
pp = pprint # alias kept from original
|
| 45 |
-
bot = ultroid = ultroid_bot # ensure these names exist in project
|
| 46 |
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
# ---------------------------------------------------------------------
|
| 51 |
-
# Helper: parse eval-friendly representation of values
|
| 52 |
-
# (kept mostly as original)
|
| 53 |
-
def _parse_eval(value=None):
|
| 54 |
-
if not value:
|
| 55 |
-
return value
|
| 56 |
-
if hasattr(value, "stringify"):
|
| 57 |
-
try:
|
| 58 |
-
return value.stringify()
|
| 59 |
-
except TypeError:
|
| 60 |
-
pass
|
| 61 |
-
elif isinstance(value, dict):
|
| 62 |
-
try:
|
| 63 |
-
return json.dumps(value, indent=1, default=str)
|
| 64 |
-
except BaseException:
|
| 65 |
-
pass
|
| 66 |
-
elif isinstance(value, list):
|
| 67 |
-
newlist = "["
|
| 68 |
-
for index, child in enumerate(value):
|
| 69 |
-
newlist += "\n " + str(_parse_eval(child))
|
| 70 |
-
if index < len(value) - 1:
|
| 71 |
-
newlist += ","
|
| 72 |
-
newlist += "\n]"
|
| 73 |
-
return newlist
|
| 74 |
-
return str(value)
|
| 75 |
-
|
| 76 |
-
# ---------------------------------------------------------------------
|
| 77 |
-
# Exec wrapper: runs user-supplied async code in custom namespace.
|
| 78 |
-
# WARNING: This runs arbitrary code via exec() — ensure only trusted users can use it.
|
| 79 |
-
async def aexec(code: str, event):
|
| 80 |
-
"""
|
| 81 |
-
Execute `code` (containing Python source for the body of an async function)
|
| 82 |
-
as an async function __aexec(e, client) and run it.
|
| 83 |
-
|
| 84 |
-
Returns whatever the executed function returns.
|
| 85 |
-
|
| 86 |
-
NOTE: This function intentionally exposes a number of objects to the executed
|
| 87 |
-
namespace (client, event, reply, etc.). This is powerful and dangerous — keep
|
| 88 |
-
access restricted (only owner/devs).
|
| 89 |
-
"""
|
| 90 |
-
# Precompute reply message (do this before creating exec_globals)
|
| 91 |
-
try:
|
| 92 |
-
reply_msg = await event.get_reply_message()
|
| 93 |
-
except Exception:
|
| 94 |
-
reply_msg = None
|
| 95 |
-
|
| 96 |
-
# Dedicated namespace for execution. Keep builtins as in original, but this is
|
| 97 |
-
# a security risk — consider limiting builtins for untrusted usage.
|
| 98 |
-
exec_globals = {
|
| 99 |
-
"print": _stringify,
|
| 100 |
-
"p": _stringify,
|
| 101 |
-
"message": event,
|
| 102 |
-
"event": event,
|
| 103 |
-
"client": event.client,
|
| 104 |
-
"reply": reply_msg,
|
| 105 |
-
"chat": event.chat_id,
|
| 106 |
-
"u": u,
|
| 107 |
-
"__builtins__": __builtins__,
|
| 108 |
-
"__name__": __name__,
|
| 109 |
-
}
|
| 110 |
|
| 111 |
-
|
| 112 |
-
# We indent every line of `code` and place it under the function body.
|
| 113 |
-
wrapped_lines = []
|
| 114 |
-
for line in code.splitlines():
|
| 115 |
-
# Ensure even empty lines are indented properly
|
| 116 |
-
if line.strip() == "":
|
| 117 |
-
wrapped_lines.append(" pass")
|
| 118 |
-
else:
|
| 119 |
-
wrapped_lines.append(" " + line)
|
| 120 |
-
wrapped_code = "async def __aexec(e, client):\n" + "\n".join(wrapped_lines)
|
| 121 |
|
| 122 |
-
try:
|
| 123 |
-
# Execute the wrapper to create __aexec in exec_globals
|
| 124 |
-
exec(wrapped_code, exec_globals)
|
| 125 |
-
func = exec_globals["__aexec"]
|
| 126 |
-
# Call the newly created coroutine function
|
| 127 |
-
return await func(event, event.client)
|
| 128 |
-
except Exception as exc:
|
| 129 |
-
# Re-raise with clearer context (caller will handle formatting)
|
| 130 |
-
raise Exception(f"Failed to execute code: {str(exc)}")
|
| 131 |
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
async def _(e):
|
| 136 |
xx = await e.eor(get_string("com_1"))
|
| 137 |
-
|
| 138 |
-
x, y = await bash("neofetch|sed 's/\\x1B\\[[0-9;\\?]*[a-zA-Z]//g' >> neo.txt")
|
| 139 |
if y and y.endswith("NOT_FOUND"):
|
| 140 |
return await xx.edit(f"Error: `{y}`")
|
| 141 |
with open("neo.txt", "r", encoding="utf-8") as neo:
|
|
@@ -148,6 +58,7 @@ async def _(e):
|
|
| 148 |
await xx.delete()
|
| 149 |
remove("neo.txt")
|
| 150 |
|
|
|
|
| 151 |
@ultroid_cmd(pattern="bash", fullsudo=True, only_devs=True)
|
| 152 |
async def _(event):
|
| 153 |
carb, rayso, yamlf = None, None, False
|
|
@@ -161,7 +72,6 @@ async def _(event):
|
|
| 161 |
rayso = True
|
| 162 |
except IndexError:
|
| 163 |
return await event.eor(get_string("devs_1"), time=10)
|
| 164 |
-
|
| 165 |
xx = await event.eor(get_string("com_1"))
|
| 166 |
reply_to_id = event.reply_to_msg_id or event.id
|
| 167 |
stdout, stderr = await bash(cmd, run_code=1)
|
|
@@ -170,7 +80,6 @@ async def _(event):
|
|
| 170 |
if stderr:
|
| 171 |
err = f"**• ERROR:** \n`{stderr}`\n\n"
|
| 172 |
if stdout:
|
| 173 |
-
# When Carbon/Rayso output is requested and allowed by chat permissions:
|
| 174 |
if (carb or udB.get_key("CARBON_ON_BASH")) and (
|
| 175 |
event.is_private
|
| 176 |
or event.chat.admin_rights
|
|
@@ -215,7 +124,6 @@ async def _(event):
|
|
| 215 |
out = "**• OUTPUT:**"
|
| 216 |
remove(li)
|
| 217 |
else:
|
| 218 |
-
# treat pip-like keyed output as YAML and pretty-format
|
| 219 |
if "pip" in cmd and all(":" in line for line in stdout.split("\n")):
|
| 220 |
try:
|
| 221 |
load = safe_load(stdout)
|
|
@@ -234,9 +142,7 @@ async def _(event):
|
|
| 234 |
out = f"**• OUTPUT:**\n{stdout}"
|
| 235 |
if not stderr and not stdout:
|
| 236 |
out = "**• OUTPUT:**\n`Success`"
|
| 237 |
-
|
| 238 |
OUT += err + out
|
| 239 |
-
|
| 240 |
if len(OUT) > 4096:
|
| 241 |
ultd = err + out
|
| 242 |
with BytesIO(str.encode(ultd)) as out_file:
|
|
@@ -253,14 +159,40 @@ async def _(event):
|
|
| 253 |
|
| 254 |
await xx.delete()
|
| 255 |
else:
|
| 256 |
-
|
| 257 |
-
|
| 258 |
-
# Telethon accepts parse_mode='html' in edit calls in recent versions
|
| 259 |
-
await xx.edit(formatted_out, parse_mode="html", link_preview=False)
|
| 260 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 261 |
|
| 262 |
-
# alias kept
|
| 263 |
-
pp = pprint
|
| 264 |
|
| 265 |
@ultroid_cmd(pattern="eval", fullsudo=True, only_devs=True)
|
| 266 |
async def _(event):
|
|
@@ -268,7 +200,6 @@ async def _(event):
|
|
| 268 |
cmd = event.text.split(maxsplit=1)[1]
|
| 269 |
except IndexError:
|
| 270 |
return await event.eor(get_string("devs_2"), time=5)
|
| 271 |
-
|
| 272 |
xx = None
|
| 273 |
mode = ""
|
| 274 |
spli = cmd.split()
|
|
@@ -297,18 +228,13 @@ async def _(event):
|
|
| 297 |
return
|
| 298 |
if not mode == "silent" and not xx:
|
| 299 |
xx = await event.eor(get_string("com_1"))
|
| 300 |
-
|
| 301 |
-
# attempt to format with black if available (not critical)
|
| 302 |
if black:
|
| 303 |
try:
|
| 304 |
cmd = black.format_str(cmd, mode=black.Mode())
|
| 305 |
-
except
|
| 306 |
-
#
|
| 307 |
pass
|
| 308 |
-
|
| 309 |
-
reply_to_id = event.reply_to_msg_id or event.id
|
| 310 |
-
|
| 311 |
-
# SECURITY: detect and report potentially dangerous commands
|
| 312 |
if any(item in cmd for item in KEEP_SAFE().All) and (
|
| 313 |
not (event.out or event.sender_id == ultroid_bot.uid)
|
| 314 |
):
|
|
@@ -320,13 +246,11 @@ async def _(event):
|
|
| 320 |
return await xx.edit(
|
| 321 |
"`Malicious Activities suspected⚠️!\nReported to owner. Aborted this request!`"
|
| 322 |
)
|
| 323 |
-
|
| 324 |
-
# Capture stdout/stderr
|
| 325 |
old_stderr = sys.stderr
|
| 326 |
old_stdout = sys.stdout
|
| 327 |
redirected_output = sys.stdout = StringIO()
|
| 328 |
redirected_error = sys.stderr = StringIO()
|
| 329 |
-
|
| 330 |
tima = time.time()
|
| 331 |
try:
|
| 332 |
value = await aexec(cmd, event)
|
|
@@ -338,18 +262,18 @@ async def _(event):
|
|
| 338 |
stderr = redirected_error.getvalue()
|
| 339 |
sys.stdout = old_stdout
|
| 340 |
sys.stderr = old_stderr
|
| 341 |
-
|
| 342 |
if value:
|
| 343 |
try:
|
| 344 |
if mode == "gsource":
|
| 345 |
exc = inspect.getsource(value)
|
| 346 |
elif mode == "g-args":
|
| 347 |
args = inspect.signature(value).parameters.values()
|
| 348 |
-
name =
|
|
|
|
|
|
|
| 349 |
exc = f"**{name}**\n\n" + "\n ".join([str(arg) for arg in args])
|
| 350 |
except Exception:
|
| 351 |
exc = traceback.format_exc()
|
| 352 |
-
|
| 353 |
evaluation = exc or stderr or stdout or _parse_eval(value) or get_string("instu_4")
|
| 354 |
if mode == "silent":
|
| 355 |
if exc:
|
|
@@ -359,10 +283,11 @@ async def _(event):
|
|
| 359 |
if len(msg) > 4000:
|
| 360 |
with BytesIO(msg.encode()) as out_file:
|
| 361 |
out_file.name = "Eval-Error.txt"
|
| 362 |
-
return await event.client.send_message(
|
|
|
|
|
|
|
| 363 |
await event.client.send_message(log_chat, msg, parse_mode="html")
|
| 364 |
return
|
| 365 |
-
|
| 366 |
tmt = tima * 1000
|
| 367 |
timef = time_formatter(tmt)
|
| 368 |
timeform = timef if not timef == "0s" else f"{tmt:.3f}ms"
|
|
@@ -385,19 +310,48 @@ async def _(event):
|
|
| 385 |
reply_to=reply_to_id,
|
| 386 |
)
|
| 387 |
return await xx.delete()
|
|
|
|
| 388 |
|
| 389 |
-
# wrap eval output in HTML blockquote and escape unsafe chars
|
| 390 |
-
formatted_eval = f"<blockquote>{escape(final_output)}</blockquote>"
|
| 391 |
-
await xx.edit(formatted_eval, parse_mode="html")
|
| 392 |
|
| 393 |
-
# Small helper used by exec namespace
|
| 394 |
def _stringify(text=None, *args, **kwargs):
|
| 395 |
if text:
|
| 396 |
u._ = text
|
| 397 |
text = _parse_eval(text)
|
| 398 |
return print(text, *args, **kwargs)
|
| 399 |
|
| 400 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 401 |
DUMMY_CPP = """#include <iostream>
|
| 402 |
using namespace std;
|
| 403 |
|
|
@@ -406,6 +360,7 @@ int main(){
|
|
| 406 |
}
|
| 407 |
"""
|
| 408 |
|
|
|
|
| 409 |
@ultroid_cmd(pattern="cpp", only_devs=True)
|
| 410 |
async def doie(e):
|
| 411 |
match = e.text.split(" ", maxsplit=1)
|
|
@@ -423,9 +378,9 @@ async def doie(e):
|
|
| 423 |
if m[1]:
|
| 424 |
o_cpp += f"\n\n**• Error :**\n`{m[1]}`"
|
| 425 |
if len(o_cpp) > 3000:
|
| 426 |
-
remove("cpp-ultroid.cpp")
|
| 427 |
if os.path.exists("CppUltroid"):
|
| 428 |
-
remove("CppUltroid")
|
| 429 |
with BytesIO(str.encode(o_cpp)) as out_file:
|
| 430 |
out_file.name = "error.txt"
|
| 431 |
return await msg.reply(f"`{match}`", file=out_file)
|
|
@@ -440,8 +395,6 @@ async def doie(e):
|
|
| 440 |
out_file.name = "eval.txt"
|
| 441 |
await msg.reply(f"`{match}`", file=out_file)
|
| 442 |
else:
|
| 443 |
-
|
| 444 |
-
|
| 445 |
-
|
| 446 |
-
remove("CppUltroid")
|
| 447 |
-
remove("cpp-ultroid.cpp")
|
|
|
|
| 2 |
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
#
|
| 4 |
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
|
| 8 |
from . import get_help
|
|
|
|
| 12 |
import inspect
|
| 13 |
import sys
|
| 14 |
import traceback
|
|
|
|
|
|
|
| 15 |
from io import BytesIO, StringIO
|
| 16 |
from os import remove
|
| 17 |
from pprint import pprint
|
|
|
|
|
|
|
| 18 |
|
| 19 |
from telethon.utils import get_display_name
|
|
|
|
| 20 |
|
|
|
|
| 21 |
from pyUltroid import _ignore_eval
|
|
|
|
|
|
|
| 22 |
|
| 23 |
+
from . import *
|
| 24 |
+
|
| 25 |
+
# Used for Formatting Eval Code, if installed
|
| 26 |
try:
|
| 27 |
import black
|
| 28 |
+
except ImportError:
|
| 29 |
black = None
|
| 30 |
+
from random import choice
|
| 31 |
|
| 32 |
try:
|
| 33 |
from yaml import safe_load
|
| 34 |
+
except ImportError:
|
| 35 |
+
from pyUltroid.fns.tools import safe_load
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 36 |
|
| 37 |
+
from . import upload_file as uf
|
| 38 |
+
from telethon.tl import functions
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 39 |
|
| 40 |
+
fn = functions
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 41 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
|
| 43 |
+
@ultroid_cmd(
|
| 44 |
+
pattern="sysinfo$",
|
| 45 |
+
)
|
| 46 |
async def _(e):
|
| 47 |
xx = await e.eor(get_string("com_1"))
|
| 48 |
+
x, y = await bash("neofetch|sed 's/\x1B\\[[0-9;\\?]*[a-zA-Z]//g' >> neo.txt")
|
|
|
|
| 49 |
if y and y.endswith("NOT_FOUND"):
|
| 50 |
return await xx.edit(f"Error: `{y}`")
|
| 51 |
with open("neo.txt", "r", encoding="utf-8") as neo:
|
|
|
|
| 58 |
await xx.delete()
|
| 59 |
remove("neo.txt")
|
| 60 |
|
| 61 |
+
|
| 62 |
@ultroid_cmd(pattern="bash", fullsudo=True, only_devs=True)
|
| 63 |
async def _(event):
|
| 64 |
carb, rayso, yamlf = None, None, False
|
|
|
|
| 72 |
rayso = True
|
| 73 |
except IndexError:
|
| 74 |
return await event.eor(get_string("devs_1"), time=10)
|
|
|
|
| 75 |
xx = await event.eor(get_string("com_1"))
|
| 76 |
reply_to_id = event.reply_to_msg_id or event.id
|
| 77 |
stdout, stderr = await bash(cmd, run_code=1)
|
|
|
|
| 80 |
if stderr:
|
| 81 |
err = f"**• ERROR:** \n`{stderr}`\n\n"
|
| 82 |
if stdout:
|
|
|
|
| 83 |
if (carb or udB.get_key("CARBON_ON_BASH")) and (
|
| 84 |
event.is_private
|
| 85 |
or event.chat.admin_rights
|
|
|
|
| 124 |
out = "**• OUTPUT:**"
|
| 125 |
remove(li)
|
| 126 |
else:
|
|
|
|
| 127 |
if "pip" in cmd and all(":" in line for line in stdout.split("\n")):
|
| 128 |
try:
|
| 129 |
load = safe_load(stdout)
|
|
|
|
| 142 |
out = f"**• OUTPUT:**\n{stdout}"
|
| 143 |
if not stderr and not stdout:
|
| 144 |
out = "**• OUTPUT:**\n`Success`"
|
|
|
|
| 145 |
OUT += err + out
|
|
|
|
| 146 |
if len(OUT) > 4096:
|
| 147 |
ultd = err + out
|
| 148 |
with BytesIO(str.encode(ultd)) as out_file:
|
|
|
|
| 159 |
|
| 160 |
await xx.delete()
|
| 161 |
else:
|
| 162 |
+
await xx.edit(OUT, link_preview=not yamlf)
|
| 163 |
+
|
|
|
|
|
|
|
| 164 |
|
| 165 |
+
pp = pprint # ignore: pylint
|
| 166 |
+
bot = ultroid = ultroid_bot
|
| 167 |
+
|
| 168 |
+
|
| 169 |
+
class u:
|
| 170 |
+
_ = ""
|
| 171 |
+
|
| 172 |
+
|
| 173 |
+
def _parse_eval(value=None):
|
| 174 |
+
if not value:
|
| 175 |
+
return value
|
| 176 |
+
if hasattr(value, "stringify"):
|
| 177 |
+
try:
|
| 178 |
+
return value.stringify()
|
| 179 |
+
except TypeError:
|
| 180 |
+
pass
|
| 181 |
+
elif isinstance(value, dict):
|
| 182 |
+
try:
|
| 183 |
+
return json_parser(value, indent=1)
|
| 184 |
+
except BaseException:
|
| 185 |
+
pass
|
| 186 |
+
elif isinstance(value, list):
|
| 187 |
+
newlist = "["
|
| 188 |
+
for index, child in enumerate(value):
|
| 189 |
+
newlist += "\n " + str(_parse_eval(child))
|
| 190 |
+
if index < len(value) - 1:
|
| 191 |
+
newlist += ","
|
| 192 |
+
newlist += "\n]"
|
| 193 |
+
return newlist
|
| 194 |
+
return str(value)
|
| 195 |
|
|
|
|
|
|
|
| 196 |
|
| 197 |
@ultroid_cmd(pattern="eval", fullsudo=True, only_devs=True)
|
| 198 |
async def _(event):
|
|
|
|
| 200 |
cmd = event.text.split(maxsplit=1)[1]
|
| 201 |
except IndexError:
|
| 202 |
return await event.eor(get_string("devs_2"), time=5)
|
|
|
|
| 203 |
xx = None
|
| 204 |
mode = ""
|
| 205 |
spli = cmd.split()
|
|
|
|
| 228 |
return
|
| 229 |
if not mode == "silent" and not xx:
|
| 230 |
xx = await event.eor(get_string("com_1"))
|
|
|
|
|
|
|
| 231 |
if black:
|
| 232 |
try:
|
| 233 |
cmd = black.format_str(cmd, mode=black.Mode())
|
| 234 |
+
except BaseException:
|
| 235 |
+
# Consider it as Code Error, and move on to be shown ahead.
|
| 236 |
pass
|
| 237 |
+
reply_to_id = event.reply_to_msg_id or event
|
|
|
|
|
|
|
|
|
|
| 238 |
if any(item in cmd for item in KEEP_SAFE().All) and (
|
| 239 |
not (event.out or event.sender_id == ultroid_bot.uid)
|
| 240 |
):
|
|
|
|
| 246 |
return await xx.edit(
|
| 247 |
"`Malicious Activities suspected⚠️!\nReported to owner. Aborted this request!`"
|
| 248 |
)
|
|
|
|
|
|
|
| 249 |
old_stderr = sys.stderr
|
| 250 |
old_stdout = sys.stdout
|
| 251 |
redirected_output = sys.stdout = StringIO()
|
| 252 |
redirected_error = sys.stderr = StringIO()
|
| 253 |
+
stdout, stderr, exc, timeg = None, None, None, None
|
| 254 |
tima = time.time()
|
| 255 |
try:
|
| 256 |
value = await aexec(cmd, event)
|
|
|
|
| 262 |
stderr = redirected_error.getvalue()
|
| 263 |
sys.stdout = old_stdout
|
| 264 |
sys.stderr = old_stderr
|
|
|
|
| 265 |
if value:
|
| 266 |
try:
|
| 267 |
if mode == "gsource":
|
| 268 |
exc = inspect.getsource(value)
|
| 269 |
elif mode == "g-args":
|
| 270 |
args = inspect.signature(value).parameters.values()
|
| 271 |
+
name = ""
|
| 272 |
+
if hasattr(value, "__name__"):
|
| 273 |
+
name = value.__name__
|
| 274 |
exc = f"**{name}**\n\n" + "\n ".join([str(arg) for arg in args])
|
| 275 |
except Exception:
|
| 276 |
exc = traceback.format_exc()
|
|
|
|
| 277 |
evaluation = exc or stderr or stdout or _parse_eval(value) or get_string("instu_4")
|
| 278 |
if mode == "silent":
|
| 279 |
if exc:
|
|
|
|
| 283 |
if len(msg) > 4000:
|
| 284 |
with BytesIO(msg.encode()) as out_file:
|
| 285 |
out_file.name = "Eval-Error.txt"
|
| 286 |
+
return await event.client.send_message(
|
| 287 |
+
log_chat, f"`{cmd}`", file=out_file
|
| 288 |
+
)
|
| 289 |
await event.client.send_message(log_chat, msg, parse_mode="html")
|
| 290 |
return
|
|
|
|
| 291 |
tmt = tima * 1000
|
| 292 |
timef = time_formatter(tmt)
|
| 293 |
timeform = timef if not timef == "0s" else f"{tmt:.3f}ms"
|
|
|
|
| 310 |
reply_to=reply_to_id,
|
| 311 |
)
|
| 312 |
return await xx.delete()
|
| 313 |
+
await xx.edit(final_output)
|
| 314 |
|
|
|
|
|
|
|
|
|
|
| 315 |
|
|
|
|
| 316 |
def _stringify(text=None, *args, **kwargs):
|
| 317 |
if text:
|
| 318 |
u._ = text
|
| 319 |
text = _parse_eval(text)
|
| 320 |
return print(text, *args, **kwargs)
|
| 321 |
|
| 322 |
+
|
| 323 |
+
async def aexec(code, event):
|
| 324 |
+
# Create a dedicated namespace for execution
|
| 325 |
+
exec_globals = {
|
| 326 |
+
'print': _stringify,
|
| 327 |
+
'p': _stringify,
|
| 328 |
+
'message': event,
|
| 329 |
+
'event': event,
|
| 330 |
+
'client': event.client,
|
| 331 |
+
'reply': await event.get_reply_message(),
|
| 332 |
+
'chat': event.chat_id,
|
| 333 |
+
'u': u,
|
| 334 |
+
'__builtins__': __builtins__,
|
| 335 |
+
'__name__': __name__
|
| 336 |
+
}
|
| 337 |
+
|
| 338 |
+
# Format the async function definition
|
| 339 |
+
wrapped_code = (
|
| 340 |
+
'async def __aexec(e, client):\n' +
|
| 341 |
+
'\n'.join(f' {line}' for line in code.split('\n'))
|
| 342 |
+
)
|
| 343 |
+
|
| 344 |
+
try:
|
| 345 |
+
# Execute the wrapped code in our custom namespace
|
| 346 |
+
exec(wrapped_code, exec_globals)
|
| 347 |
+
# Get the defined async function
|
| 348 |
+
func = exec_globals['__aexec']
|
| 349 |
+
# Execute it with proper parameters
|
| 350 |
+
return await func(event, event.client)
|
| 351 |
+
except Exception as e:
|
| 352 |
+
raise Exception(f"Failed to execute code: {str(e)}")
|
| 353 |
+
|
| 354 |
+
|
| 355 |
DUMMY_CPP = """#include <iostream>
|
| 356 |
using namespace std;
|
| 357 |
|
|
|
|
| 360 |
}
|
| 361 |
"""
|
| 362 |
|
| 363 |
+
|
| 364 |
@ultroid_cmd(pattern="cpp", only_devs=True)
|
| 365 |
async def doie(e):
|
| 366 |
match = e.text.split(" ", maxsplit=1)
|
|
|
|
| 378 |
if m[1]:
|
| 379 |
o_cpp += f"\n\n**• Error :**\n`{m[1]}`"
|
| 380 |
if len(o_cpp) > 3000:
|
| 381 |
+
os.remove("cpp-ultroid.cpp")
|
| 382 |
if os.path.exists("CppUltroid"):
|
| 383 |
+
os.remove("CppUltroid")
|
| 384 |
with BytesIO(str.encode(o_cpp)) as out_file:
|
| 385 |
out_file.name = "error.txt"
|
| 386 |
return await msg.reply(f"`{match}`", file=out_file)
|
|
|
|
| 395 |
out_file.name = "eval.txt"
|
| 396 |
await msg.reply(f"`{match}`", file=out_file)
|
| 397 |
else:
|
| 398 |
+
await eor(msg, o_cpp)
|
| 399 |
+
os.remove("CppUltroid")
|
| 400 |
+
os.remove("cpp-ultroid.cpp")
|
|
|
|
|
|