From 638f69d335d7028f07d40ab31472f6621207ee2b Mon Sep 17 00:00:00 2001 From: Chris Christiansen Date: Thu, 2 Jul 2026 17:32:57 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20/tui-command=20endepunkt=20=E2=80=94=20?= =?UTF-8?q?ekte=20shell-eksekvering=20med=20timeout=20og=20auth?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.py | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/main.py b/main.py index c7740d4..dce5b2b 100644 --- a/main.py +++ b/main.py @@ -1068,3 +1068,34 @@ if __name__ == "__main__": import uvicorn port = int(os.environ.get("PORT", 8080)) uvicorn.run(app, host="0.0.0.0", port=port) + + +class TuiCommandRequest(BaseModel): + command: str + timeout: int = 30 + +async def _tui_command(request: Request, req: TuiCommandRequest): + import asyncio, shlex + cmd = req.command.strip() + if not cmd: + return JSONResponse({"output": "", "exit_code": 1, "error": "Tom kommando"}) + try: + proc = await asyncio.create_subprocess_shell( + cmd, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, + cwd="/home/chris.christiansen/OSVauco", + ) + stdout, stderr = await asyncio.wait_for(proc.communicate(), timeout=req.timeout) + return JSONResponse({ + "output": stdout.decode(errors="replace"), + "stderr": stderr.decode(errors="replace"), + "exit_code": proc.returncode, + }) + except asyncio.TimeoutError: + return JSONResponse({"output": "", "stderr": f"Timeout etter {req.timeout}s", "exit_code": 124}) + except Exception as e: + return JSONResponse({"output": "", "stderr": str(e), "exit_code": 1}) + +app.add_api_route("/tui-command", endpoint=require_auth(_tui_command), methods=["POST"]) +