Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -6,6 +6,7 @@ from queue import Queue
|
|
6 |
import os
|
7 |
import shlex
|
8 |
import signal
|
|
|
9 |
from telegram import Update
|
10 |
from telegram.ext import ApplicationBuilder, CommandHandler, ContextTypes
|
11 |
|
@@ -19,13 +20,22 @@ bot_app = None
|
|
19 |
bot_running = False
|
20 |
bot_thread = None
|
21 |
current_dir = os.getcwd()
|
|
|
|
|
22 |
|
23 |
-
#
|
24 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
|
26 |
-
# --- Logging ---
|
27 |
def add_terminal_log(entry):
|
28 |
terminal_logs.append(entry)
|
|
|
29 |
if len(terminal_logs) > MAX_LOGS:
|
30 |
terminal_logs.pop(0)
|
31 |
|
@@ -34,7 +44,7 @@ def add_bot_log(entry):
|
|
34 |
if len(bot_logs) > MAX_LOGS:
|
35 |
bot_logs.pop(0)
|
36 |
|
37 |
-
#
|
38 |
def execute_command(cmd):
|
39 |
global current_dir, current_proc
|
40 |
output = []
|
@@ -54,14 +64,21 @@ def execute_command(cmd):
|
|
54 |
if cmd.strip().startswith("cd"):
|
55 |
parts = shlex.split(cmd)
|
56 |
if len(parts) > 1:
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
else:
|
64 |
-
msg = f"
|
65 |
output.append(msg)
|
66 |
add_terminal_log(msg)
|
67 |
else:
|
@@ -69,46 +86,37 @@ def execute_command(cmd):
|
|
69 |
output.append(msg)
|
70 |
add_terminal_log(msg)
|
71 |
else:
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
# --- Logging ---
|
97 |
-
def add_bot_log(entry):
|
98 |
-
bot_logs.append(entry)
|
99 |
-
if len(bot_logs) > MAX_LOGS:
|
100 |
-
bot_logs.pop(0)
|
101 |
|
102 |
-
|
103 |
-
def execute_command(cmd):
|
104 |
-
return f"Executed: {cmd}"
|
105 |
|
106 |
-
#
|
107 |
async def start_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
108 |
await update.message.reply_text("Hello! I'm your terminal bot.\nUse /bash <command> to execute shell commands.")
|
109 |
add_bot_log("[Bot] Received /start command.")
|
110 |
|
111 |
-
# --- /bash Handler ---
|
112 |
async def bash_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
113 |
cmd = ' '.join(context.args)
|
114 |
if not cmd:
|
@@ -116,7 +124,6 @@ async def bash_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
|
116 |
return
|
117 |
|
118 |
add_bot_log(f"[Bot] $ {cmd}")
|
119 |
-
|
120 |
try:
|
121 |
result = execute_command(cmd)
|
122 |
except Exception as e:
|
@@ -125,7 +132,6 @@ async def bash_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
|
125 |
add_bot_log(result)
|
126 |
await update.message.reply_text(f"$ {cmd}\n{result}")
|
127 |
|
128 |
-
# --- Start Bot ---
|
129 |
def start_bot():
|
130 |
global bot_app, bot_running, bot_thread, BOT_TOKEN
|
131 |
if bot_running or not BOT_TOKEN:
|
@@ -155,7 +161,6 @@ def start_bot():
|
|
155 |
bot_thread.start()
|
156 |
add_bot_log("[Bot] Bot thread started.")
|
157 |
|
158 |
-
# --- Stop Bot ---
|
159 |
def stop_bot():
|
160 |
global bot_app, bot_running
|
161 |
if not bot_running or not bot_app:
|
@@ -171,14 +176,13 @@ def stop_bot():
|
|
171 |
|
172 |
threading.Thread(target=lambda: asyncio.run(shutdown()), daemon=True).start()
|
173 |
|
174 |
-
#
|
175 |
def update_bot_logs():
|
176 |
return "\n".join(bot_logs[-100:])
|
177 |
-
|
178 |
def update_terminal_logs():
|
179 |
return "\n".join(terminal_logs[-100:])
|
180 |
|
181 |
-
|
182 |
def live_terminal(cmd):
|
183 |
result = [f"$ {cmd}"]
|
184 |
try:
|
@@ -188,7 +192,7 @@ def live_terminal(cmd):
|
|
188 |
result.append(f"$ {current_dir} >")
|
189 |
return "\n".join(result)
|
190 |
|
191 |
-
#
|
192 |
with gr.Blocks() as demo:
|
193 |
with gr.Tab("💻 Terminal"):
|
194 |
gr.Markdown("## 🖥️ Interactive Terminal")
|
@@ -228,5 +232,5 @@ with gr.Blocks() as demo:
|
|
228 |
stop_btn.click(fn=handle_stop, outputs=bot_output)
|
229 |
demo.load(fn=update_bot_logs, outputs=bot_output)
|
230 |
|
231 |
-
#
|
232 |
demo.launch()
|
|
|
6 |
import os
|
7 |
import shlex
|
8 |
import signal
|
9 |
+
import glob
|
10 |
from telegram import Update
|
11 |
from telegram.ext import ApplicationBuilder, CommandHandler, ContextTypes
|
12 |
|
|
|
20 |
bot_running = False
|
21 |
bot_thread = None
|
22 |
current_dir = os.getcwd()
|
23 |
+
current_proc = None # Track running process
|
24 |
+
LOG_FILE = "terminal_logs.txt"
|
25 |
|
26 |
+
# Load previous logs if available
|
27 |
+
if os.path.exists(LOG_FILE):
|
28 |
+
with open(LOG_FILE, "r") as f:
|
29 |
+
terminal_logs = f.read().splitlines()[-MAX_LOGS:]
|
30 |
+
|
31 |
+
# Logging
|
32 |
+
def save_log_to_file(entry):
|
33 |
+
with open(LOG_FILE, "a") as f:
|
34 |
+
f.write(entry + "\n")
|
35 |
|
|
|
36 |
def add_terminal_log(entry):
|
37 |
terminal_logs.append(entry)
|
38 |
+
save_log_to_file(entry)
|
39 |
if len(terminal_logs) > MAX_LOGS:
|
40 |
terminal_logs.pop(0)
|
41 |
|
|
|
44 |
if len(bot_logs) > MAX_LOGS:
|
45 |
bot_logs.pop(0)
|
46 |
|
47 |
+
# Command Execution
|
48 |
def execute_command(cmd):
|
49 |
global current_dir, current_proc
|
50 |
output = []
|
|
|
64 |
if cmd.strip().startswith("cd"):
|
65 |
parts = shlex.split(cmd)
|
66 |
if len(parts) > 1:
|
67 |
+
pattern = os.path.join(current_dir, parts[1])
|
68 |
+
matches = glob.glob(pattern)
|
69 |
+
if matches:
|
70 |
+
new_path = os.path.abspath(matches[0])
|
71 |
+
if os.path.isdir(new_path):
|
72 |
+
current_dir = new_path
|
73 |
+
msg = f"Changed directory to {current_dir}"
|
74 |
+
output.append(msg)
|
75 |
+
add_terminal_log(msg)
|
76 |
+
else:
|
77 |
+
msg = f"Not a directory: {new_path}"
|
78 |
+
output.append(msg)
|
79 |
+
add_terminal_log(msg)
|
80 |
else:
|
81 |
+
msg = f"No matching path for: {parts[1]}"
|
82 |
output.append(msg)
|
83 |
add_terminal_log(msg)
|
84 |
else:
|
|
|
86 |
output.append(msg)
|
87 |
add_terminal_log(msg)
|
88 |
else:
|
89 |
+
try:
|
90 |
+
current_proc = subprocess.Popen(
|
91 |
+
cmd,
|
92 |
+
cwd=current_dir,
|
93 |
+
shell=True,
|
94 |
+
stdout=subprocess.PIPE,
|
95 |
+
stderr=subprocess.STDOUT,
|
96 |
+
text=True,
|
97 |
+
bufsize=1
|
98 |
+
)
|
99 |
+
for line in iter(current_proc.stdout.readline, ''):
|
100 |
+
line = line.strip()
|
101 |
+
if line:
|
102 |
+
output.append(line)
|
103 |
+
add_terminal_log(line)
|
104 |
+
current_proc.stdout.close()
|
105 |
+
current_proc.wait()
|
106 |
+
except Exception as e:
|
107 |
+
error_msg = f"[Error] {e}"
|
108 |
+
output.append(error_msg)
|
109 |
+
add_terminal_log(error_msg)
|
110 |
+
finally:
|
111 |
+
current_proc = None
|
|
|
|
|
|
|
|
|
|
|
|
|
112 |
|
113 |
+
return "\n".join(output)
|
|
|
|
|
114 |
|
115 |
+
# Telegram Bot
|
116 |
async def start_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
117 |
await update.message.reply_text("Hello! I'm your terminal bot.\nUse /bash <command> to execute shell commands.")
|
118 |
add_bot_log("[Bot] Received /start command.")
|
119 |
|
|
|
120 |
async def bash_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
121 |
cmd = ' '.join(context.args)
|
122 |
if not cmd:
|
|
|
124 |
return
|
125 |
|
126 |
add_bot_log(f"[Bot] $ {cmd}")
|
|
|
127 |
try:
|
128 |
result = execute_command(cmd)
|
129 |
except Exception as e:
|
|
|
132 |
add_bot_log(result)
|
133 |
await update.message.reply_text(f"$ {cmd}\n{result}")
|
134 |
|
|
|
135 |
def start_bot():
|
136 |
global bot_app, bot_running, bot_thread, BOT_TOKEN
|
137 |
if bot_running or not BOT_TOKEN:
|
|
|
161 |
bot_thread.start()
|
162 |
add_bot_log("[Bot] Bot thread started.")
|
163 |
|
|
|
164 |
def stop_bot():
|
165 |
global bot_app, bot_running
|
166 |
if not bot_running or not bot_app:
|
|
|
176 |
|
177 |
threading.Thread(target=lambda: asyncio.run(shutdown()), daemon=True).start()
|
178 |
|
179 |
+
# UI Hooks
|
180 |
def update_bot_logs():
|
181 |
return "\n".join(bot_logs[-100:])
|
182 |
+
|
183 |
def update_terminal_logs():
|
184 |
return "\n".join(terminal_logs[-100:])
|
185 |
|
|
|
186 |
def live_terminal(cmd):
|
187 |
result = [f"$ {cmd}"]
|
188 |
try:
|
|
|
192 |
result.append(f"$ {current_dir} >")
|
193 |
return "\n".join(result)
|
194 |
|
195 |
+
# Gradio UI
|
196 |
with gr.Blocks() as demo:
|
197 |
with gr.Tab("💻 Terminal"):
|
198 |
gr.Markdown("## 🖥️ Interactive Terminal")
|
|
|
232 |
stop_btn.click(fn=handle_stop, outputs=bot_output)
|
233 |
demo.load(fn=update_bot_logs, outputs=bot_output)
|
234 |
|
235 |
+
# Launch App
|
236 |
demo.launch()
|