|
| 1 | +"""Appendix adapter — crawled URL sample and data-source glossary.""" |
| 2 | +from __future__ import annotations |
| 3 | + |
| 4 | +from typing import Any |
| 5 | + |
| 6 | +from ....tools.export_audit_data import _GLOSSARY_ROWS |
| 7 | +from ..document import ( |
| 8 | + KeyValueBlock, |
| 9 | + PdfSection, |
| 10 | + PdfTruncation, |
| 11 | + SpacerBlock, |
| 12 | + UrlListBlock, |
| 13 | +) |
| 14 | +from ..options import PdfBuildOptions |
| 15 | +from . import register |
| 16 | + |
| 17 | + |
| 18 | +@register("appendix") |
| 19 | +def adapt_appendix(payload: dict[str, Any], opts: PdfBuildOptions) -> list[PdfSection]: |
| 20 | + if not opts.include_appendix: |
| 21 | + return [] |
| 22 | + |
| 23 | + sections: list[PdfSection] = [] |
| 24 | + |
| 25 | + # --- Crawled URLs sample --- |
| 26 | + links = [l for l in (payload.get("links") or []) if isinstance(l, dict)] |
| 27 | + if links: |
| 28 | + limit = opts.limits.urls_sample |
| 29 | + sample = links[:limit] |
| 30 | + rows = [ |
| 31 | + { |
| 32 | + "url": str(lnk.get("url") or ""), |
| 33 | + "status": str(lnk.get("status") or ""), |
| 34 | + "title": str(lnk.get("title") or "").strip(), |
| 35 | + } |
| 36 | + for lnk in sample |
| 37 | + ] |
| 38 | + has_titles = any(r["title"] for r in rows) |
| 39 | + trunc = PdfTruncation(shown=len(rows), total=len(links)) if len(links) > limit else None |
| 40 | + sections.append(PdfSection( |
| 41 | + id="appendix.urls", |
| 42 | + section_key="links", |
| 43 | + title="Crawled URLs (sample)", |
| 44 | + priority=80, |
| 45 | + page_break_before=False, |
| 46 | + blocks=[ |
| 47 | + UrlListBlock( |
| 48 | + id="appendix.url_list", |
| 49 | + rows=rows, |
| 50 | + show_title=has_titles, |
| 51 | + truncation=trunc, |
| 52 | + ), |
| 53 | + SpacerBlock(id="appendix.url_spacer", height_pt=6), |
| 54 | + ], |
| 55 | + )) |
| 56 | + |
| 57 | + # --- Glossary --- |
| 58 | + if opts.include_glossary: |
| 59 | + gloss_rows = [(term, desc) for term, desc in _GLOSSARY_ROWS] |
| 60 | + sections.append(PdfSection( |
| 61 | + id="appendix.glossary", |
| 62 | + section_key="core", |
| 63 | + title="Data source glossary", |
| 64 | + priority=90, |
| 65 | + blocks=[KeyValueBlock(id="appendix.glossary_kv", rows=gloss_rows, layout="glossary")], |
| 66 | + )) |
| 67 | + |
| 68 | + return sections |
0 commit comments