Spaces:
Paused
Paused
Update app.py
Browse files
app.py
CHANGED
|
@@ -327,16 +327,17 @@ def get_flask_apps():
|
|
| 327 |
|
| 328 |
def run_command(cmd: str):
|
| 329 |
"""Handle terminal-like commands including Flask and Python apps"""
|
| 330 |
-
global current_dir
|
| 331 |
-
|
| 332 |
-
if not
|
| 333 |
-
|
| 334 |
-
|
| 335 |
-
|
| 336 |
-
|
| 337 |
-
|
| 338 |
-
|
| 339 |
|
|
|
|
| 340 |
# === STOP running process ===
|
| 341 |
if raw_cmd == "close":
|
| 342 |
if running_process and running_process.poll() is None:
|
|
@@ -346,29 +347,31 @@ def run_command(cmd: str):
|
|
| 346 |
return f"$ {cmd}\n\nNo active process to stop.", "", None
|
| 347 |
|
| 348 |
# === Start Flask app from code ===
|
| 349 |
-
elif raw_cmd == "flaskrun" and
|
| 350 |
-
|
| 351 |
-
|
| 352 |
-
|
| 353 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 354 |
|
| 355 |
# === Run Python application ===
|
| 356 |
-
elif raw_cmd == "python3
|
| 357 |
-
file_path =
|
| 358 |
if not os.path.exists(file_path):
|
| 359 |
-
|
| 360 |
if is_flask_app(file_path):
|
| 361 |
-
# Read the Flask app code and run it
|
| 362 |
try:
|
| 363 |
-
with open(file_path, 'r') as f:
|
| 364 |
code = f.read()
|
| 365 |
app_name = os.path.splitext(os.path.basename(file_path))[0]
|
| 366 |
-
run_flask_app(app_name, code)
|
| 367 |
-
return f"
|
| 368 |
except Exception as e:
|
| 369 |
return f"$ {cmd}\n\nError reading Flask app: {e}", "", None
|
| 370 |
else:
|
| 371 |
-
# Run as regular Python script
|
| 372 |
result = run_python_app(file_path)
|
| 373 |
return f"$ {cmd}\n\n{result}", "", None
|
| 374 |
|
|
@@ -378,60 +381,63 @@ def run_command(cmd: str):
|
|
| 378 |
return f"$ {cmd}\n\n{apps_info}", "", None
|
| 379 |
|
| 380 |
# === View logs ===
|
| 381 |
-
elif raw_cmd
|
| 382 |
-
|
| 383 |
-
logs = view_logs(
|
| 384 |
-
return f"$ {cmd}\n\nLogs for {
|
| 385 |
|
| 386 |
# === Change directory (cd) ===
|
| 387 |
-
elif raw_cmd
|
| 388 |
-
|
| 389 |
-
|
|
|
|
| 390 |
if os.path.isdir(target):
|
| 391 |
-
current_dir = target
|
| 392 |
return f"$ {cmd}\n\nChanged directory to: {current_dir}", "", None
|
| 393 |
-
return f"$ {cmd}\n\nDirectory not found: {
|
| 394 |
|
| 395 |
# === Create file/folder ===
|
| 396 |
-
elif raw_cmd
|
| 397 |
-
|
| 398 |
-
|
| 399 |
-
|
|
|
|
| 400 |
os.makedirs(target, exist_ok=True)
|
| 401 |
return f"$ {cmd}\n\nCreated folder: {target}", "", None
|
| 402 |
else:
|
| 403 |
os.makedirs(os.path.dirname(target), exist_ok=True)
|
| 404 |
-
with open(target, "w") as f:
|
| 405 |
pass
|
| 406 |
return f"$ {cmd}\n\nCreated file: {target}", "", None
|
| 407 |
|
| 408 |
# === Delete file/folder ===
|
| 409 |
-
elif raw_cmd
|
| 410 |
-
|
| 411 |
-
|
|
|
|
| 412 |
if os.path.isfile(target):
|
| 413 |
os.remove(target)
|
| 414 |
return f"$ {cmd}\n\nDeleted file: {target}", "", None
|
| 415 |
elif os.path.isdir(target):
|
| 416 |
-
shutil.rmtree(target)
|
| 417 |
return f"$ {cmd}\n\nDeleted folder: {target}", "", None
|
| 418 |
else:
|
| 419 |
return f"$ {cmd}\n\nNot found: {target}", "", None
|
| 420 |
|
| 421 |
# === Open file/folder ===
|
| 422 |
-
elif raw_cmd
|
| 423 |
-
|
| 424 |
-
|
|
|
|
| 425 |
if not os.path.exists(target):
|
| 426 |
-
return f"$ {cmd}\n\nFile not found: {
|
| 427 |
-
|
| 428 |
if os.path.isdir(target):
|
| 429 |
items = os.listdir(target)
|
| 430 |
return f"$ {cmd}\n\n" + ("\n".join(items) if items else "(empty folder)"), "", None
|
| 431 |
-
|
| 432 |
try:
|
| 433 |
with open(target, "r", encoding="utf-8") as f:
|
| 434 |
content = f.read()
|
|
|
|
| 435 |
open_file_path = target
|
| 436 |
return f"$ {cmd}\n\nOpened file: {target}", content, target
|
| 437 |
except Exception as e:
|
|
@@ -451,21 +457,31 @@ def run_command(cmd: str):
|
|
| 451 |
return "", "", None
|
| 452 |
|
| 453 |
# === Normal shell command ===
|
| 454 |
-
|
| 455 |
-
|
| 456 |
-
|
| 457 |
-
|
| 458 |
-
|
| 459 |
-
|
| 460 |
-
|
| 461 |
-
|
| 462 |
-
|
| 463 |
-
|
| 464 |
-
|
| 465 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 466 |
|
| 467 |
except Exception as e:
|
| 468 |
-
return f"
|
| 469 |
|
| 470 |
def save_file(new_content: str, file_path: str):
|
| 471 |
global open_file_path
|
|
|
|
| 327 |
|
| 328 |
def run_command(cmd: str):
|
| 329 |
"""Handle terminal-like commands including Flask and Python apps"""
|
| 330 |
+
global current_dir, running_process
|
| 331 |
+
cmd = cmd.strip() # Remove leading/trailing whitespace
|
| 332 |
+
if not cmd:
|
| 333 |
+
return "No command provided", "", None
|
| 334 |
+
|
| 335 |
+
# Split command into command and arguments (maxsplit=1 for commands with spaces)
|
| 336 |
+
parts = cmd.split(maxsplit=1)
|
| 337 |
+
raw_cmd = parts[0].lower()
|
| 338 |
+
args = parts[1] if len(parts) > 1 else ""
|
| 339 |
|
| 340 |
+
try:
|
| 341 |
# === STOP running process ===
|
| 342 |
if raw_cmd == "close":
|
| 343 |
if running_process and running_process.poll() is None:
|
|
|
|
| 347 |
return f"$ {cmd}\n\nNo active process to stop.", "", None
|
| 348 |
|
| 349 |
# === Start Flask app from code ===
|
| 350 |
+
elif raw_cmd == "flaskrun" and args:
|
| 351 |
+
# Expect args to be: app_name followed by code
|
| 352 |
+
args_parts = args.split(maxsplit=1)
|
| 353 |
+
if len(args_parts) < 2:
|
| 354 |
+
return f"$ {cmd}\n\nUsage: flaskrun <app_name> <code>", "", None
|
| 355 |
+
app_name, code = args_parts
|
| 356 |
+
code = code.strip('"').strip("'")
|
| 357 |
+
result = run_flask_app(app_name, code)
|
| 358 |
+
return f"$ {cmd}\n\n{result}", "", None
|
| 359 |
|
| 360 |
# === Run Python application ===
|
| 361 |
+
elif raw_cmd == "python3" and args:
|
| 362 |
+
file_path = expand_path(args)
|
| 363 |
if not os.path.exists(file_path):
|
| 364 |
+
return f"$ {cmd}\n\nFile not found: {file_path}", "", None
|
| 365 |
if is_flask_app(file_path):
|
|
|
|
| 366 |
try:
|
| 367 |
+
with open(file_path, 'r', encoding='utf-8') as f:
|
| 368 |
code = f.read()
|
| 369 |
app_name = os.path.splitext(os.path.basename(file_path))[0]
|
| 370 |
+
result = run_flask_app(app_name, code)
|
| 371 |
+
return f"$ {cmd}\n\n{result}", "", None
|
| 372 |
except Exception as e:
|
| 373 |
return f"$ {cmd}\n\nError reading Flask app: {e}", "", None
|
| 374 |
else:
|
|
|
|
| 375 |
result = run_python_app(file_path)
|
| 376 |
return f"$ {cmd}\n\n{result}", "", None
|
| 377 |
|
|
|
|
| 381 |
return f"$ {cmd}\n\n{apps_info}", "", None
|
| 382 |
|
| 383 |
# === View logs ===
|
| 384 |
+
elif raw_cmd == "logs" and args:
|
| 385 |
+
app_name = args
|
| 386 |
+
logs = view_logs(app_name)
|
| 387 |
+
return f"$ {cmd}\n\nLogs for {app_name}:\n{logs}", "", None
|
| 388 |
|
| 389 |
# === Change directory (cd) ===
|
| 390 |
+
elif raw_cmd == "cd":
|
| 391 |
+
if not args:
|
| 392 |
+
return f"$ {cmd}\n\nNo directory specified", "", None
|
| 393 |
+
target = expand_path(args)
|
| 394 |
if os.path.isdir(target):
|
| 395 |
+
current_dir = os.path.abspath(target)
|
| 396 |
return f"$ {cmd}\n\nChanged directory to: {current_dir}", "", None
|
| 397 |
+
return f"$ {cmd}\n\nDirectory not found: {args}", "", None
|
| 398 |
|
| 399 |
# === Create file/folder ===
|
| 400 |
+
elif raw_cmd == "create":
|
| 401 |
+
if not args:
|
| 402 |
+
return f"$ {cmd}\n\nNo path specified", "", None
|
| 403 |
+
target = expand_path(args)
|
| 404 |
+
if args.endswith("/"):
|
| 405 |
os.makedirs(target, exist_ok=True)
|
| 406 |
return f"$ {cmd}\n\nCreated folder: {target}", "", None
|
| 407 |
else:
|
| 408 |
os.makedirs(os.path.dirname(target), exist_ok=True)
|
| 409 |
+
with open(target, "w", encoding="utf-8") as f:
|
| 410 |
pass
|
| 411 |
return f"$ {cmd}\n\nCreated file: {target}", "", None
|
| 412 |
|
| 413 |
# === Delete file/folder ===
|
| 414 |
+
elif raw_cmd == "delete":
|
| 415 |
+
if not args:
|
| 416 |
+
return f"$ {cmd}\n\nNo path specified", "", None
|
| 417 |
+
target = expand_path(args)
|
| 418 |
if os.path.isfile(target):
|
| 419 |
os.remove(target)
|
| 420 |
return f"$ {cmd}\n\nDeleted file: {target}", "", None
|
| 421 |
elif os.path.isdir(target):
|
| 422 |
+
shutil.rmtree(target, ignore_errors=True)
|
| 423 |
return f"$ {cmd}\n\nDeleted folder: {target}", "", None
|
| 424 |
else:
|
| 425 |
return f"$ {cmd}\n\nNot found: {target}", "", None
|
| 426 |
|
| 427 |
# === Open file/folder ===
|
| 428 |
+
elif raw_cmd == "open":
|
| 429 |
+
if not args:
|
| 430 |
+
return f"$ {cmd}\n\nNo path specified", "", None
|
| 431 |
+
target = expand_path(args)
|
| 432 |
if not os.path.exists(target):
|
| 433 |
+
return f"$ {cmd}\n\nFile not found: {args}", "", None
|
|
|
|
| 434 |
if os.path.isdir(target):
|
| 435 |
items = os.listdir(target)
|
| 436 |
return f"$ {cmd}\n\n" + ("\n".join(items) if items else "(empty folder)"), "", None
|
|
|
|
| 437 |
try:
|
| 438 |
with open(target, "r", encoding="utf-8") as f:
|
| 439 |
content = f.read()
|
| 440 |
+
global open_file_path
|
| 441 |
open_file_path = target
|
| 442 |
return f"$ {cmd}\n\nOpened file: {target}", content, target
|
| 443 |
except Exception as e:
|
|
|
|
| 457 |
return "", "", None
|
| 458 |
|
| 459 |
# === Normal shell command ===
|
| 460 |
+
try:
|
| 461 |
+
# Avoid shell=True for common commands
|
| 462 |
+
if raw_cmd == "ls":
|
| 463 |
+
cmd_parts = ['ls', '-l'] if not args else ['ls', '-l', args]
|
| 464 |
+
elif raw_cmd == "cat" and args:
|
| 465 |
+
cmd_parts = ['cat', expand_path(args)]
|
| 466 |
+
else:
|
| 467 |
+
cmd_parts = cmd.split() # Split for safer execution
|
| 468 |
+
running_process = subprocess.Popen(
|
| 469 |
+
cmd_parts,
|
| 470 |
+
shell=False, # Prefer shell=False for safety
|
| 471 |
+
cwd=current_dir,
|
| 472 |
+
stdout=subprocess.PIPE,
|
| 473 |
+
stderr=subprocess.PIPE,
|
| 474 |
+
text=True
|
| 475 |
+
)
|
| 476 |
+
stdout, stderr = running_process.communicate()
|
| 477 |
+
running_process = None
|
| 478 |
+
output = stdout + stderr
|
| 479 |
+
return f"$ {cmd}\n\n{output if output else '(no output)'}", "", None
|
| 480 |
+
except FileNotFoundError:
|
| 481 |
+
return f"$ {cmd}\n\nCommand not found: {raw_cmd}", "", None
|
| 482 |
|
| 483 |
except Exception as e:
|
| 484 |
+
return f"$ {cmd}\n\nError: {e}", "", None
|
| 485 |
|
| 486 |
def save_file(new_content: str, file_path: str):
|
| 487 |
global open_file_path
|