"""Read sample folders, preserving conversion inventory and workbook conventions.""" import sys,json,re from pathlib import Path from concurrent.futures import ThreadPoolExecutor,as_completed from openpyxl import load_workbook ROOT=Path(__file__).resolve().parents[3] sys.path.insert(0,str(Path(__file__).resolve().parents[1]/'src')) from bridge_drawing_extractor.core import convert,write_json from bridge_drawing_extractor.semantic import classify OUT=ROOT/'outputs/sample_batch_20261029';OUT.mkdir(exist_ok=True) EXE=ROOT/'Code/giyang_extract/libredwg/dwgread.exe' folders=sorted([p for p in ROOT.glob('엔지니어(sample*') if p.is_dir()],key=lambda p:int(re.search(r'sample(\d+)',p.name)[1])) inventory=[];templates=[] for folder in folders: for f in sorted(folder.glob('*.xlsx')): w=load_workbook(f,data_only=False) templates.append(dict(path=str(f),sheets={s.title:[dict(cell=c.coordinate,value=c.value,comment=c.comment.text if c.comment else None) for row in s for c in row if c.value is not None or c.comment] for s in w})) write_json(OUT/'template_inventory.json',templates) jobs=[p for folder in folders for p in folder.rglob('*') if p.suffix.lower()=='.dwg'] def read(p): try: d=convert(p,OUT/'.cache',EXE) return dict(path=str(p),folder=p.parent.name,sha256=d['sha256'],roles=classify(d['texts']),count=len(d['texts'])) except Exception as e:return dict(path=str(p),folder=p.parent.name,error=str(e)) with ThreadPoolExecutor(max_workers=3) as pool: futures={pool.submit(read,p):p for p in jobs} for future in as_completed(futures): item=future.result();inventory.append(item) print(f'{len(inventory)}/{len(jobs)} {Path(item["path"]).name}: {item.get("roles",item.get("error"))}',flush=True) write_json(OUT/'inventory.json',inventory) print('DONE',len(inventory),flush=True)