From 97c8bb9db96e27051f8746865f657408263db0b8 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Tue, 26 Feb 2019 23:08:19 +0100 Subject: o Creating a PartDb that manages a file system directory with one xml file per part. o Switching xml-based code to use PartDb. --- src/ee/digikey/search_parts.py | 94 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 src/ee/digikey/search_parts.py (limited to 'src/ee/digikey/search_parts.py') diff --git a/src/ee/digikey/search_parts.py b/src/ee/digikey/search_parts.py new file mode 100644 index 0000000..62bb4ee --- /dev/null +++ b/src/ee/digikey/search_parts.py @@ -0,0 +1,94 @@ +from pathlib import Path +from typing import List + +from ee.digikey import Digikey, DigikeyParser, DigikeyClient, SearchResponseTypes, DigikeyProduct +from ee.part import PartDb, load_db, save_db +from ee.xml import bomFile, bom_file_utils +from ee.xml.bomFile import DigikeyDistributorInfo +from ee.xml.uris import DIGIKEY_URI + +__all__ = ["search_parts"] + + +def resolved(di: DigikeyDistributorInfo, part: bomFile.Part, p: DigikeyProduct): + di.stateProp = "resolved" + + fact_set = bom_file_utils.find_fact_set(part, DIGIKEY_URI, create=True) + + # Remove the old list + fact_set.factsProp = bomFile.FactList() + facts: List[bomFile.Fact] = fact_set.factsProp.factProp + + for a in p.attributes: + facts.append(bomFile.Fact(key=a.attribute_type.id, label=a.attribute_type.label, value=a.value)) + + +def search_parts(in_dir: Path, out_dir: Path, cache_dir: Path, force_refresh: bool): + print("in: {}, out: {}".format(in_dir, out_dir)) + + in_db = load_db(in_dir) + out_parts = PartDb() + + parser = DigikeyParser(Digikey()) + client = DigikeyClient(cache_dir) + + for part in in_db.iterparts(): + dpn = bom_file_utils.find_dpn(part, DIGIKEY_URI) + mpn = bom_file_utils.find_pn(part) + + is_mpn = query = None + + if dpn is not None: + query = dpn + is_mpn = False + elif mpn is not None: + query = mpn + is_mpn = True + + if query is None: + print("could not find pn or dpn: part.id={}".format(part.idProp)) + continue + + di = part.distributor_infoProp # type: DigikeyDistributorInfo + + if di is None: + di = bomFile.DigikeyDistributorInfo() + di.extensiontype_ = "DigikeyDistributorInfo" + di.original_tagname_ = "distributor-info" + part.distributor_infoProp = di + + if force_refresh or di.stateProp != "resolved": + text = client.search(query) + response = parser.parse_string(text) + + if response.response_type == SearchResponseTypes.SINGLE: + resolved(di, part, response.products[0]) + elif response.response_type == SearchResponseTypes.MANY: + + # find those with an exact match. Digikey uses a prefix search so a query for "FOO" will return "FOO" + # and "FOOT". + def get_field(p): + return p.mpn if is_mpn else p.part_number + + filtered_products = [p for p in response.products if get_field(p) == query] + + if len(filtered_products) == 0: + di.stateProp = "not-found" + else: + dpn = sorted(filtered_products, key=lambda p: p.part_number)[0].part_number + + response = parser.parse_string(client.search(dpn)) + if response.response_type == SearchResponseTypes.SINGLE: + resolved(di, part, response.products[0]) + else: + di.stateProp = "many" + + elif response.response_type == SearchResponseTypes.TOO_MANY: + di.stateProp = "too-many" + elif response.response_type == SearchResponseTypes.NO_MATCHES: + di.stateProp = "not-found" + + out_parts.add_entry(part, True) + + print("Saving {} work parts".format(out_parts.size())) + save_db(out_dir, out_parts) -- cgit v1.2.3