119 lines
5 KiB
Python
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."}
|