From b9da2d88e21e5edda04e928352b45d203147be26 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Tue, 14 May 2019 21:29:04 +0200 Subject: ee.xsd: o Removing distributor info, wasn't useful. o Removing part type, using a fact instead. part-search-list: o Putting in some smart rules about values for parts. Might be too smart for its own good. o Removing duplication checking, that is up to the searcher to decide. --- src/ee/part/__init__.py | 25 +++++++++++------- src/ee/part/pn_part_search_list.py | 52 ++++++++++++++++++++++++++++---------- 2 files changed, 55 insertions(+), 22 deletions(-) (limited to 'src/ee/part') diff --git a/src/ee/part/__init__.py b/src/ee/part/__init__.py index 996eeff..43e4cfa 100644 --- a/src/ee/part/__init__.py +++ b/src/ee/part/__init__.py @@ -1,5 +1,5 @@ from pathlib import Path -from typing import List, MutableMapping, Optional, Iterator, Union +from typing import List, Optional, Iterator, Union from ee import EeException from ee.money import Money @@ -43,6 +43,12 @@ class PartNumber(Reference): def to_xml(self): return types.PartNumber(value=self.value) + def __eq__(self, other): + return self.value == other.value + + def __hash__(self): + return hash(self.value) + class SupplierPartNumber(Reference): def __init__(self, value: str): @@ -51,6 +57,12 @@ class SupplierPartNumber(Reference): def to_xml(self): return types.SupplierPartNumber(value=self.value) + def __eq__(self, other): + return self.value == other.value + + def __hash__(self): + return hash(self.value) + class ReferenceList(object): def __init__(self, part_uri): @@ -296,6 +308,9 @@ class Part(object): def find_fact(self, key: str) -> Optional[types.Fact]: return next((f for f in self.get_facts() if f.keyProp == key), None) + def remove_fact(self, key): + self.xml.factsProp.fact = [f for f in self.xml.factsProp.fact if f.keyProp != key] + class Facts(object): def __init__(self, part): @@ -331,7 +346,6 @@ class Assembly(object): class PartDb(object): def __init__(self): self.parts: List[Entry] = [] - self.pn_index: MutableMapping[str, Entry] = {} self.new_entries = 0 self._assembly: Optional[Assembly] = None @@ -342,9 +356,6 @@ class PartDb(object): 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 @@ -355,10 +366,6 @@ class PartDb(object): 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 - @property def has_assembly(self): return self._assembly is not None diff --git a/src/ee/part/pn_part_search_list.py b/src/ee/part/pn_part_search_list.py index 049d0b8..343048e 100644 --- a/src/ee/part/pn_part_search_list.py +++ b/src/ee/part/pn_part_search_list.py @@ -1,7 +1,7 @@ from pathlib import Path from ee.part import PartDb, load_db, save_db, Part, fact_keys -from ee.xml import types +from ee.xml import types, uris __all__ = ["pn_part_search_list"] @@ -10,35 +10,61 @@ ignored_part_classes = [ ] +def valid_pns(part: Part): + """Check if the part has any MPNs or SPNs""" + return len(part.get_mpns()) > 0 or len(part.get_spns()) > 0 + + +def get_value(part: Part): + """Check if the part has a value and it is not a resistor, capacitor or inductor. Their value is not useful for a + part number-based lookup""" + value = part.find_fact(uris.make_fact_key("value")) + + if value is None: + return + + typ = part.find_fact(uris.make_fact_key("type")) + if typ is None: + return + + # if type is Zener, it's value could be a voltage + + return value.valueProp if typ.valueProp not in (uris.RESISTOR, uris.CAPACITOR, uris.INDUCTOR) else None + + def pn_part_search_list(in_path: Path, out_path: Path, supplier: str): in_parts = load_db(in_path) out_parts = PartDb() - # print("loaded {} existing parts".format(in_parts.size())) - + count = 0 + skipped = list() for xml in in_parts.iterparts(): + count += 1 part = Part(xml) - pn_value = next((p.valueProp for p in part.get_mpns()), None) + + refs = [ref.referenceProp for ref in part.get_schematic_references()] part_class = part.find_fact(fact_keys.part_class) if part_class: if part_class.valueProp in ignored_part_classes: + skipped.append(refs) continue - if pn_value is None: - refs = [ref.referenceProp for ref in part.get_schematic_references()] - print("Skipping part with no part number: schematic reference: {}".format(", ".join(refs))) - continue - - entry = out_parts.find_by_pn(pn_value) + if not valid_pns(part): + value = get_value(part) + if not value: + skipped.append(refs) + continue - if entry is not None: - continue + # Use the value of the component as a part number to search for + xml.referencesProp.part_number.append(types.PartNumber(value=value)) new_part = types.Part() new_part.referencesProp = xml.referencesProp out_parts.add_entry(new_part, True) - # print("Saving {} work parts".format(out_parts.size())) + if len(skipped) > 0: + print("Skipped {} of {} parts".format(len(skipped), count)) + save_db(out_path, out_parts) -- cgit v1.2.3