From 9c799885596df9a598a74cdb417b899510f4fd61 Mon Sep 17 00:00:00 2001 From: jletienne Date: Mon, 20 Oct 2025 18:07:02 +0200 Subject: [PATCH] Add upload_base64 controller: Implement endpoint for uploading files encoded in base64 to Nextcloud, including error handling for directory creation and file upload conflicts. --- controllers/upload_base64.py | 111 +++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 controllers/upload_base64.py diff --git a/controllers/upload_base64.py b/controllers/upload_base64.py new file mode 100644 index 0000000..da9ab7f --- /dev/null +++ b/controllers/upload_base64.py @@ -0,0 +1,111 @@ +"""Contrôleur pour uploader des fichiers en base64 (pour clients Omnis/anciens)""" +from fastapi import APIRouter, HTTPException +from fastapi.responses import JSONResponse +from pydantic import BaseModel +from nc_py_api import NextcloudException +from utils import get_nextcloud_client +from typing import Optional +import base64 + +router = APIRouter() + + +class FileUploadBase64(BaseModel): + """Modèle pour l'upload de fichier en base64""" + path: str # Chemin du dossier de destination + filename: str # Nom du fichier + file_base64: str # Contenu du fichier encodé en base64 + content_type: Optional[str] = "application/octet-stream" # Type MIME du fichier + + +@router.post("/upload-base64") +async def upload_file_base64(data: FileUploadBase64): + """ + Upload un fichier vers Nextcloud à partir de données base64 + + Args: + data: Objet contenant le fichier en base64 et les métadonnées + + Returns: + JSON contenant les informations du fichier uploadé + """ + try: + # Créer le client Nextcloud + nc = get_nextcloud_client() + + # Normaliser le chemin de destination + if data.path == "/" or data.path == "": + destination_path = f"/{data.filename}" + directory_path = "/" + else: + # Enlever les slashes de début/fin et ajouter le nom du fichier + clean_path = data.path.strip("/") + destination_path = f"/{clean_path}/{data.filename}" + directory_path = f"/{clean_path}" + + # Vérifier si le dossier existe, sinon le créer + if directory_path != "/": + try: + # Vérifier si le dossier existe + nc.files.by_path(directory_path) + except NextcloudException as e: + if "404" in str(e): + # Le dossier n'existe pas, on le crée + try: + nc.files.mkdir(directory_path) + print(f"📁 Dossier créé : {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)}" + ) + + # Décoder le fichier base64 + try: + file_content = base64.b64decode(data.file_base64) + except Exception as decode_error: + raise HTTPException( + status_code=400, + detail=f"Erreur lors du décodage base64 : {str(decode_error)}" + ) + + # 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 '{data.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": data.filename, + "path": destination_path, + "size": len(file_content), + "content_type": data.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)}" + ) +