# File: backend/classifier.py import io import re from PyPDF2 import PdfReader def deep_cloud_classify(filename: str, file_bytes: bytes, file_size_bytes: int) -> str: """ Uses PyPDF2 to inspect the internal metadata and text structure of the file stream. Does not read page content, only the metadata dictionary and structural objects. """ if not filename: return "Unknown" # 1. Filename Fast-Check if bool(re.match(r"^camscanner\s\d{2}-\d{2}-\d{4}\s\d{2}\.\d{2}\.\d{2}\.pdf$", filename, re.IGNORECASE)): return "Scanned (CamScanner)" if not filename.lower().endswith(".pdf"): return "Native/Text-based" # 2. PyPDF2 Internal Metadata & Density Check try: reader = PdfReader(io.BytesIO(file_bytes)) metadata = reader.metadata or {} producer = metadata.get("/Producer", "") or "" creator = metadata.get("/Creator", "") or "" indicators = ["camscanner", "intsig", "hp scan", "brother", "xerox", "canon"] if any(i in producer.lower() or i in creator.lower() for i in indicators): return "Scanned (Branded)" # Structural Check: Does this PDF have actual text layers? has_text = False for page in reader.pages: text = page.extract_text() if text and len(text.strip()) > 50: has_text = True break file_size_mb = file_size_bytes / (1024 * 1024) page_count = len(reader.pages) density = file_size_mb / page_count if page_count > 0 else 0 if not has_text: return "Scanned (Image-Only)" elif density > 0.3: return "Scanned (High-Density)" return "Native/Text-based" except Exception as e: print(f"Classifier error on {filename}: {e}") return "Unknown"