"""Validazione PDF e estrazione metadati tramite fitz.""" import re from pathlib import Path def validate_pdf(pdf_path: Path) -> tuple[bool, str]: """Verifica esistenza, leggibilità e presenza di testo digitale estraibile.""" if not pdf_path.exists(): return False, f"File non trovato: {pdf_path}" if pdf_path.suffix.lower() != ".pdf": return False, f"Non è un PDF: {pdf_path.name}" size = pdf_path.stat().st_size if size == 0: return False, "File vuoto" if size < 1024: return False, f"File troppo piccolo ({size} byte) — probabilmente corrotto" try: import pdfplumber with pdfplumber.open(pdf_path) as pdf: n_pages = len(pdf.pages) if n_pages == 0: return False, "PDF senza pagine" sample = min(5, n_pages) pages_with_text = sum( 1 for i in range(sample) if len((pdf.pages[i].extract_text() or "").strip()) > 50 ) if pages_with_text == 0: extended = min(15, n_pages) if extended > sample: ext_with_text = sum( 1 for i in range(sample, extended) if len((pdf.pages[i].extract_text() or "").strip()) > 50 ) if ext_with_text > 0: return True, ( f"{n_pages} pagine — prime {sample} vuote, " f"testo trovato in pagine successive " f"(possibile copertina immagine)" ) return False, ( f"Nessun testo nelle prime {extended} pagine " f"— probabilmente scansionato (OCR non supportato)" ) return True, f"{n_pages} pagine, testo digitale confermato" except MemoryError: return False, "Memoria esaurita durante l'apertura del PDF" except Exception as e: msg = str(e).lower() if "password" in msg or "encrypted" in msg: return False, "PDF protetto da password" return False, f"Impossibile aprire: {e}" def extract_metadata(pdf_path: Path) -> dict: """ Estrae title, author, year e page count dal PDF tramite fitz. Restituisce un dict con chiavi sempre presenti (stringa vuota se assenti). """ try: import fitz doc = fitz.open(str(pdf_path)) meta = doc.metadata pages = len(doc) doc.close() year = "" creation = meta.get("creationDate", "") m = re.match(r"D:(\d{4})", creation) if m: year = m.group(1) return { "source": pdf_path.name, "title": (meta.get("title") or "").strip(), "author": (meta.get("author") or "").strip(), "year": year, "pages": pages, } except Exception: return {"source": pdf_path.name, "title": "", "author": "", "year": "", "pages": 0}