From 442b96a5cdadff361f0f359ba3eb45e40e4b9ddd Mon Sep 17 00:00:00 2001 From: owl Date: Mon, 12 May 2025 21:23:24 +0700 Subject: [PATCH] eval --- bot.py | 52 +++++++++++++++++++++++++++++++++++++++++++++- docker-compose.yml | 30 -------------------------- tgbot/config.py | 5 +++++ 3 files changed, 56 insertions(+), 31 deletions(-) diff --git a/bot.py b/bot.py index 4424224..d31562b 100644 --- a/bot.py +++ b/bot.py @@ -1,10 +1,13 @@ +import contextlib +import io + from telegram import Update, InputFile from telegram.ext import ApplicationBuilder, ContextTypes, CommandHandler, MessageHandler, filters, InlineQueryHandler, \ CallbackContext, CallbackQueryHandler import logging from tgbot.shit.fed import build_fediverse_inline_results, extract_content -from tgbot.config import TOKEN, PROMPTING_USERS +from tgbot.config import TOKEN, PROMPTING_USERS, EXEC_UIDS from tgbot.shit.handlers import handle_xitter, handle_red_ebalo, handle_hentai, handle_cute_button from tgbot.shit.prompting import gen_image from tgbot.shit.render import render_text_on_image, image_to_string, encode_text, decode_text @@ -118,6 +121,51 @@ async def handle_inline(update: Update, context: ContextTypes.DEFAULT_TYPE): await handle_red_ebalo(update, context) +async def handle_eval(update: Update, context: ContextTypes.DEFAULT_TYPE): + user_id = update.effective_user.id + if user_id not in EXEC_UIDS: + await update.message.reply_text("Eh") + return + + code = update.message.text.removeprefix("/eval").strip() + if not code: + await update.message.reply_text("✍️ Send some Python code to evaluate.") + return + + # Redirect stdout to capture output + stdout = io.StringIO() + + # Create an isolated async context for execution + async def run_code(): + local_vars = {} + code_wrapped = f"async def __eval_func():\n" + for line in code.splitlines(): + code_wrapped += " " + line + "\n" + + try: + exec(code_wrapped, {}, local_vars) + with contextlib.redirect_stdout(stdout): + r = await local_vars["__eval_func"]() + return r + except Exception as e: + return f"❌ {e}" + + # Run the async function and get the output + result = await run_code() + output = stdout.getvalue() + + if result is not None: + output += f"\n➡️ {result}" + + if not output.strip(): + output = "✅ Done." + + # Send output (truncate if needed) + MAX_LEN = 4000 + if len(output) > MAX_LEN: + output = output[:MAX_LEN] + "\n... (truncated)" + + await update.message.reply_text(f"
{output.strip()}
", parse_mode="HTML") def main(): application = ApplicationBuilder().token(TOKEN).build() @@ -135,6 +183,8 @@ def main(): txt_file_filter = filters.Document.FileExtension("txt") application.add_handler(MessageHandler(txt_file_filter, handle_txt_upload)) + application.add_handler(CommandHandler("eval", handle_eval)) + application.run_polling() diff --git a/docker-compose.yml b/docker-compose.yml index 7ce451a..43a897e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,21 +1,4 @@ services: - vpn: - hostname: vpn - build: - context: . - dockerfile: Dockerfile.vpn - cap_add: - - NET_ADMIN - devices: - - /dev/net/tun - restart: unless-stopped - volumes: - - ./config.ovpn:/etc/openvpn/config.ovpn - networks: - - vpn_net - dns: - - 1.1.1.1 - - 8.8.8.8 owlrandomshitbot: restart: unless-stopped @@ -24,19 +7,6 @@ services: context: . dockerfile: Dockerfile.tgbot env_file: ".env" - network_mode: "service:vpn" - depends_on: - - vpn - - booru-api: - restart: unless-stopped - image: booru-api - build: - context: . - dockerfile: Dockerfile.booru-api - network_mode: "service:vpn" - depends_on: - - vpn networks: vpn_net: diff --git a/tgbot/config.py b/tgbot/config.py index e73d6ce..bd7c75b 100644 --- a/tgbot/config.py +++ b/tgbot/config.py @@ -18,3 +18,8 @@ try: except AttributeError: PROMPTING_USERS = None +try: + EXEC_UIDS: list[int] | None = [int(e) for e in os.getenv("EXEC_UIDS").split(" ")] +except AttributeError: + EXEC_UIDS = None +