#!/usr/bin/env python3 from __future__ import annotations import csv, json, re, subprocess from collections import Counter from pathlib import Path ROOT=Path('/root/work/pharmit-ghidra') CAND=ROOT/'out/a4_receipt_template_candidates' OUT=CAND/'quickreport_receipt_deep' OUT.mkdir(parents=True, exist_ok=True) PARSER=ROOT/'scripts/parse_fastreport_bin.py' QR_CLASSES={'TQuickRep','TQRBand','TQRChildBand','TQRLabel','TQRDBText','TQRShape','TQRImage','TQRDBImage','TQRRichText','TQRExpr','TQRCompositeReport'} KEYWORDS=['약제비 계산서','약제비','영수증','진료비','납입확인서','납입 확인서','소득공제','요양기관 종류','환 자','환자성명','약 제 비 총 액','총 수 납 금 액'] def text(o): pr=o.get('props',{}) for k in ['Caption','Text','DataField','FieldName','Memo.UTF8W']: v=pr.get(k) if isinstance(v,str) and v.strip(): return v.strip() if isinstance(v,list): s='\n'.join(str(x) for x in v if str(x).strip()).strip() if s: return s return '' def parse_file(p:Path): jpath=OUT/(p.name+'.objects.json') if not jpath.exists(): subprocess.run(['python3',str(PARSER),str(p)], stdout=jpath.open('w'), stderr=subprocess.DEVNULL, check=False) try: return json.loads(jpath.read_text(encoding='utf-8')) except Exception: return {'objects':[]} def bounds(objs): xs=[]; ys=[] for o in objs: pr=o.get('props',{}) try: if 'Left' in pr and 'Width' in pr: xs += [float(pr['Left']), float(pr['Left'])+float(pr['Width'])] if 'Top' in pr and 'Height' in pr: ys += [float(pr['Top']), float(pr['Top'])+float(pr['Height'])] except Exception: pass return ([round(min(xs),3),round(max(xs),3)] if xs else None, [round(min(ys),3),round(max(ys),3)] if ys else None) def group_reports(objs): q=[o for o in objs if o.get('class') in QR_CLASSES] starts=[i for i,o in enumerate(q) if o.get('class') in {'TQuickRep','TQRCompositeReport'}] if not starts: return [('qr_blob', q)] if q else [] groups=[] for n,si in enumerate(starts): ei=starts[n+1] if n+1