42 lines
2.8 KiB
Python
42 lines
2.8 KiB
Python
"""Verify A4 page count, CJK text, embedded glyphs, bookmarks and source evidence."""
|
|
import hashlib
|
|
import json
|
|
import unicodedata
|
|
from pathlib import Path
|
|
from pypdf import PdfReader
|
|
|
|
ROOT=Path(__file__).resolve().parents[1]
|
|
OUT=ROOT/'docs/teaching/rtcp-beginners'
|
|
pdf=OUT/'五轴RTCP与工件坐标-初学者完整讲义.pdf'
|
|
r=PdfReader(pdf)
|
|
outline=json.loads((OUT/'outline.json').read_text())
|
|
layout=json.loads((OUT/'verification/layout.json').read_text())
|
|
numeric=json.loads((OUT/'gcode-evidence.json').read_text())
|
|
assert len(r.pages)==len(outline)==72
|
|
assert numeric['status']=='verified' and numeric['executed_program']['status']=='completed'
|
|
assert not layout['errors'] and all(not p['violations'] and not p['overflow'] for p in layout['pages'])
|
|
pages=[];fonts={}
|
|
normalize=lambda s:''.join(unicodedata.normalize('NFKC',s).split())
|
|
for i,page in enumerate(r.pages):
|
|
text=page.extract_text();assert len(text)>120,(i,len(text))
|
|
assert normalize(outline[i]['title']) in normalize(text),(i,outline[i]['title'])
|
|
assert abs(float(page.mediabox.width)-595.28)<1 and abs(float(page.mediabox.height)-841.89)<1
|
|
assert '\ufffd' not in text
|
|
for entry in page['/Resources'].get('/Font',{}).values():
|
|
font=entry.get_object()
|
|
for item in font.get('/DescendantFonts',[font]):
|
|
value=item.get_object();desc=value.get('/FontDescriptor')
|
|
if desc:
|
|
desc=desc.get_object();name=str(desc.get('/FontName'))
|
|
embedded=bool(value.get('/Subtype')=='/Type3' and value.get('/CharProcs')) or any(k in desc for k in ['/FontFile','/FontFile2','/FontFile3'])
|
|
fonts[name]=embedded
|
|
pages.append({'page':i+1,'characters':len(text),'title':outline[i]['title']})
|
|
assert fonts and all(fonts.values()) and any('CJK' in k for k in fonts)
|
|
def count_bookmarks(items):
|
|
return sum(count_bookmarks(item) if isinstance(item,list) else 1 for item in items)
|
|
bookmarks=count_bookmarks(r.outline)
|
|
assert bookmarks>=72
|
|
report={'report_id':'rtcp-beginners-pdf-v1','status':'verified','page_count':len(r.pages),'pdf':pdf.name,'bytes':pdf.stat().st_size,'sha256':hashlib.sha256(pdf.read_bytes()).hexdigest(),'pages':pages,'embedded_fonts':fonts,'bookmarks':bookmarks,'numeric_report':numeric['report_id'],'executed_program_status':numeric['executed_program']['status'],'wasm_sha256':numeric['wasm_sha256'],'evidence':[{'path':str(p.relative_to(OUT)),'sha256':hashlib.sha256(p.read_bytes()).hexdigest()} for p in [OUT/'handbook.html',OUT/'outline.json',OUT/'gcode-evidence.json',OUT/'verification/layout.json',*sorted((OUT/'assets').iterdir()),*sorted((OUT/'verification').glob('pdf-contact-*.png'))]]}
|
|
(OUT/'verification/acceptance.json').write_text(json.dumps(report,ensure_ascii=False,indent=2)+'\n')
|
|
print(json.dumps({k:report[k] for k in ['report_id','status','page_count','bytes','bookmarks']},ensure_ascii=False))
|