"""Admin routes: index, favicon, browse-dirs, robots.""" from __future__ import annotations from pathlib import Path from fastapi import APIRouter, HTTPException from fastapi.responses import FileResponse, PlainTextResponse, Response from core.constants import STATIC_DIR router = APIRouter() _BROWSE_BLOCKED: frozenset[str] = frozenset({ "/proc", "/sys", "/dev", "/run", "/boot", }) @router.get("/") async def index(): return FileResponse( STATIC_DIR / "index.html", headers={"Cache-Control": "no-store, max-age=0"}, ) @router.get("/favicon.ico") async def favicon(): return Response(status_code=204) @router.get("/api/browse-dirs") async def browse_dirs(path: str = "/"): p = Path(path).resolve() p_str = str(p) if any(p_str == b or p_str.startswith(b + "/") for b in _BROWSE_BLOCKED): raise HTTPException(403, "Access to this path is not permitted") if not p.is_dir(): raise HTTPException(404, "Not a directory") try: entries = sorted( [d.name for d in p.iterdir() if d.is_dir() and not d.name.startswith(".")], key=str.lower, ) except PermissionError: raise HTTPException(403, "Permission denied") parent = str(p.parent) if p.parent != p else None return {"path": str(p), "parent": parent, "dirs": entries} @router.get("/robots.txt", response_class=PlainTextResponse) async def robots_txt(): return "User-agent: *\nDisallow: /"