import os import re from dotenv import load_dotenv from fastapi import FastAPI, Request, Form from fastapi.responses import HTMLResponse from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates from e2b_desktop import Sandbox load_dotenv() # load .env if present E2B_API_KEY = "e2b_f0011592397591255c8c9cf7fe9c8178dfe483e5" app = FastAPI() templates = Jinja2Templates(directory="templates") app.mount("/static", StaticFiles(directory="static"), name="static") desktop = None vnc_url = None vnc_host_port = None def extract_host_port(url): m = re.search(r"https?://([^/:]+)(?::(\d+))?", url) if m: host = m.group(1) port = m.group(2) or "5900" return f"{host}:{port}" return None @app.get("/", response_class=HTMLResponse) async def index(request: Request): return templates.TemplateResponse("index.html", { "request": request, "vnc_url": vnc_url or "", "vnc_host_port": vnc_host_port or "", "status_msg": "Idle" if not desktop else f"Running: {vnc_host_port}" }) @app.post("/start") async def start(): global desktop, vnc_url, vnc_host_port if desktop is None: desktop = Sandbox(api_key=E2B_API_KEY) desktop.stream.start(require_auth=False) vnc_url = desktop.stream.get_url() vnc_host_port = extract_host_port(vnc_url) return {"iframe": vnc_url, "status": f"✅ VNC Started — {vnc_host_port}"} return {"iframe": vnc_url, "status": f"⚠️ Already Running — {vnc_host_port}"} @app.post("/stop") async def stop(): global desktop, vnc_url, vnc_host_port if desktop: desktop.kill() desktop = None vnc_url = None vnc_host_port = None return {"iframe": "", "status": "✅ VNC Stopped"} return {"iframe": "", "status": "⚠️ Nothing to Stop"} @app.post("/send_text") async def send_text(teks: str = Form(...)): global desktop if not teks.strip(): return {"msg": "⚠️ Teks kosong"} if not desktop: return {"msg": "❌ VNC belum berjalan"} try: desktop.write(teks) desktop.press("enter") return {"msg": f"✅ Teks '{teks}' berhasil dikirim"} except Exception as e: return {"msg": f"Error: {e}"}