| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- import os
- import shutil
- from fastapi import FastAPI, Request, File, UploadFile, Form
- from fastapi.responses import HTMLResponse, RedirectResponse
- from fastapi.templating import Jinja2Templates
- from fastapi.staticfiles import StaticFiles
- # =====================================================================
- # MODIFICATION START: REMOVED ROOT_PATH
- # Reason: We removed the `root_path="/patch-manager"` argument.
- # Because Nginx already strips the prefix before passing traffic to
- # this container, setting it here was causing FastAPI to double-process
- # the route and throw internal 404s. Standard FastAPI initialization is best.
- # =====================================================================
- app = FastAPI()
- # =====================================================================
- # MODIFICATION END
- # =====================================================================
- # Failsafe: Create the directory inside the container if it somehow gets missed
- os.makedirs("static", exist_ok=True)
- app.mount("/static", StaticFiles(directory="static"), name="static")
- templates = Jinja2Templates(directory="templates")
- # The persistent directory for your custom code
- OVERLAY_DIR = "/srv"
- @app.get("/", response_class=HTMLResponse)
- async def index(request: Request):
- files = []
- if os.path.exists(OVERLAY_DIR):
- for root, dirs, filenames in os.walk(OVERLAY_DIR):
- for filename in filenames:
- rel_path = os.path.relpath(os.path.join(root, filename), OVERLAY_DIR)
- files.append(rel_path)
- return templates.TemplateResponse("index.html", {"request": request, "files": sorted(files)})
- @app.post("/upload")
- async def upload_file(file: UploadFile = File(...), target_path: str = Form("")):
- save_dir = os.path.join(OVERLAY_DIR, target_path.strip("/"))
- os.makedirs(save_dir, exist_ok=True)
- file_location = os.path.join(save_dir, file.filename)
- with open(file_location, "wb+") as file_object:
- shutil.copyfileobj(file.file, file_object)
-
- # =====================================================================
- # MODIFICATION START: EXPLICIT NGINX REDIRECTS
- # Reason: Since we removed root_path, we must explicitly tell the
- # user's browser to redirect back to the Nginx URL ("/patch-manager/")
- # after a successful action, otherwise it redirects to the internal "/"
- # and gets lost on the main ArduPilot page.
- # =====================================================================
- return RedirectResponse(url="/patch-manager/", status_code=303)
- # =====================================================================
- # MODIFICATION END
- # =====================================================================
- @app.post("/delete")
- async def delete_file(filepath: str = Form(...)):
- target = os.path.join(OVERLAY_DIR, filepath)
- if os.path.exists(target):
- os.remove(target)
- target_dir = os.path.dirname(target)
- if not os.listdir(target_dir) and target_dir != OVERLAY_DIR:
- os.rmdir(target_dir)
- return RedirectResponse(url="/patch-manager/", status_code=303)
- @app.get("/edit", response_class=HTMLResponse)
- async def edit_file(request: Request, filepath: str):
- target = os.path.join(OVERLAY_DIR, filepath)
- content = ""
- if os.path.exists(target):
- with open(target, "r", encoding="utf-8", errors="ignore") as f:
- content = f.read()
- return templates.TemplateResponse("edit.html", {"request": request, "filepath": filepath, "content": content})
- @app.post("/edit")
- async def save_file(filepath: str = Form(...), content: str = Form(...)):
- target = os.path.join(OVERLAY_DIR, filepath)
- if os.path.exists(target):
- with open(target, "w", encoding="utf-8") as f:
- f.write(content)
- return RedirectResponse(url="/patch-manager/", status_code=303)
|