import io import logging from typing import Optional from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, Form from core.subscription.middleware import verify_token from agents.auditor import audit_final_document, GlobalAuditOutput from pypdf import PdfReader import docx logger = logging.getLogger(__name__) router = APIRouter(prefix="/api/audit", tags=["audit"]) def extract_text_from_file(filename: str, content: bytes) -> str: ext = filename.split(".")[-1].lower() if "." in filename else "" if ext == "pdf": try: reader = PdfReader(io.BytesIO(content)) text = [] for page in reader.pages: text.append(page.extract_text() or "") return "\n".join(text) except Exception as e: logger.error(f"Error parsing PDF: {e}") raise HTTPException(status_code=400, detail="Nie można odczytać pliku PDF.") elif ext == "docx": try: doc = docx.Document(io.BytesIO(content)) return "\n".join([para.text for para in doc.paragraphs]) except Exception as e: logger.error(f"Error parsing DOCX: {e}") raise HTTPException(status_code=400, detail="Nie można odczytać pliku DOCX.") else: try: return content.decode("utf-8") except: raise HTTPException(status_code=400, detail="Nieobsługiwany format pliku. Obsługiwane są PDF, DOCX oraz TXT.") @router.post("/reverse-audit", response_model=GlobalAuditOutput) async def reverse_audit( file: UploadFile = File(...), program_name: Optional[str] = Form("Nieznany program"), token_data: dict = Depends(verify_token) ): """ Endpoint obsługujący funkcję Reverse Audit. Przyjmuje plik PDF/DOCX wniosku i uruchamia audytor GraphRAG. """ if not file: raise HTTPException(status_code=400, detail="Brak pliku.") file_content = await file.read() extracted_text = extract_text_from_file(file.filename, file_content) if not extracted_text or len(extracted_text.strip()) < 50: raise HTTPException(status_code=400, detail="Plik jest pusty lub nie udało się odczytać wystarczającej ilości tekstu.") try: audit_result = audit_final_document( project_id="reverse_audit", program_name=program_name, content=extracted_text, enable_multi_perspective=True, is_external_audit=True ) return audit_result except Exception as e: logger.error(f"Error in reverse_audit: {e}") raise HTTPException(status_code=500, detail=f"Błąd podczas przeprowadzania audytu: {str(e)}")