|
from fastapi import APIRouter, File, UploadFile, HTTPException, Depends |
|
from bson.objectid import ObjectId |
|
import os |
|
import PyPDF2 |
|
from io import BytesIO |
|
from datetime import datetime |
|
|
|
from auth import get_admin_user |
|
from database import get_db |
|
from config import SAVE_FOLDER |
|
from chat import embedding_model |
|
|
|
router = APIRouter(prefix="/api/admin", tags=["Administration"]) |
|
db=get_db() |
|
|
|
@router.post("/knowledge/upload") |
|
async def upload_pdf( |
|
file: UploadFile = File(...), |
|
title: str = None, |
|
tags: str = None, |
|
current_user: dict = Depends(get_admin_user) |
|
): |
|
try: |
|
if not file.filename.endswith('.pdf'): |
|
raise HTTPException(status_code=400, detail="Le fichier doit être un PDF") |
|
|
|
contents = await file.read() |
|
pdf_file = BytesIO(contents) |
|
|
|
pdf_reader = PyPDF2.PdfReader(pdf_file) |
|
text_content = "" |
|
for page_num in range(len(pdf_reader.pages)): |
|
text_content += pdf_reader.pages[page_num].extract_text() + "\n" |
|
|
|
embedding = None |
|
if embedding_model: |
|
try: |
|
max_length = 5000 |
|
truncated_text = text_content[:max_length] |
|
embedding = embedding_model.embed_query(truncated_text).tolist() |
|
except Exception as e: |
|
print(f"Erreur: {str(e)}") |
|
|
|
doc_id = ObjectId() |
|
|
|
pdf_path = f"files/{str(doc_id)}.pdf" |
|
os.makedirs("files", exist_ok=True) |
|
with open(pdf_path, "wb") as f: |
|
pdf_file.seek(0) |
|
f.write(contents) |
|
|
|
document = { |
|
"_id": doc_id, |
|
"text": text_content, |
|
"embedding": embedding, |
|
"title": title or file.filename, |
|
"tags": tags.split(",") if tags else [], |
|
"uploaded_by": str(current_user["_id"]), |
|
"upload_date": datetime.utcnow() |
|
} |
|
|
|
print(f"Tentative d'insertion du document avec ID: {doc_id}") |
|
result = db.connaissances.insert_one(document) |
|
print(f"Document inséré avec ID: {result.inserted_id}") |
|
|
|
verification = db.connaissances.find_one({"_id": doc_id}) |
|
if verification: |
|
print(f"Document vérifié et trouvé dans la base de données") |
|
return {"success": True, "document_id": str(doc_id)} |
|
else: |
|
print(f"ERREUR: Document non trouvé après insertion") |
|
return {"success": False, "error": "Document non trouvé après insertion"} |
|
|
|
except Exception as e: |
|
import traceback |
|
print(f"Erreur lors de l'upload du PDF: {traceback.format_exc()}") |
|
raise HTTPException(status_code=500, detail=f"Erreur: {str(e)}") |
|
|
|
@router.get("/knowledge") |
|
async def list_documents(current_user: dict = Depends(get_admin_user)): |
|
try: |
|
documents = list(db.connaissances.find().sort("upload_date", -1)) |
|
|
|
result = [] |
|
for doc in documents: |
|
doc_safe = { |
|
"id": str(doc["_id"]), |
|
"title": doc.get("title", "Sans titre"), |
|
"tags": doc.get("tags", []), |
|
"date": doc.get("upload_date").isoformat() if "upload_date" in doc else None, |
|
"text_preview": doc.get("text", "")[:100] + "..." if len(doc.get("text", "")) > 100 else doc.get("text", "") |
|
} |
|
result.append(doc_safe) |
|
|
|
return {"documents": result} |
|
except Exception as e: |
|
print(f"Erreur lors de la liste des documents: {str(e)}") |
|
raise HTTPException(status_code=500, detail=f"Erreur: {str(e)}") |
|
|
|
@router.delete("/knowledge/{document_id}") |
|
async def delete_document(document_id: str, current_user: dict = Depends(get_admin_user)): |
|
try: |
|
try: |
|
doc_id = ObjectId(document_id) |
|
except Exception: |
|
raise HTTPException(status_code=400, detail="ID de document invalide") |
|
|
|
document = db.connaissances.find_one({"_id": doc_id}) |
|
if not document: |
|
raise HTTPException(status_code=404, detail="Document non trouvé") |
|
|
|
result = db.connaissances.delete_one({"_id": doc_id}) |
|
|
|
if result.deleted_count == 0: |
|
raise HTTPException(status_code=500, detail="Échec de la suppression du document") |
|
|
|
pdf_path = f"files/{document_id}.pdf" |
|
if os.path.exists(pdf_path): |
|
try: |
|
os.remove(pdf_path) |
|
print(f"Fichier supprimé: {pdf_path}") |
|
except Exception as e: |
|
print(f"Erreur lors de la suppression du fichier: {str(e)}") |
|
|
|
return {"success": True, "message": "Document supprimé avec succès"} |
|
|
|
except HTTPException as he: |
|
raise he |
|
except Exception as e: |
|
raise HTTPException(status_code=500, detail=f"Erreur lors de la suppression: {str(e)}") |