aorus
This commit is contained in:
@@ -8,7 +8,7 @@ from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from fastapi import APIRouter, Depends
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from fastapi.responses import FileResponse
|
||||
from starlette.background import BackgroundTask
|
||||
from sqlmodel import Session, select
|
||||
@@ -235,8 +235,8 @@ def get_debug_system_stats() -> dict[str, Any]:
|
||||
}
|
||||
|
||||
|
||||
@router.get("/settings/backup/download")
|
||||
def download_backup_zip() -> FileResponse:
|
||||
def _create_backup_zip() -> tuple[Path, str]:
|
||||
"""Crée l'archive ZIP de sauvegarde. Retourne (chemin_tmp, nom_fichier)."""
|
||||
now = datetime.now(timezone.utc)
|
||||
ts = now.strftime("%Y%m%d_%H%M%S")
|
||||
db_path = _resolve_sqlite_db_path()
|
||||
@@ -247,17 +247,12 @@ def download_backup_zip() -> FileResponse:
|
||||
os.close(fd)
|
||||
tmp_zip = Path(tmp_zip_path)
|
||||
|
||||
stats = {
|
||||
"database_files": 0,
|
||||
"upload_files": 0,
|
||||
"text_files": 0,
|
||||
}
|
||||
stats = {"database_files": 0, "upload_files": 0, "text_files": 0}
|
||||
|
||||
with zipfile.ZipFile(tmp_zip, mode="w", compression=zipfile.ZIP_DEFLATED, compresslevel=6) as zipf:
|
||||
if db_path and db_path.is_file():
|
||||
zipf.write(db_path, arcname=f"db/{db_path.name}")
|
||||
stats["database_files"] = 1
|
||||
|
||||
stats["upload_files"] = _zip_directory(zipf, uploads_dir, "uploads")
|
||||
stats["text_files"] = _zip_data_text_files(zipf, data_root, db_path, uploads_dir)
|
||||
|
||||
@@ -274,10 +269,66 @@ def download_backup_zip() -> FileResponse:
|
||||
}
|
||||
zipf.writestr("manifest.json", json.dumps(manifest, ensure_ascii=False, indent=2))
|
||||
|
||||
download_name = f"jardin_backup_{ts}.zip"
|
||||
return tmp_zip, f"jardin_backup_{ts}.zip"
|
||||
|
||||
|
||||
@router.get("/settings/backup/download")
|
||||
def download_backup_zip() -> FileResponse:
|
||||
tmp_zip, download_name = _create_backup_zip()
|
||||
return FileResponse(
|
||||
path=str(tmp_zip),
|
||||
media_type="application/zip",
|
||||
filename=download_name,
|
||||
background=BackgroundTask(_safe_remove, str(tmp_zip)),
|
||||
)
|
||||
|
||||
|
||||
@router.post("/settings/backup/samba")
|
||||
def backup_to_samba(session: Session = Depends(get_session)) -> dict[str, Any]:
|
||||
"""Envoie une sauvegarde ZIP vers un partage Samba/CIFS."""
|
||||
|
||||
def _get(key: str, default: str = "") -> str:
|
||||
row = session.exec(select(UserSettings).where(UserSettings.cle == key)).first()
|
||||
return row.valeur if row else default
|
||||
|
||||
server = _get("samba_serveur").strip()
|
||||
share = _get("samba_partage").strip()
|
||||
username = _get("samba_utilisateur").strip()
|
||||
password = _get("samba_motdepasse")
|
||||
subfolder = _get("samba_sous_dossier").strip().strip("/\\")
|
||||
|
||||
if not server or not share:
|
||||
raise HTTPException(400, "Configuration Samba incomplète : serveur et partage requis.")
|
||||
|
||||
try:
|
||||
import smbclient # type: ignore
|
||||
except ImportError:
|
||||
raise HTTPException(500, "Module smbprotocol non installé dans l'environnement.")
|
||||
|
||||
tmp_zip, filename = _create_backup_zip()
|
||||
try:
|
||||
smbclient.register_session(server, username=username or None, password=password or None)
|
||||
|
||||
remote_dir = f"\\\\{server}\\{share}"
|
||||
if subfolder:
|
||||
remote_dir = f"{remote_dir}\\{subfolder}"
|
||||
try:
|
||||
smbclient.makedirs(remote_dir, exist_ok=True)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
remote_path = f"{remote_dir}\\{filename}"
|
||||
|
||||
with open(tmp_zip, "rb") as local_f:
|
||||
data = local_f.read()
|
||||
with smbclient.open_file(remote_path, mode="wb") as smb_f:
|
||||
smb_f.write(data)
|
||||
|
||||
return {"ok": True, "fichier": filename, "chemin": remote_path}
|
||||
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception as exc:
|
||||
raise HTTPException(500, f"Erreur Samba : {exc}") from exc
|
||||
finally:
|
||||
_safe_remove(str(tmp_zip))
|
||||
|
||||
Reference in New Issue
Block a user