From 57ee7f341924295eb6ee08cabe64fea4aca6cb8a Mon Sep 17 00:00:00 2001 From: Thierry Date: Thu, 26 Mar 2026 11:31:06 +0100 Subject: [PATCH] Upload files to "frontend/routes" --- frontend/routes/__init__.py | Bin 0 -> 1024 bytes frontend/routes/admin.py | 58 ++++++++++++++++++++++++++++++++++++ frontend/routes/crop.py | 19 ++++++++++++ frontend/routes/upload.py | 54 +++++++++++++++++++++++++++++++++ frontend/routes/viewer.py | 22 ++++++++++++++ 5 files changed, 153 insertions(+) create mode 100644 frontend/routes/__init__.py create mode 100644 frontend/routes/admin.py create mode 100644 frontend/routes/crop.py create mode 100644 frontend/routes/upload.py create mode 100644 frontend/routes/viewer.py diff --git a/frontend/routes/__init__.py b/frontend/routes/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..06d7405020018ddf3cacee90fd4af10487da3d20 GIT binary patch literal 1024 ScmZQz7zLvtFd70QH3R?z00031 literal 0 HcmV?d00001 diff --git a/frontend/routes/admin.py b/frontend/routes/admin.py new file mode 100644 index 0000000..b8b9d07 --- /dev/null +++ b/frontend/routes/admin.py @@ -0,0 +1,58 @@ +from fastapi import APIRouter, Request +from fastapi.responses import HTMLResponse +import api_client + +router = APIRouter() + + +def _render(request: Request, template: str, **kwargs) -> HTMLResponse: + """Render using JinjaX catalog for all .jinja templates""" + catalog = request.app.state.catalog + html_content = catalog.render(template, **kwargs) + return HTMLResponse(content=html_content) + + +@router.get("/admin/list", response_class=HTMLResponse) +async def admin_list(request: Request): + try: + pointclouds = await api_client.list_pointclouds() + return _render( + request, "partials/cloud_list", + pointclouds=pointclouds, error=None, + ) + except Exception as e: + return _render( + request, "partials/cloud_list", + pointclouds=[], error=str(e), + ) + + +@router.get("/admin/debug/{pc_id}", response_class=HTMLResponse) +async def admin_debug(request: Request, pc_id: str): + try: + data = await api_client.get_debug(pc_id) + return _render( + request, "partials/debug_panel", + pc_id=pc_id, data=data, error=None, + ) + except Exception as e: + return _render( + request, "partials/debug_panel", + pc_id=pc_id, data=None, error=str(e), + ) + + +@router.delete("/admin/delete/{pc_id}", response_class=HTMLResponse) +async def admin_delete(request: Request, pc_id: str): + try: + await api_client.delete_pointcloud(pc_id) + pointclouds = await api_client.list_pointclouds() + return _render( + request, "partials/cloud_list", + pointclouds=pointclouds, error=None, + ) + except Exception as e: + return _render( + request, "partials/cloud_list", + pointclouds=[], error=str(e), + ) \ No newline at end of file diff --git a/frontend/routes/crop.py b/frontend/routes/crop.py new file mode 100644 index 0000000..a731d63 --- /dev/null +++ b/frontend/routes/crop.py @@ -0,0 +1,19 @@ +from fastapi import APIRouter, Request +from fastapi.responses import JSONResponse +from pydantic import BaseModel +import api_client + +router = APIRouter() + + +class CropPayload(BaseModel): + matrix: list[float] + scale: list[float] + subset_name: str = "" + + +@router.post("/crop/{pc_id}") +async def crop(pc_id: str, payload: CropPayload): + """Proxifie la requête de clipping vers le backend FastAPI.""" + result = await api_client.crop_pointcloud(pc_id, payload.model_dump()) + return JSONResponse(result) \ No newline at end of file diff --git a/frontend/routes/upload.py b/frontend/routes/upload.py new file mode 100644 index 0000000..08f443d --- /dev/null +++ b/frontend/routes/upload.py @@ -0,0 +1,54 @@ +# routes/upload.py + +from fastapi import APIRouter, Request, UploadFile, File, HTTPException +from fastapi.responses import HTMLResponse +from pathlib import Path +import api_client +import config + +router = APIRouter() + + +def _render(request: Request, template: str, **kwargs) -> HTMLResponse: + """Render using JinjaX catalog for all .jinja templates""" + catalog = request.app.state.catalog + html_content = catalog.render(template, **kwargs) + return HTMLResponse(content=html_content) + + +@router.get("/", response_class=HTMLResponse) +async def index(request: Request): + return _render(request, "index") + + +@router.get("/health-check", response_class=HTMLResponse) +async def health_check(request: Request): + try: + data = await api_client.check_health() + return _render( + request, + "partials/health_status", + ok=True, + entwine_available=data.get("entwine_available", False), + disk_free_gb=data.get("disk_free_gb", "?"), + ) + except Exception as e: + return _render(request, "partials/health_status", ok=False, error=str(e)) + + +@router.post("/upload", response_class=HTMLResponse) +async def upload(request: Request, file: UploadFile = File(...)): + suffix = Path(file.filename).suffix.lower() + if suffix not in config.SUPPORTED_EXTENSIONS: + return _render( + request, + "partials/upload_result", + error=f"Format non supporté : {suffix}. " + f"Formats acceptés : {', '.join(config.SUPPORTED_EXTENSIONS)}", + result=None, + ) + try: + data = await api_client.upload_file(file.filename, await file.read()) + return _render(request, "partials/upload_result", result=data, error=None) + except Exception as e: + return _render(request, "partials/upload_result", error=str(e), result=None) \ No newline at end of file diff --git a/frontend/routes/viewer.py b/frontend/routes/viewer.py new file mode 100644 index 0000000..2b33cef --- /dev/null +++ b/frontend/routes/viewer.py @@ -0,0 +1,22 @@ +from fastapi import APIRouter, Request +from fastapi.responses import HTMLResponse +import config + +router = APIRouter() + + +def _render(request: Request, template: str, **kwargs) -> HTMLResponse: + """Render using JinjaX catalog for all .jinja templates""" + catalog = request.app.state.catalog + html_content = catalog.render(template, **kwargs) + return HTMLResponse(content=html_content) + + +@router.get("/viewer/{pc_id}", response_class=HTMLResponse) +async def viewer(request: Request, pc_id: str): + return _render( + request, + "partials/viewer", + pc_id=pc_id, + embed_url=f"{config.BACKEND_INTERNAL_URL}/viewer-embed/{pc_id}", + ) \ No newline at end of file