WebTermX / app.py
userbymahadi's picture
Update app.py
388b9c9 verified
import os
import subprocess
import asyncio
import psutil
import httpx
import shutil
from fastapi import FastAPI, WebSocket, WebSocketDisconnect, UploadFile, File, Body
from fastapi.responses import HTMLResponse, JSONResponse, FileResponse
app = FastAPI()
# Environment variable থেকে পাসওয়ার্ড নেওয়া
ACCESS_PASSWORD = os.getenv("ACCESS_PASSWORD", "admin")
# সিস্টেম রুট থেকে শুরু করার অনুমতি দেওয়া হয়েছে
current_working_dir = "/"
@app.get("/")
async def get():
with open("index.html", "r", encoding="utf-8") as f:
return HTMLResponse(content=f.read())
# --- ফাইল ম্যানেজার API (Root Access Enabled) ---
@app.get("/api/files")
async def list_files(path: str = "/"):
try:
# পাথ যদি খালি থাকে তবে রুটে নিয়ে যাবে
target_path = path if path.startswith("/") else "/"
files = []
for entry in os.scandir(target_path):
try:
files.append({
"name": entry.name,
"is_dir": entry.is_dir(),
"path": os.path.abspath(entry.path),
"size": f"{entry.stat().st_size / 1024:.1f} KB" if entry.is_file() else "-"
})
except PermissionError:
continue # পারমিশন নেই এমন ফাইল স্কিপ করবে
return sorted(files, key=lambda x: not x['is_dir'])
except Exception as e:
return JSONResponse(status_code=500, content={"error": str(e)})
@app.get("/api/read")
async def read_file(path: str):
try:
with open(path, "r", encoding="utf-8") as f:
return {"content": f.read()}
except Exception as e:
return {"content": f"Error: {str(e)}"}
@app.post("/api/save")
async def save_file(path: str = Body(...), content: str = Body(...)):
with open(path, "w", encoding="utf-8") as f:
f.write(content)
return {"status": "saved"}
@app.post("/api/create")
async def create_item(name: str = Body(...), is_dir: bool = Body(...), path: str = Body(...)):
target = os.path.join(path, name)
if is_dir:
os.makedirs(target, exist_ok=True)
else:
with open(target, "w") as f: f.write("")
return {"status": "created"}
@app.post("/api/upload")
async def upload_file(file: UploadFile = File(...), path: str = "/"):
target_path = os.path.join(path, file.filename)
with open(target_path, "wb") as buffer:
shutil.copyfileobj(file.file, buffer)
return {"message": "Uploaded"}
@app.get("/api/download")
async def download_file(path: str):
return FileResponse(path)
@app.delete("/api/delete")
async def delete_file(path: str):
if os.path.isdir(path):
shutil.rmtree(path)
else:
os.remove(path)
return {"message": "Deleted"}
# --- প্রক্সি ---
@app.get("/proxy")
async def proxy(url: str = "http://localhost:8080"):
async with httpx.AsyncClient() as client:
try:
response = await client.get(url, timeout=5.0)
return HTMLResponse(content=response.text)
except Exception as e:
return HTMLResponse(content=f"<div style='color:red;padding:20px;'>Error: {str(e)}</div>")
# --- টার্মিনাল সেশন ---
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
global current_working_dir
await websocket.accept()
try:
auth = await websocket.receive_text()
if auth != ACCESS_PASSWORD:
await websocket.send_text("AUTH_FAILED")
await websocket.close()
return
await websocket.send_text("AUTH_SUCCESS")
while True:
command = await websocket.receive_text()
if command.startswith("cd "):
new_p = command[3:].strip()
try:
os.chdir(os.path.expanduser(new_p))
current_working_dir = os.getcwd()
await websocket.send_text(f"CWD: {current_working_dir}")
except Exception as e:
await websocket.send_text(str(e))
continue
process = await asyncio.create_subprocess_shell(
command, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, cwd=current_working_dir
)
stdout, stderr = await process.communicate()
output = stdout.decode().strip() or stderr.decode().strip() or "Done."
await websocket.send_text(output)
except WebSocketDisconnect:
pass