#!/usr/bin/env python3 """ Verification and Audit Script for Milestone 3 Deliverables. Checks: 1. XML well-formedness of docs/PANDUAN_SISTEM_LENGKAP.fodt 2. Presence and integrity of embedded images and styles in .fodt 3. PDF compilation and page count 4. Rendering pages to test PNGs via pdftoppm 5. Visual layout checks (no text clipping, crisp images, page breaks) """ import os import sys import subprocess import xml.etree.ElementTree as ET from PIL import Image WORKSPACE_ROOT = "/home/asus/feedmill/reTraining" FODT_PATH = os.path.join(WORKSPACE_ROOT, "docs/PANDUAN_SISTEM_LENGKAP.fodt") PDF_PATH = os.path.join(WORKSPACE_ROOT, "docs/PANDUAN_SISTEM_LENGKAP.pdf") AUDIT_DIR = os.path.join(WORKSPACE_ROOT, ".agents/worker_m3/audit_render") os.makedirs(AUDIT_DIR, exist_ok=True) def verify_fodt(): print("--- 1. AUDITING FODT (Flat XML OpenDocument Text) ---") assert os.path.exists(FODT_PATH), f"FODT file missing: {FODT_PATH}" size = os.path.getsize(FODT_PATH) print(f"FODT File Size: {size:,} bytes") assert size > 5_000_000, f"FODT file suspiciously small: {size} bytes" tree = ET.parse(FODT_PATH) root = tree.getroot() print(f"Root Element: {root.tag}") assert root.tag.endswith("document"), f"Unexpected root tag: {root.tag}" # Namespaces ns = { "office": "urn:oasis:names:tc:opendocument:xmlns:office:1.0", "text": "urn:oasis:names:tc:opendocument:xmlns:text:1.0", "style": "urn:oasis:names:tc:opendocument:xmlns:style:1.0", "draw": "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0", "table": "urn:oasis:names:tc:opendocument:xmlns:table:1.0", } # Check headings h_elements = root.findall(".//text:h", ns) print(f"Total Heading Elements (): {len(h_elements)}") assert len(h_elements) >= 70, f"Too few heading elements: {len(h_elements)}" # Check paragraphs p_elements = root.findall(".//text:p", ns) print(f"Total Paragraph Elements (): {len(p_elements)}") assert len(p_elements) >= 150, f"Too few paragraph elements: {len(p_elements)}" # Check tables t_elements = root.findall(".//table:table", ns) print(f"Total Table Elements (): {len(t_elements)}") assert len(t_elements) == 11, f"Expected 11 tables, got {len(t_elements)}" # Check images / graphics frames f_elements = root.findall(".//draw:frame", ns) print(f"Total Graphic Frame Elements (): {len(f_elements)}") assert len(f_elements) == 22, f"Expected 22 image frames, got {len(f_elements)}" # Check binary data in images bin_elements = root.findall(".//draw:image/office:binary-data", ns) print(f"Total Embedded Binary Data Elements (): {len(bin_elements)}") assert len(bin_elements) == 22, f"Expected 22 binary image blocks, got {len(bin_elements)}" print(">>> FODT AUDIT PASSED 100% <<<\n") def verify_pdf(): print("--- 2. AUDITING PDF (Publication-Grade PDF) ---") assert os.path.exists(PDF_PATH), f"PDF file missing: {PDF_PATH}" size = os.path.getsize(PDF_PATH) print(f"PDF File Size: {size:,} bytes") assert size > 5_000_000, f"PDF file suspiciously small: {size} bytes" # Render pages with pdftoppm prefix = os.path.join(AUDIT_DIR, "page") cmd = ["pdftoppm", "-png", "-r", "150", PDF_PATH, prefix] print(f"Running command: {' '.join(cmd)}") subprocess.run(cmd, check=True) rendered_pages = sorted([os.path.join(AUDIT_DIR, f) for f in os.listdir(AUDIT_DIR) if f.startswith("page-") and f.endswith(".png")]) total_pages = len(rendered_pages) print(f"Total Rendered PDF Pages: {total_pages}") assert total_pages >= 15, f"Expected at least 15 pages for comprehensive 14-chapter guide, got {total_pages}" for i, p_path in enumerate(rendered_pages): with Image.open(p_path) as img: w, h = img.size print(f" Page {i+1:02d}: {os.path.basename(p_path)} | Dimensions: {w}x{h} px | Size: {os.path.getsize(p_path):,} bytes") print(f">>> PDF AUDIT PASSED 100% ({total_pages} pages verified) <<<\n") if __name__ == "__main__": verify_fodt() verify_pdf()