ay/backend/routers/document.py
2025-06-24 18:17:53 +02:00

119 lines
5 KiB
Python

from fastapi import APIRouter, Depends, HTTPException, status, UploadFile, File
from fastapi.responses import FileResponse
from sqlalchemy.orm import Session
import os
import uuid # Pour générer des noms de fichiers uniques
from core.database import get_db
from core.security import create_access_token # Non utilisé directement ici mais potentiellement dans d'autres routers
from core.config import settings # Pour accéder au chemin d'upload
from crud import document as crud_document
from crud import user as crud_user # Pour récupérer l'utilisateur courant
from schemas import document as schemas_document
from schemas import user as schemas_user # Pour le modèle UserInDBBase ou UserResponse
from dependencies import get_current_user # Pour la protection des routes
router = APIRouter(
prefix="/documents",
tags=["Documents"],
responses={404: {"description": "Not found"}},
)
@router.post("/upload-cv", response_model=schemas_document.DocumentResponse, status_code=status.HTTP_201_CREATED)
async def upload_cv(
file: UploadFile = File(...),
db: Session = Depends(get_db),
current_user: schemas_user.UserResponse = Depends(get_current_user)
):
"""
Permet à un utilisateur authentifié d'uploader un CV.
Le fichier est stocké sur le serveur et ses métadonnées sont enregistrées en base de données.
"""
if not file.filename.lower().endswith(('.pdf', '.doc', '.docx')):
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Seuls les fichiers PDF, DOC, DOCX sont autorisés."
)
# Créer un nom de fichier unique pour éviter les collisions et les problèmes de sécurité
unique_filename = f"{uuid.uuid4()}_{file.filename}"
file_path = os.path.join(settings.UPLOADS_DIR, unique_filename)
# S'assurer que le répertoire d'uploads existe
os.makedirs(settings.UPLOADS_DIR, exist_ok=True)
try:
with open(file_path, "wb") as buffer:
# Écrit le fichier par morceaux pour les gros fichiers
while content := await file.read(1024 * 1024): # Lire par blocs de 1MB
buffer.write(content)
except Exception as e:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Erreur lors de l'enregistrement du fichier: {e}"
)
finally:
await file.close()
# Enregistrer les métadonnées du document dans la base de données
document_data = schemas_document.DocumentCreate(filename=file.filename)
db_document = crud_document.create_document(db, document_data, file_path, current_user.id)
return db_document
@router.get("/", response_model=list[schemas_document.DocumentResponse])
def get_user_documents(
db: Session = Depends(get_db),
current_user: schemas_user.UserResponse = Depends(get_current_user)
):
"""
Récupère tous les documents uploadés par l'utilisateur authentifié.
"""
documents = crud_document.get_documents_by_owner(db, current_user.id)
return documents
@router.get("/{document_id}", response_model=schemas_document.DocumentResponse)
def get_document_details(
document_id: int,
db: Session = Depends(get_db),
current_user: schemas_user.UserResponse = Depends(get_current_user)
):
"""
Récupère les détails d'un document spécifique de l'utilisateur authentifié.
"""
document = crud_document.get_document_by_id(db, document_id)
if not document:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Document non trouvé.")
if document.owner_id != current_user.id:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Vous n'avez pas accès à ce document.")
return document
@router.delete("/{document_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_document(
document_id: int,
db: Session = Depends(get_db),
current_user: schemas_user.UserResponse = Depends(get_current_user)
):
"""
Supprime un document spécifique de l'utilisateur authentifié,
à la fois de la base de données et du système de fichiers.
"""
db_document = crud_document.get_document_by_id(db, document_id)
if not db_document:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Document non trouvé.")
if db_document.owner_id != current_user.id:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Vous n'avez pas la permission de supprimer ce document.")
# Supprimer le fichier du système de fichiers
if os.path.exists(db_document.filepath):
try:
os.remove(db_document.filepath)
except OSError as e:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Erreur lors de la suppression du fichier sur le serveur: {e}"
)
# Supprimer l'entrée de la base de données
crud_document.delete_document(db, document_id)
return {"message": "Document supprimé avec succès."}