From 26088d26a2317c3fa3ae0010fca37f4bcec1d3c5 Mon Sep 17 00:00:00 2001 From: Thierry Date: Wed, 1 Apr 2026 21:32:50 +0200 Subject: [PATCH] Upload files to "backend" --- backend/__init__.py | Bin 0 -> 1024 bytes backend/config.py | 32 +++++++++++++++ backend/main.py | 94 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 126 insertions(+) create mode 100644 backend/__init__.py create mode 100644 backend/config.py create mode 100644 backend/main.py diff --git a/backend/__init__.py b/backend/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..06d7405020018ddf3cacee90fd4af10487da3d20 GIT binary patch literal 1024 ScmZQz7zLvtFd70QH3R?z00031 literal 0 HcmV?d00001 diff --git a/backend/config.py b/backend/config.py new file mode 100644 index 0000000..45e24f4 --- /dev/null +++ b/backend/config.py @@ -0,0 +1,32 @@ +import os +from pathlib import Path + +# URL Potree - configurée via variable d'environnement POTREE_URL +# Pour le développement local : POTREE_URL=http://localhost:8090 +# Pour la production : POTREE_URL=http://potree_server:8090 + +def load_potree_config(): + """Charge la configuration Potree depuis les variables d'environnement.""" + return os.getenv( + "POTREE_URL", "http://localhost:8090" + ).strip().rstrip("/") + +def get_entwine_path(): + """Retourne le chemin de entwine ou None si non trouvé""" + path = os.getenv("ENTWINE_PATH") + if path: + return path.strip() + return None + +BASE_DIR = Path(__file__).resolve().parent +DATA_DIR = BASE_DIR / "data" +UPLOADS_DIR = DATA_DIR / "uploads" +EPT_DIR = DATA_DIR / "ept" # était POTREE_DIR + +UPLOADS_DIR.mkdir(parents=True, exist_ok=True) +EPT_DIR.mkdir(parents=True, exist_ok=True) + +SUPPORTED_FORMATS = [".las", ".laz", ".ply", ".xyz", ".pts"] + +POTREE_URL = load_potree_config() +ENTWINE_PATH = get_entwine_path() diff --git a/backend/main.py b/backend/main.py new file mode 100644 index 0000000..8980be4 --- /dev/null +++ b/backend/main.py @@ -0,0 +1,94 @@ +from fastapi import FastAPI +from fastapi.staticfiles import StaticFiles +from fastapi.responses import HTMLResponse, RedirectResponse +from config import EPT_DIR +from routes import upload, viewer, admin +from utils.disk import get_disk_usage, get_entwine_path +import subprocess + +ENTWINE_PATH = get_entwine_path() + +app = FastAPI(title="PointCloud Backend") +app.mount("/ept_data", StaticFiles(directory=str(EPT_DIR)), name="ept_data") +app.mount("/static", StaticFiles(directory="static"), name="static") +app.mount("/potree", StaticFiles(directory="static/potree"), name="potree") + +# ── Fichiers Potree dans /static ───────────────────────────────────────────── +app.mount("/static/potree", StaticFiles(directory="static/potree"), name="static_potree") + +app.include_router(upload.router) +app.include_router(viewer.router) +app.include_router(admin.router) + +@app.get("/api") +def home(): + return RedirectResponse(url="/docs") + +@app.get("/health") +def health(): + return { + "ok": True, + "entwine_available": ENTWINE_PATH is not None, + "entwine_path": ENTWINE_PATH, + "disk_free_gb": get_disk_usage(), + } + +def get_pdal_info() -> dict: + """Retourne version et path de pdal via subprocess.""" + info = {"path": None, "version": None} + + try: + result = subprocess.run( + ["which", "pdal"], + capture_output=True, text=True, check=False + ) + if result.returncode == 0: + info["path"] = result.stdout.strip() + except Exception: + pass + + try: + result = subprocess.run( + ["pdal", "--version"], + capture_output=True, text=True, check=False + ) + if result.returncode == 0: + # Sortie : "---\npdal 2.10.0 (git-version: 22e6b2)\n---" + lines = [l.strip() for l in result.stdout.strip().splitlines() + if l.strip() and not l.startswith("-")] + if lines: + info["version"] = lines[0] + except Exception: + pass + + return info + + +@app.get("/", response_class=HTMLResponse) +def home(): + entwine_path = get_entwine_path() + pdal = get_pdal_info() + + return f""" + + + + + Backend - PointCloud + + + +

Backend PointCloud OK ✅

+ +

Configuration

+ + +""" \ No newline at end of file