Upload files to "frontend/routes"
This commit is contained in:
parent
c4b3c41718
commit
ff2413df86
2 changed files with 78 additions and 58 deletions
|
|
@ -25,47 +25,54 @@ async def save_backend_config(request: Request):
|
|||
form_data = await request.form()
|
||||
new_backend_url = form_data.get("backend_url", "").strip().rstrip("/")
|
||||
new_potree_url = form_data.get("potree_url", "").strip().rstrip("/")
|
||||
|
||||
|
||||
if not new_backend_url:
|
||||
return request.app.state.templates.TemplateResponse(
|
||||
"partials/backend_config.html",
|
||||
{"request": request, "current_backend_url": config.BACKEND_URL, "current_potree_url": config.POTREE_URL, "error": "URL du backend vide"},
|
||||
)
|
||||
|
||||
# Sauvegarder dans le fichier JSON
|
||||
|
||||
config_file = Path(__file__).parent.parent / "config" / "backend.json"
|
||||
config_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
|
||||
config_data = {}
|
||||
if new_backend_url:
|
||||
config_data["backend_url"] = new_backend_url
|
||||
if new_potree_url:
|
||||
config_data["potree_url"] = new_potree_url
|
||||
|
||||
|
||||
with open(config_file, "w") as f:
|
||||
json.dump(config_data, f, indent=2)
|
||||
|
||||
# Mettre à jour les variables module
|
||||
|
||||
config.BACKEND_URL = new_backend_url
|
||||
config.POTREE_URL = new_potree_url
|
||||
|
||||
|
||||
return request.app.state.templates.TemplateResponse(
|
||||
"partials/backend_config.html",
|
||||
{"request": request, "current_backend_url": new_backend_url, "current_potree_url": new_potree_url, "success": True},
|
||||
)
|
||||
|
||||
|
||||
@router.get("/list", response_class=HTMLResponse)
|
||||
@router.get("/admin/list", response_class=HTMLResponse)
|
||||
async def admin_list(request: Request):
|
||||
"""Affiche la liste de tous les nuages de points"""
|
||||
pointclouds = await api_client.list_pointclouds()
|
||||
"""
|
||||
Liste via l'api_client (tab Admin).
|
||||
Retourne cloud_list_body.html pour injection dans #cloud-list-body.
|
||||
"""
|
||||
try:
|
||||
pointclouds = await api_client.list_pointclouds()
|
||||
except Exception as e:
|
||||
return request.app.state.templates.TemplateResponse(
|
||||
"partials/cloud_list_body.html",
|
||||
{"request": request, "pointclouds": [], "error": str(e)},
|
||||
)
|
||||
return request.app.state.templates.TemplateResponse(
|
||||
"partials/cloud_list.html",
|
||||
"partials/cloud_list_body.html",
|
||||
{"request": request, "pointclouds": pointclouds},
|
||||
)
|
||||
|
||||
|
||||
@router.get("/debug/{pc_id}", response_class=HTMLResponse)
|
||||
@router.get("/admin/debug/{pc_id}", response_class=HTMLResponse)
|
||||
async def admin_debug(request: Request, pc_id: str):
|
||||
"""Affiche les informations de debug pour un nuage"""
|
||||
debug_info = await api_client.get_debug(pc_id)
|
||||
|
|
@ -75,40 +82,62 @@ async def admin_debug(request: Request, pc_id: str):
|
|||
)
|
||||
|
||||
|
||||
@router.delete("/delete/{pc_id}", response_class=HTMLResponse)
|
||||
@router.delete("/admin/delete/{pc_id}", response_class=HTMLResponse)
|
||||
async def admin_delete(request: Request, pc_id: str):
|
||||
"""Supprime un nuage de points"""
|
||||
"""Supprime un nuage de points et rafraîchit la liste"""
|
||||
try:
|
||||
result = await api_client.delete_pointcloud(pc_id)
|
||||
return request.app.state.templates.TemplateResponse(
|
||||
"partials/upload_result.html",
|
||||
{"request": request, "result": {
|
||||
"id": pc_id,
|
||||
"filename": f"{pc_id}.las",
|
||||
"size_mb": 0,
|
||||
"conversion_time_seconds": 0,
|
||||
}, "error": None},
|
||||
)
|
||||
await api_client.delete_pointcloud(pc_id)
|
||||
except Exception as e:
|
||||
return request.app.state.templates.TemplateResponse(
|
||||
"partials/upload_result.html",
|
||||
{"request": request, "error": str(e), "result": None},
|
||||
"partials/cloud_list_body.html",
|
||||
{"request": request, "pointclouds": [], "error": f"Erreur suppression : {str(e)}"},
|
||||
)
|
||||
|
||||
# Après suppression, on retourne la liste mise à jour
|
||||
from pathlib import Path as _Path
|
||||
pointclouds = []
|
||||
ept_dir = _Path(config.EPT_DIR)
|
||||
if ept_dir.exists():
|
||||
for item in sorted(ept_dir.iterdir(), key=lambda x: x.stat().st_ctime, reverse=True):
|
||||
if item.is_dir():
|
||||
total_size = sum(f.stat().st_size for f in item.rglob("*") if f.is_file())
|
||||
file_count = sum(1 for f in item.rglob("*") if f.is_file())
|
||||
if file_count > 0:
|
||||
pointclouds.append({
|
||||
"id": item.name,
|
||||
"size_mb": round(total_size / (1024 * 1024), 2),
|
||||
"file_count": file_count,
|
||||
"manifest": {},
|
||||
"created": item.stat().st_ctime,
|
||||
})
|
||||
|
||||
return request.app.state.templates.TemplateResponse(
|
||||
"partials/cloud_list_body.html",
|
||||
{"request": request, "pointclouds": pointclouds},
|
||||
)
|
||||
|
||||
|
||||
@router.post("/admin/crop/{pc_id}", response_class=HTMLResponse)
|
||||
async def admin_crop(request: Request, pc_id: str):
|
||||
"""Crop via api_client — lit le body form (appelé depuis crop_section.html)"""
|
||||
form_data = await request.form()
|
||||
try:
|
||||
box = {
|
||||
"minX": float(form_data.get("minX", 0)),
|
||||
"minY": float(form_data.get("minY", 0)),
|
||||
"minZ": float(form_data.get("minZ", 0)),
|
||||
"maxX": float(form_data.get("maxX", 0)),
|
||||
"maxY": float(form_data.get("maxY", 0)),
|
||||
"maxZ": float(form_data.get("maxZ", 0)),
|
||||
}
|
||||
except (TypeError, ValueError) as e:
|
||||
return request.app.state.templates.TemplateResponse(
|
||||
"partials/upload_result.html",
|
||||
{"request": request, "error": f"Coordonnées invalides : {str(e)}", "result": None},
|
||||
)
|
||||
|
||||
@router.post("/crop/{pc_id}", response_class=HTMLResponse)
|
||||
async def admin_crop(request: Request, pc_id: str, box: dict):
|
||||
"""
|
||||
Crop le nuage de points avec PDAL.
|
||||
|
||||
Args:
|
||||
pc_id: ID du nuage de points à cropper
|
||||
box: dict avec les coordonnées de la box 3D
|
||||
{"minX", "minY", "minZ", "maxX", "maxY", "maxZ"}
|
||||
"""
|
||||
try:
|
||||
result = await api_client.crop_pointcloud(pc_id, box)
|
||||
|
||||
if result.get("ok"):
|
||||
return request.app.state.templates.TemplateResponse(
|
||||
"partials/upload_result.html",
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@ from fastapi.responses import HTMLResponse
|
|||
import config
|
||||
import api_client
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
import os
|
||||
from datetime import datetime
|
||||
|
||||
router = APIRouter()
|
||||
|
|
@ -12,42 +10,35 @@ router = APIRouter()
|
|||
|
||||
@router.get("/viewer/list", response_class=HTMLResponse)
|
||||
async def viewer_list(request: Request):
|
||||
"""Liste les nuages de points disponibles - Endpoint autonome frontend"""
|
||||
"""
|
||||
Liste les nuages de points — retourne uniquement le contenu intérieur
|
||||
(cloud_list_body.html) pour injection dans #cloud-list-body.
|
||||
La card enveloppe et le bouton Actualiser vivent dans index.html, pas ici.
|
||||
"""
|
||||
pointclouds = []
|
||||
|
||||
# Récupérer la liste des nuages directement depuis le système de fichiers
|
||||
|
||||
ept_dir = Path(config.EPT_DIR)
|
||||
if ept_dir.exists():
|
||||
for item in sorted(ept_dir.iterdir(), key=lambda x: x.stat().st_ctime, reverse=True):
|
||||
if item.is_dir():
|
||||
# Lire le manifeste
|
||||
manifest_path = item / "manifest.json"
|
||||
manifest = {}
|
||||
if manifest_path.exists():
|
||||
try:
|
||||
manifest = {"ept_dir": item.name}
|
||||
except:
|
||||
pass
|
||||
|
||||
# Calculer la taille et le nombre de fichiers
|
||||
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,
|
||||
"manifest": manifest,
|
||||
"manifest": {},
|
||||
"created": item.stat().st_ctime,
|
||||
})
|
||||
|
||||
|
||||
return request.app.state.templates.TemplateResponse(
|
||||
"partials/cloud_list.html",
|
||||
"partials/cloud_list_body.html",
|
||||
{"request": request, "pointclouds": pointclouds},
|
||||
)
|
||||
|
||||
|
|
@ -58,4 +49,4 @@ async def viewer(request: Request, pc_id: str):
|
|||
return request.app.state.templates.TemplateResponse(
|
||||
"partials/viewer.html",
|
||||
{"request": request, "pc_id": pc_id, "embed_url": embed_url},
|
||||
)
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue