Files
reTraining/verify_publication_docs.py
T

101 lines
4.1 KiB
Python

#!/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 (<text:h>): {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 (<text:p>): {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 (<table:table>): {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 (<draw:frame>): {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 (<office:binary-data>): {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()