From 89197dad4f5f427faa7fba12971b20037ad5ba71 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Fri, 14 Jun 2019 10:40:31 +0200 Subject: split-parts-by-supplier: rename to split-bom-by-supplier. digikey-create-bom: Implementing CSV generation for Digi-Key. --- src/ee/tools/digikey_create_bom.py | 33 +++++++++++++ src/ee/tools/ninja.py | 9 ++++ src/ee/tools/split_bom_by_supplier.py | 86 +++++++++++++++++++++++++++++++++ src/ee/tools/split_parts_by_supplier.py | 72 --------------------------- src/ee/tools/templates/build.ninja.j2 | 24 +++++---- 5 files changed, 143 insertions(+), 81 deletions(-) create mode 100644 src/ee/tools/digikey_create_bom.py create mode 100644 src/ee/tools/split_bom_by_supplier.py delete mode 100644 src/ee/tools/split_parts_by_supplier.py (limited to 'src/ee/tools') diff --git a/src/ee/tools/digikey_create_bom.py b/src/ee/tools/digikey_create_bom.py new file mode 100644 index 0000000..a83da83 --- /dev/null +++ b/src/ee/tools/digikey_create_bom.py @@ -0,0 +1,33 @@ +import argparse +from pathlib import Path + +import ee.tools +from ee.digikey.bom import create_bom + +parser = argparse.ArgumentParser() +ee.tools.add_default_argparse_group(parser) + +parser.add_argument("--bom", + required=True, + metavar="PART DB") + +parser.add_argument("--out", + required=True, + metavar="CSV") + +parser.add_argument("--part-db", + nargs="*", + required=True, + metavar="PART DB") + +parser.add_argument("--store", + default="us", + metavar="STORE CODE") + +parser.add_argument("--allow-incomplete", + action="store_true") + +args = parser.parse_args() +ee.tools.process_default_argparse_group(args) + +create_bom(Path(args.bom), [Path(p) for p in args.part_db], Path(args.out), args.store, args.allow_incomplete) diff --git a/src/ee/tools/ninja.py b/src/ee/tools/ninja.py index aa6952b..7d73d8f 100644 --- a/src/ee/tools/ninja.py +++ b/src/ee/tools/ninja.py @@ -21,6 +21,15 @@ class NinjaSupplier(object): def part_db(self): return "$public_dir/{}/parts.xml".format(self.key) + @property + def bom_input(self): + return "$public_dir/{}/bom.xml".format(self.key) + + @property + def bom_output(self): + # This needs to be configurable per supplier + return "$public_dir/{}/bom.csv".format(self.key) + def ninja_path_filter(s: Union[Path, str, List[str]]) -> str: if isinstance(s, Path): diff --git a/src/ee/tools/split_bom_by_supplier.py b/src/ee/tools/split_bom_by_supplier.py new file mode 100644 index 0000000..01a6ef3 --- /dev/null +++ b/src/ee/tools/split_bom_by_supplier.py @@ -0,0 +1,86 @@ +import argparse +from pathlib import Path +from typing import List, Tuple + +import ee.tools +from ee.db import ObjDb +from ee.logging import log +from ee.part import Part, load_db, save_db, PartDb +from ee.part.bom import load_bom, check_bom + + +class OrderPart(object): + def __init__(self, order_part: Part, part: Part): + self.order_part = order_part + self.part = part + + +def split_bom_by_supplier(bom_path: Path, part_files: List[Path], supplier_list: List[Tuple[str, str, Path]]): + # key, url, file + + bom_parts, supplier_parts = load_bom(bom_path, part_files) + check_bom(bom_parts, supplier_parts) + + uri_idx = supplier_parts.index("uri") + + for supplier, uri, path in supplier_list: + print(supplier, uri, path) + + supplier_info = {uri: path for _, uri, path in supplier_list} + part_dbs = {uri: PartDb() for _, uri, _ in supplier_list} + + for bom_part in bom_parts.values: + sch = bom_part.get_exactly_one_schematic_reference().referenceProp + part_reference = bom_part.get_only_part_reference() + + if not part_reference: + # log.warn("Missing part for {}, allowing for now".format(sch)) + continue + + # print("{}: {}".format(sch, part_reference.part_uriProp)) + part = uri_idx.get_single(part_reference.part_uriProp) + print("{}: {}".format(sch, part.uri)) + print("{}: {}".format(sch, part.supplier)) + + part_dbs[part.supplier].add_entry(bom_part, new=False) + + for uri, path in supplier_info.items(): + part_db = part_dbs[uri] + save_db(path, part_db) + + +parser = argparse.ArgumentParser() +ee.tools.add_default_argparse_group(parser) + +parser.add_argument("--bom", + required=True, + metavar="PART DB") + +parser.add_argument("--part-db", + nargs="*", + required=True, + metavar="PART DB") + +parser.add_argument("--supplier", + required=True, + nargs="*", + metavar="SUPPLIER") + +parser.add_argument("--order", + required=True, + nargs="*", + metavar="PART DB") + +args = parser.parse_args() +ee.tools.process_default_argparse_group(args) + +ss = [] + +order_files = {o.split("=", maxsplit=1)[0]: o.split("=", maxsplit=1)[1] for o in args.order} + +for s in args.supplier: + key, url = s.split("=", maxsplit=1) + file = order_files[key] + ss.append((key, url, Path(file))) + +split_bom_by_supplier(Path(args.bom), [Path(path) for path in args.part_db], ss) diff --git a/src/ee/tools/split_parts_by_supplier.py b/src/ee/tools/split_parts_by_supplier.py deleted file mode 100644 index 9202f0d..0000000 --- a/src/ee/tools/split_parts_by_supplier.py +++ /dev/null @@ -1,72 +0,0 @@ -import argparse -from pathlib import Path -from typing import List - -import ee.tools -from ee.db import ObjDb -from ee.part import Part, load_db, save_db, PartDb -from ee.project import Project - - -class OrderPart(object): - def __init__(self, order_part: Part, part: Part): - self.order_part = order_part - self.part = part - - -def uri_fn(part: Part): - return part.uri - - -def split_parts_by_supplier(project: Project, order_file: Path, part_dbs: List[Path], out_dir: Path): - parts: ObjDb[Part] = ObjDb[Part]() - part_by_uri = parts.add_unique_index("uri", uri_fn) - - for part_db in part_dbs: - for xml in load_db(part_db).iterparts(): - parts.add(Part(xml)) - - order_parts: ObjDb[OrderPart] = ObjDb() - supplier_idx = order_parts.add_index("supplier", lambda op: op.part.supplier) - for xml in load_db(order_file).iterparts(): - order_part = Part(xml) - part = part_by_uri.get_single(order_part.get_exactly_one_part_reference().part_uriProp) - order_parts.add(OrderPart(order_part, part)) - - for supplier, parts_for_supplier in supplier_idx.items(): - desc = project.get_supplier_by_uri(supplier) - - print("{}: {}".format(desc.name, len(parts))) - # supplier_db: ObjDb[Part] = ObjDb[Part]() - # supplier_db.add_unique_index("uri", uri_fn) - - supplier_descriptor = project.get_supplier_by_uri(supplier) - - db = PartDb() - for part_for_supplier in parts_for_supplier: - db.add_entry(part_for_supplier.part.underlying, False) - - save_db(out_dir / "{}.xml".format(supplier_descriptor.key), db, sort=True) - - -parser = argparse.ArgumentParser() -ee.tools.add_default_argparse_group(parser) - -parser.add_argument("--parts", - required=True, - metavar="PART DB") - -parser.add_argument("--part-db", - nargs="*", - required=True, - metavar="PART DB") - -parser.add_argument("--out-dir", - metavar="DIR FOR PART DBS") - -args = parser.parse_args() -ee.tools.process_default_argparse_group(args) - -part_db_dirs = [Path(part_db) for part_db in args.part_db] - -split_parts_by_supplier(Project.load(), Path(args.parts), part_db_dirs, Path(args.out_dir)) diff --git a/src/ee/tools/templates/build.ninja.j2 b/src/ee/tools/templates/build.ninja.j2 index 9fff519..1ab6102 100644 --- a/src/ee/tools/templates/build.ninja.j2 +++ b/src/ee/tools/templates/build.ninja.j2 @@ -56,8 +56,8 @@ rule element14-search-parts rule create-bom command = $ee create-bom {{ log }} --schematic $schematic --part-db $part_dbs --out $out $strategy -rule split-parts-by-supplier - command = $ee split-parts-by-supplier {{ log }} --parts $in --out $out $part_dbs +rule split-bom-by-supplier + command = $ee split-bom-by-supplier {{ log }} --bom $in $part_dbs $suppliers $orders rule import-parts-yaml description = import-parts-yaml $in @@ -151,6 +151,12 @@ build $public_dir/{{ s.key }}/souffle/out/fact.csv: souffle {{ alt if is_file(al build {{ s.part_db }}: part-apply-souffle-post $public_dir/{{ s.key }}/souffle/out/fact.csv in_sch = $public_dir/{{ s.key }}/downloaded.xml work = $public_dir/{{ s.key }}/souffle + +rule {{ s.key }}-create-bom + command = $ee {{ s.key }}-create-bom {{ log }} --bom $in --out $out $part_dbs --allow-incomplete + +build {{ s.bom_output }}: {{ s.key }}-create-bom {{ s.bom_input }} + part_dbs = --part-db {{ s.part_db }} {%- endfor %} {%- for f in parts_yaml_files %} @@ -167,11 +173,10 @@ build $public_dir/bom.xml | $report_dir/bom.rst: create-bom $public_dir/sch.xml {%- endif %} {%- set reports=reports+["$report_dir/bom.rst"] %} -{# -build $public_dir/orders/index.xml: split-parts-by-supplier $public_dir/bom.xml | {%- for s in suppliers %} {{ s.part_db }}{% endfor %} - part_dbs ={%- for s in suppliers %} {{ s.part_db }}{% endfor %} - suppliers = {% s for s in suppliers %} -#} +build {%- for s in suppliers %} {{ s.bom_input }}{% endfor %}: split-bom-by-supplier $public_dir/bom.xml | {%- for s in suppliers %} {{ s.part_db }}{% endfor %} + part_dbs = {%- for s in suppliers %} --part-db {{ s.part_db }}{% endfor %} + suppliers = {%- for s in suppliers %} --supplier {{ s.key }}={{ s.supplier.uri }}{% endfor %} + orders = {%- for s in suppliers %} --order {{ s.key }}={{ s.bom_input }}{% endfor %} rule seeed-download-opl description = seeed-download-opl $opl @@ -190,5 +195,6 @@ build $public_dir/seeed/opl/{{ opl }}.xml: seeed-download-opl # Reports build ee-reports: phony {{ " ".join(reports) }} -build part-dbs: phony {%- for s in suppliers %} {{ s.part_db }}{% endfor %} -build ee-all: phony ee-reports part-dbs +build ee-part-dbs: phony {%- for s in suppliers %} {{ s.part_db }}{% endfor %} +build ee-orders: phony {%- for s in suppliers %} {{ s.bom_output }}{% endfor %} +build ee-all: phony ee-reports ee-orders -- cgit v1.2.3