# -*- coding: utf-8 -*- """ 并行复制待补分类的 STEP 数模(X盘网络盘慢,串行不可行)。 复用 gen-pending-series.py 的扫描缓存 + 解析器。 用法: PYTHONUTF8=1 python copy-pending-step.py """ import os, sys, shutil from concurrent.futures import ThreadPoolExecutor, as_completed import importlib.util HERE = os.path.dirname(os.path.abspath(__file__)) spec = importlib.util.spec_from_file_location('gps', os.path.join(HERE, 'gen-pending-series.py')) gps = importlib.util.module_from_spec(spec) spec.loader.exec_module(gps) DST = os.path.join(gps.DST, 'step') os.makedirs(DST, exist_ok=True) scanned = gps.load_scan() todo = [] for sp in gps.SPECS: records, _ = gps.collect(sp, scanned) for m in records.values(): dst = os.path.join(DST, m['model'] + '.step') if not os.path.exists(dst): todo.append((m['src'], dst, m['model'])) print(f'待复制 {len(todo)} 个(已存在则跳过)') def cp(item): src, dst, model = item for attempt in range(3): try: shutil.copy2(src, dst) return (model, 'ok', None) except Exception as e: if attempt == 2: return (model, 'err', str(e)) return (model, 'err', 'unknown') ok = err = 0 errors = [] with ThreadPoolExecutor(max_workers=8) as ex: futs = [ex.submit(cp, it) for it in todo] for i, fut in enumerate(as_completed(futs), 1): model, status, e = fut.result() if status == 'ok': ok += 1 else: err += 1 errors.append(f'{model}: {e}') if i % 100 == 0: print(f' {i}/{len(todo)} (ok={ok} err={err})') print(f'\n完成: 复制 {ok} 个, 失败 {err} 个') for e in errors[:20]: print(' !', e) print(f'step 目录现有 {len(os.listdir(DST))} 个文件')