94 lines
3.2 KiB
Python

"""Contrôleur pour uploader des fichiers vers Nextcloud"""
from fastapi import APIRouter, HTTPException, UploadFile, File, Form
from fastapi.responses import JSONResponse
from nc_py_api import NextcloudException
from utils import get_nextcloud_client, create_directory_recursive, normalize_upload_paths
from typing import Optional
router = APIRouter()
@router.post("/upload")
async def upload_file(
file: UploadFile = File(..., description="Fichier à uploader"),
path: str = Form(..., description="Chemin du dossier de destination (ex: /Documents)"),
filename: Optional[str] = Form(None, description="Nom du fichier (optionnel, utilise le nom original si non spécifié)")
):
"""
Upload un fichier vers un dossier Nextcloud
Args:
file: Le fichier à uploader
path: Chemin du dossier de destination
filename: Nom du fichier (optionnel)
Returns:
JSON contenant les informations du fichier uploadé
"""
try:
# Créer le client Nextcloud
nc = get_nextcloud_client()
# Déterminer le nom du fichier
final_filename = filename if filename else file.filename
# Normaliser les chemins (gère le cas où path contient déjà le nom du fichier)
directory_path, destination_path = normalize_upload_paths(path, final_filename)
# Créer le dossier de destination récursivement s'il n'existe pas
if directory_path != "/":
try:
create_directory_recursive(nc, directory_path)
except Exception as mkdir_error:
raise HTTPException(
status_code=500,
detail=f"Impossible de créer le dossier '{directory_path}': {str(mkdir_error)}"
)
# Lire le contenu du fichier
file_content = await file.read()
# Uploader le fichier vers Nextcloud
try:
nc.files.upload(
path=destination_path,
content=file_content
)
except NextcloudException as e:
if "409" in str(e) or "412" in str(e):
raise HTTPException(
status_code=409,
detail=f"Le fichier '{final_filename}' existe déjà"
)
else:
raise HTTPException(
status_code=500,
detail=f"Erreur Nextcloud: {str(e)}"
)
# Retourner les informations du fichier uploadé
result = {
"success": True,
"message": "Fichier uploadé avec succès",
"file": {
"name": final_filename,
"path": destination_path,
"size": len(file_content),
"content_type": file.content_type
}
}
return JSONResponse(content=result, status_code=201)
except HTTPException:
raise
except Exception as e:
raise HTTPException(
status_code=500,
detail=f"Erreur interne: {str(e)}"
)
finally:
# Fermer le fichier uploadé
await file.close()