PyNextcloud/controllers/upload_base64.py

112 lines
3.8 KiB
Python

"""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)}"
)