file / app.py
Kanhshsh's picture
Update app.py
67cfbd5 verified
raw
history blame
3.6 kB
import gradio as gr
import subprocess
import asyncio
import threading
import os
import time
from queue import Queue, Empty
from telegram import Update
from telegram.ext import ApplicationBuilder, CommandHandler, ContextTypes
# --- Config ---
BOT_TOKEN = os.environ.get("BOT_TOKEN", "YOUR_BOT_TOKEN_HERE")
log_queue = Queue()
telegram_cmd_logs = []
bot_should_run = True # Thread-safe flag
# --- Telegram Command Handler ---
async def bash_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
if not bot_should_run:
await update.message.reply_text("Bot is disabled.")
return
cmd = ' '.join(context.args)
if not cmd:
await update.message.reply_text("Usage: /bash <command>")
return
log_queue.put(f"[Telegram] /bash {cmd}")
try:
proc = await asyncio.create_subprocess_shell(
cmd,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.STDOUT,
)
stdout, _ = await proc.communicate()
output = stdout.decode().strip()
except Exception as e:
output = f"Error: {e}"
await update.message.reply_text(f"$ {cmd}\n{output}")
telegram_cmd_logs.append(f"$ {cmd}\n{output}")
if len(telegram_cmd_logs) > 50:
telegram_cmd_logs.pop(0)
# --- Start bot once in main thread ---
def launch_bot():
async def main():
app = ApplicationBuilder().token(BOT_TOKEN).build()
app.add_handler(CommandHandler("bash", bash_command))
log_queue.put("[Bot] Running...")
await app.run_polling()
def bot_thread():
asyncio.run(main())
thread = threading.Thread(target=bot_thread, daemon=True)
thread.start()
# --- Terminal Function ---
def live_terminal(cmd):
if not cmd.strip():
yield "$ "
return
yield f"$ {cmd}\n"
process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
for line in iter(process.stdout.readline, ''):
yield line
process.stdout.close()
process.wait()
yield "$ "
# --- Log Updater ---
def update_logs():
logs = []
try:
while True:
logs.append(log_queue.get_nowait())
except Empty:
pass
logs.extend(telegram_cmd_logs[-20:])
return "\n".join(logs[-20:])
# --- Start/Stop Bot Command Execution Only ---
def enable_bot():
global bot_should_run
bot_should_run = True
log_queue.put("[Bot] Enabled")
return update_logs()
def disable_bot():
global bot_should_run
bot_should_run = False
log_queue.put("[Bot] Disabled")
return update_logs()
# --- Gradio Interface ---
with gr.Blocks() as demo:
gr.Markdown("## πŸ–₯️ Live Terminal + Telegram Bot Interface")
with gr.Row():
terminal_output = gr.Textbox(label="Live Terminal", lines=20, interactive=False)
cmd_input = gr.Textbox(placeholder="Type shell command", label="Command Input")
run_btn = gr.Button("▢️ Run Command")
with gr.Row():
start_btn = gr.Button("βœ… Enable Bot")
stop_btn = gr.Button("πŸ›‘ Disable Bot")
log_output = gr.Textbox(label="πŸ“œ Logs", lines=15, interactive=False)
run_btn.click(live_terminal, inputs=cmd_input, outputs=terminal_output)
start_btn.click(fn=enable_bot, outputs=log_output)
stop_btn.click(fn=disable_bot, outputs=log_output)
def background_log_updater():
while True:
time.sleep(3)
yield update_logs()
demo.load(background_log_updater, outputs=log_output)
# --- Launch everything ---
launch_bot()
demo.launch()