import logging from pathlib import Path from typing import Mapping, Union from configclass import Config from namedlist import namedlist from ee.ds import DataSetManager, DataSet logger = logging.getLogger(__name__) _dsm = None # type: DataSetManager _data_sets = {} def change_data_sets_for_task(task, _callable): _data_sets[task][1] = _callable(_data_sets[task][1]) def output_data_set_for_task(task): return _data_sets[task][0] def input_data_sets_for_task(task): return _data_sets[task][1] _config_template = Config({ }) _config = None # type: Mapping[str, str] def init(data_set_manager: DataSetManager, **kwargs): global _config _config = _config_template.make(kwargs) global _dsm _dsm = data_set_manager class BomComponent(object): def __init__(self, ref, mpn): self.ref = ref self.mpn = mpn def to_object(self, ds): return ds.create_object("bom-component", self.ref). \ set("ref", self.ref). \ set("mpn", self.mpn) def task_bom(): """ Takes all schematic components, filters out all virtual/non- physical components (like power flags and ground components) and creates 'bom-component' objects. """ out_data_set = _data_sets[task_bom][0] in_data_sets = _data_sets[task_bom][1] def action(): in_ds = _dsm.load_data_sets(in_data_sets) with _dsm.create_rw(out_data_set, clean=True) as output: components = [o for o in in_ds.items() if o.object_type.name == "component"] bom_components = {} for c in components: ref = c.get("ref") mpn = c.get("mpn") if not ref: raise Exception("Missing ref") if not mpn: output.create_object("message", "bom-{}".format(ref)). \ set("level", "error"). \ set("message", "Missing required field 'mpn'") continue if ref in bom_components: raise Exception("Duplicate ref '{}'".format("ref")) bom_components[ref] = BomComponent(ref, mpn) [c.to_object(output) for c in bom_components.values()] return { "file_dep": [_dsm.cookie_for_ds(ds) for ds in in_data_sets], "actions": [action], "targets": [_dsm.cookie_for_ds(out_data_set)], } _data_sets[task_bom] = ["bom", ["components"]] def order_csv(count: int, group_by_mpn: bool, output_file: Path, data_sets): ds = _dsm.load_data_sets(data_sets) out = DataSet() if group_by_mpn: parts = {} Part = namedlist("Part", "mpn, cnt, refs") for c in [o for o in ds.items() if o.object_type.name == "bom-component"]: ref = c.get("ref") mpn = c.get("mpn") if mpn in parts: parts[mpn].cnt += 1 parts[mpn].refs.append(ref) else: parts[mpn] = Part(mpn=mpn, cnt=1, refs=[ref]) for part in sorted(parts.values(), key=lambda p: p.mpn): out.create_object("row", part.mpn). \ set("MPN", part.mpn). \ set("Count", part.cnt * count). \ set("References", ",".join(part.refs)) _dsm.store_csv(output_file, out, "row", order_by="MPN") else: raise Exception("Not implemented") def create_task_order_csv(output_file: Union[str, Path], data_sets, count: int = 1): return { "name": "order-{}".format(count), "actions": [(order_csv, [count, True, Path(output_file), data_sets])], "file_dep": [_dsm.cookie_for_ds(ds) for ds in data_sets], "targets": [output_file], }