from pathlib import Path from typing import List, MutableMapping, Optional, Iterator from ee.xml import types, bom_file_utils __all__ = [ "PartDb", "load_db", "save_db", ] class Entry(object): def __init__(self, new: bool, part: types.Part): self.new = new self.part = part self.pn = next((p.valueProp for p in bom_file_utils.part_numbers(part)), None) def dpn(self, uri: str): return [spn for spn in bom_file_utils.supplier_part_numbers(self.part) if spn.supplierProp == uri] class PartDb(object): def __init__(self): self.parts: List[Entry] = [] self.pn_index: MutableMapping[str, Entry] = {} self.new_entries = 0 def add_entry(self, part: types.Part, new: bool): e = Entry(new, part) self.parts.append(e) if e.pn: self.pn_index[e.pn] = e if e.new: self.new_entries = self.new_entries + 1 def iterparts(self, sort=False) -> Iterator[types.Part]: it = (e.part for e in self.parts) return sorted(it, key=lambda p: p.uriProp) if sort else it def size(self) -> int: return len(self.parts) def find_by_pn(self, pn: str) -> Optional[types.Part]: entry = self.pn_index.get(pn, None) return entry.part if entry else None def load_db(path: Path) -> PartDb: db = PartDb() with path.open("r") as f: part_db: types.PartDb = types.parse(f, silence=True) part_db.partsProp = part_db.partsProp or types.PartList() for p in part_db.partsProp.part: db.add_entry(p, False) return db def save_db(path: Path, db: PartDb, sort=False): part_db = types.PartDb() parts = part_db.parts = types.PartList() parts.partProp.extend(db.iterparts(sort=sort)) with path.open("w") as f: part_db.export(outfile=f, level=0, name_=bom_file_utils.find_root_tag(part_db))