from fastapi import FastAPI, UploadFile, File, Form, HTTPException from fastapi.responses import FileResponse from fastapi.middleware.cors import CORSMiddleware from fastapi.staticfiles import StaticFiles import yaml import os import subprocess from pathlib import Path from utils import parse_yaml_config, get_presets_dir app = FastAPI() # CORS setup for frontend use app.add_middleware( CORSMiddleware, allow_origins=["*"], # For dev; restrict for production allow_methods=["*"], allow_headers=["*"], ) # Serve static files (e.g., HTML GUI) app.mount("/static", StaticFiles(directory="static"), name="static") @app.get("/") def read_root(): return FileResponse("static/index.html") @app.post("/upload-config/") async def upload_config(file: UploadFile = File(...)): config_data = yaml.safe_load(await file.read()) return {"parsed": config_data} @app.post("/transcode/") async def transcode(yaml_config: dict): try: ffmpeg_cmd = parse_yaml_config(yaml_config) process = subprocess.run(ffmpeg_cmd, check=True, capture_output=True, text=True) return { "status": "success", "cmd": ffmpeg_cmd, "output": process.stdout, "error": process.stderr } except subprocess.CalledProcessError as e: raise HTTPException(status_code=500, detail=e.stderr or str(e)) @app.get("/browse/") def browse(path: str = "/data"): if not os.path.exists(path): raise HTTPException(status_code=404, detail="Path not found") entries = [{ "name": f, "is_dir": os.path.isdir(os.path.join(path, f)) } for f in os.listdir(path)] return {"path": path, "entries": entries} @app.post("/save-preset/") def save_preset(name: str = Form(...), file: UploadFile = File(...)): path = get_presets_dir() / f"{name}.yml" with open(path, "wb") as f: f.write(file.file.read()) return {"message": "Preset saved"} @app.get("/list-presets/") def list_presets(): return {"presets": [p.stem for p in get_presets_dir().glob("*.yml")]} @app.get("/preset/{name}") def get_preset(name: str): path = get_presets_dir() / f"{name}.yml" if not path.exists(): raise HTTPException(status_code=404, detail="Preset not found") return FileResponse(path)