from fastapi import APIRouter, HTTPException, Query, Request from fastapi.responses import JSONResponse, HTMLResponse from config import EPT_DIR, POTREE_URL import config from services.manifest import read_manifest from services.html_generator import generate_viewer_html import shutil router = APIRouter() @router.get("/viewer/list", response_class=HTMLResponse) def list_pointclouds(request: Request): """Liste les nuages de points disponibles""" from fastapi import Request pointclouds = [] for item in sorted(EPT_DIR.iterdir(), key=lambda x: x.stat().st_ctime, reverse=True): if item.is_dir(): total_size = 0 file_count = 0 for f in item.rglob("*"): if f.is_file(): total_size += f.stat().st_size file_count += 1 if file_count > 0: pointclouds.append({ "id": item.name, "size_mb": round(total_size / (1024 * 1024), 2), "file_count": file_count, "created": item.stat().st_ctime, }) return request.app.state.templates.TemplateResponse( "partials/cloud_list.html", {"request": request, "pointclouds": pointclouds}, ) @router.get("/viewer/{pc_id}") def viewer(pc_id: str, potree_url: str = Query(default=POTREE_URL, description="URL du serveur Potree")): out_dir = EPT_DIR / pc_id if not out_dir.exists(): raise HTTPException(404, f"ID {pc_id} non trouvé") manifest = read_manifest(out_dir) return HTMLResponse(generate_viewer_html(pc_id, manifest.get("ept_dir"), embed=False, potree_url=potree_url)) @router.get("/viewer-embed/{pc_id}") def viewer_embed(pc_id: str, potree_url: str = Query(default=POTREE_URL, description="URL du serveur Potree")): out_dir = EPT_DIR / pc_id if not out_dir.exists(): raise HTTPException(404, f"ID {pc_id} non trouvé") manifest = read_manifest(out_dir) return HTMLResponse(generate_viewer_html(pc_id, manifest.get("ept_dir"), embed=True, potree_url=potree_url))