Add NAS dashboard MVP: Docker mgmt, Gitea, Files, Terminal
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
import os
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
from fastapi import APIRouter, UploadFile, File
|
||||
from fastapi.responses import FileResponse
|
||||
from config import VOLUME_ROOT
|
||||
|
||||
router = APIRouter()
|
||||
BASE = Path(VOLUME_ROOT)
|
||||
|
||||
|
||||
def _safe_path(path: str) -> Path:
|
||||
target = (BASE / path).resolve()
|
||||
if not str(target).startswith(str(BASE.resolve())):
|
||||
raise ValueError("forbidden")
|
||||
return target
|
||||
|
||||
|
||||
@router.get("/browse")
|
||||
def browse(path: str = ""):
|
||||
target = _safe_path(path)
|
||||
entries = []
|
||||
for item in sorted(target.iterdir()):
|
||||
try:
|
||||
st = item.stat()
|
||||
entries.append({"name": item.name, "is_dir": item.is_dir(), "size": st.st_size if item.is_file() else 0})
|
||||
except PermissionError:
|
||||
continue
|
||||
return {"path": str(target.relative_to(BASE)), "entries": entries}
|
||||
|
||||
|
||||
@router.get("/download")
|
||||
def download(path: str):
|
||||
return FileResponse(_safe_path(path))
|
||||
|
||||
|
||||
@router.post("/upload")
|
||||
async def upload(path: str, file: UploadFile = File(...)):
|
||||
target = _safe_path(path) / file.filename
|
||||
with open(target, "wb") as f:
|
||||
shutil.copyfileobj(file.file, f)
|
||||
return {"ok": True}
|
||||
|
||||
|
||||
@router.delete("/delete")
|
||||
def delete(path: str):
|
||||
target = _safe_path(path)
|
||||
if target.is_dir():
|
||||
shutil.rmtree(target)
|
||||
else:
|
||||
target.unlink()
|
||||
return {"ok": True}
|
||||
Reference in New Issue
Block a user