diff options
author | Trygve Laugstøl <trygvis@inamo.no> | 2019-03-15 14:55:15 +0100 |
---|---|---|
committer | Trygve Laugstøl <trygvis@inamo.no> | 2019-03-15 14:55:15 +0100 |
commit | 237a6faa8a23826e68bbc00bc107b2d6f97235d0 (patch) | |
tree | fe1a6a6b1a4ed991a6eacd9ec6960325db3f9e4f | |
parent | 3523190bb7ca1c38caea3a1aae51062d22e56b09 (diff) | |
download | ee-python-237a6faa8a23826e68bbc00bc107b2d6f97235d0.tar.gz ee-python-237a6faa8a23826e68bbc00bc107b2d6f97235d0.tar.bz2 ee-python-237a6faa8a23826e68bbc00bc107b2d6f97235d0.tar.xz ee-python-237a6faa8a23826e68bbc00bc107b2d6f97235d0.zip |
Refactoring:
o Renaming part.id to part.uri. Changing to URIs and use that as an
identifier if the part is known. Schematic part does not have an URI.
o Merging <schema-reference> and <part-numbers> into <references>
o Creating <part-uri> as a possible <reference>. Used by order to point
to other parts.
-rw-r--r-- | src/ee/digikey/normalize_facts.py | 2 | ||||
-rw-r--r-- | src/ee/digikey/search_parts.py | 29 | ||||
-rw-r--r-- | src/ee/element14/search_parts.py | 8 | ||||
-rw-r--r-- | src/ee/kicad/make_bom.py | 25 | ||||
-rw-r--r-- | src/ee/order/__init__.py | 81 | ||||
-rw-r--r-- | src/ee/part/__init__.py | 24 | ||||
-rw-r--r-- | src/ee/part/create_distributor_search_list.py | 10 | ||||
-rw-r--r-- | src/ee/tools/create_order.py | 5 | ||||
-rw-r--r-- | src/ee/xml/bom_file_utils.py | 29 | ||||
-rw-r--r-- | src/ee/xml/types.py | 448 | ||||
-rw-r--r-- | xsd/ee.xsd | 37 |
11 files changed, 510 insertions, 188 deletions
diff --git a/src/ee/digikey/normalize_facts.py b/src/ee/digikey/normalize_facts.py index 91ad4db..d7546c3 100644 --- a/src/ee/digikey/normalize_facts.py +++ b/src/ee/digikey/normalize_facts.py @@ -153,4 +153,4 @@ def normalize_facts(in_path: Path, out_path: Path): out_parts.add_entry(part, True) print("Saving {} work parts".format(out_parts.size())) - save_db(out_path, out_parts) + save_db(out_path, out_parts, sort=True) diff --git a/src/ee/digikey/search_parts.py b/src/ee/digikey/search_parts.py index 4f637c7..3d271d5 100644 --- a/src/ee/digikey/search_parts.py +++ b/src/ee/digikey/search_parts.py @@ -10,15 +10,17 @@ __all__ = ["search_parts"] def resolved(p: DigikeyProduct) -> types.Part: - part = types.Part(id=p.part_number, - distributor_info=types.DistributorInfo(), - facts=types.FactList(), - part_numbers=types.PartNumberList()) + # TODO: fix uri + part = types.Part(uri="https://digikey.com/pn#{}".format(p.part_number), + distributor_info=types.DistributorInfo(), + facts=types.FactList(), + references=types.ReferencesList()) part.distributor_infoProp.stateProp = "resolved" - part_numbers = part.part_numbersProp.part_numberProp + supplier_part_numbers = part.referencesProp.supplier_part_numberProp + supplier_part_numbers.append(types.SupplierPartNumber(value=p.part_number, supplier=DIGIKEY_URI)) - part_numbers.append(types.PartNumber(value=p.part_number, distributor=DIGIKEY_URI)) + part_numbers = part.referencesProp.part_numberProp if p.mpn: part_numbers.append(types.PartNumber(value=p.mpn)) facts: List[types.Fact] = part.factsProp.factProp @@ -46,8 +48,8 @@ def search_parts(in_path: Path, out_path: Path, cache_dir: Path): 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) + dpn = next((p.valueProp for p in bom_file_utils.supplier_part_numbers(part) if p.supplierProp == DIGIKEY_URI), None) + mpn = next((p.valueProp for p in bom_file_utils.part_numbers(part)), None) is_mpn = query = None @@ -59,13 +61,14 @@ def search_parts(in_path: Path, out_path: Path, cache_dir: Path): is_mpn = True if query is None: - print("could not find pn or dpn: part.id={}".format(part.idProp)) + # TODO: use schematic reference + print("could not find pn or dpn: part.uri={}".format(part.uriProp)) continue out_id = query - out_part = types.Part(id=out_id, - distributor_info=types.DistributorInfo(), - part_numbers=part.part_numbersProp) + out_part = types.Part(uri=out_id, + distributor_info=types.DistributorInfo(), + references=part.referencesProp) di = out_part.distributor_infoProp text = client.search(query) @@ -101,4 +104,4 @@ def search_parts(in_path: Path, out_path: Path, cache_dir: Path): out_parts.add_entry(out_part, True) print("Saving {} work parts".format(out_parts.size())) - save_db(out_path, out_parts) + save_db(out_path, out_parts, sort=True) diff --git a/src/ee/element14/search_parts.py b/src/ee/element14/search_parts.py index 55e8130..cfa1d34 100644 --- a/src/ee/element14/search_parts.py +++ b/src/ee/element14/search_parts.py @@ -14,9 +14,9 @@ def search_parts(in_path: Path, out_path: Path, cache_dir: Path, config: Element client = Element14Client(config, cache_dir) for part in in_db.iterparts(): - mpn = bom_file_utils.find_pn(part) + mpn = bom_file_utils.first_pn(part) - query = mpn # TODO: suppor dpn + query = mpn # TODO: support dpn out_id = query @@ -24,8 +24,8 @@ def search_parts(in_path: Path, out_path: Path, cache_dir: Path, config: Element out_part = types.Part(id=out_id, distributor_info=types.DistributorInfo(), - part_numbers=part.part_numbersProp) + references=part.referencesProp) di = out_part.distributor_infoProp print("Saving {} work parts".format(out_parts.size())) - save_db(out_path, out_parts) + save_db(out_path, out_parts, sort=True) diff --git a/src/ee/kicad/make_bom.py b/src/ee/kicad/make_bom.py index 7dd5532..0a8f4bb 100644 --- a/src/ee/kicad/make_bom.py +++ b/src/ee/kicad/make_bom.py @@ -62,7 +62,7 @@ def mpn_strategy(component: Component, part: types.Part) -> types.Part: mpn = component.get_field("mpn") if mpn is not None: pn = types.PartNumber(value=mpn.value) - part.part_numbersProp.add_part_number(pn) + part.referencesProp.add_part_number(pn) return part @@ -74,8 +74,8 @@ def dpn_strategy_factory(dpn_mappings: Mapping[str, str]) -> StrategyCallable: if s is None: continue - pn = types.PartNumber(value=s.value, distributor=distributor) - part.part_numbersProp.add_part_number(pn) + pn = types.SupplierPartNumber(value=s.value, supplier=distributor) + part.referencesProp.add_part_number(pn) return part @@ -111,17 +111,22 @@ def work(sch, out: Path, strategy: MakeBomStrategy, new_mode, pretty): parts = PartDb() components = to_bom(sch) for c in components: - part = types.Part(id=c.ref) - part.schema_reference = c.ref - part.part_numbersProp = types.PartNumberList() + part = types.Part() + part.referencesProp = types.ReferencesList() + part.referencesProp.schematic_reference.append(types.SchematicReference(reference=c.ref)) part = strategy.process_part(c, part) - if len(part.part_numbersProp.get_part_number()) == 0: - part.part_numbersProp = None + if part is None: + continue + + if len(part.referencesProp.schematic_reference) == 0 and \ + len(part.referencesProp.part_number) == 0 and \ + len(part.referencesProp.supplier_part_number) == 0: + # No need to dirty the xml with empty lists + part.referencesProp = None - if part is not None: - parts.add_entry(part, True) + parts.add_entry(part, True) save_db(out, parts) diff --git a/src/ee/order/__init__.py b/src/ee/order/__init__.py index 5350667..56d233f 100644 --- a/src/ee/order/__init__.py +++ b/src/ee/order/__init__.py @@ -2,6 +2,7 @@ from functools import total_ordering from pathlib import Path from typing import List, Tuple +from ee import EeException from ee.part import PartDb, load_db, save_db from ee.xml import types, bom_file_utils @@ -12,12 +13,17 @@ __all__ = ["create_order"] class PartInfo(object): def __init__(self, part: types.Part): self.part = part - self.id = part.id - self.pn = bom_file_utils.find_pn(part) + self.ref = next((ref.referenceProp for ref in bom_file_utils.schematic_references(part)), None) + self.pn = next((p.valueProp for p in bom_file_utils.part_numbers(part)), None) self.available_from: List[Tuple[str, types.Part]] = [] + rl = part.referencesProp = part.referencesProp or types.ReferencesList() # type: types.ReferencesList + rl.schematic_referenceProp = rl.schematic_referenceProp or [] + rl.part_numberProp = rl.part_numberProp or [] + rl.supplier_part_numberProp = rl.supplier_part_numberProp or [] + def __lt__(self, other: "PartInfo"): - return self.part.idProp == other.part.idProp + return self.ref == other.ref def create_order(schematic_path: Path, out_path: Path, part_db_dirs: List[Path], fail_on_missing_parts: bool): @@ -30,28 +36,41 @@ def create_order(schematic_path: Path, out_path: Path, part_db_dirs: List[Path], infos = [PartInfo(sch) for sch in sch_db.iterparts()] for info in infos: - print("Resolving {}".format(info.id)) - - for distributor, db in dbs: - for p in db.iterparts(sort=True): - if info.pn: - p_pn: str = bom_file_utils.find_pn(p) - - if info.pn == p_pn: - info.available_from.append((distributor, p)) - - for sch_pn_ in bom_file_utils.part_numbers(info.part): - sch_pn: types.PartNumber = sch_pn_ - - for p_pn_ in bom_file_utils.part_numbers(p): - p_pn: types.PartNumber = p_pn_ - - if sch_pn.distributorProp == p_pn.distributorProp and sch_pn.value == p_pn.value: - if p.idProp not in info.available_from: - info.available_from.append((distributor, p)) + print("Resolving {}".format(info.ref)) + + sch_part_numbers = info.part.referencesProp.part_number + sch_supplier_part_numbers: List[types.SupplierPartNumber] = info.part.referencesProp.supplier_part_number + + for supplier, db in dbs: + for supplier_part in db.iterparts(sort=True): + found = None + for sch_pn in sch_part_numbers: + for pn in bom_file_utils.part_numbers(supplier_part): + if sch_pn.valueProp == pn.valueProp: + found = supplier_part + break + if found: + break + + if found: + info.available_from.append((supplier, found)) + break + + found = None + for sch_spn in sch_supplier_part_numbers: + for spn in bom_file_utils.supplier_part_numbers(supplier_part): + if sch_spn.valueProp == spn.valueProp and sch_spn.supplierProp == spn.supplierProp: + found = supplier_part + break + if found: + break + + if found: + info.available_from.append((supplier, found)) + break for info in infos: - print("Resolved {} to {}".format(info.id, info.available_from)) + print("Resolved {} to {}".format(info.ref, info.available_from)) warnings = [] has_missing_parts = False @@ -59,28 +78,22 @@ def create_order(schematic_path: Path, out_path: Path, part_db_dirs: List[Path], if len(info.available_from) == 0: has_missing_parts = True warnings.append("Could not find {} in any database, part numbers: {}". - format(info.id, ", ".join([p.value for p in bom_file_utils.part_numbers(info.part)]))) + format(info.ref, ", ".join([p.value for p in bom_file_utils.part_numbers(info.part)]))) for w in sorted(warnings): print(w) if has_missing_parts and fail_on_missing_parts: - print("has missing parts") - return False + raise EeException("The order has parts that can't be found from any supplier") for info in infos: - part = types.Part(id=info.part.id, - schema_reference=info.part.schema_reference, - part_numbers=types.PartNumberList()) - - part_numbers = part.part_numbersProp.part_number - if len(info.available_from) == 0: continue - distributor, distributor_part = info.available_from[0] + supplier, supplier_part = info.available_from[0] - part_numbers.append(types.PartNumber(value=distributor_part.id, distributor=distributor)) + references = types.ReferencesList(schematic_reference=info.part.referencesProp.schematic_reference) + part = types.Part(uri=supplier_part.uri, references=references) out_parts.add_entry(part, True) diff --git a/src/ee/part/__init__.py b/src/ee/part/__init__.py index 45561ec..36a3d3c 100644 --- a/src/ee/part/__init__.py +++ b/src/ee/part/__init__.py @@ -1,9 +1,7 @@ from pathlib import Path from typing import List, MutableMapping, Optional, Iterator -from ee import EeException from ee.xml import types, bom_file_utils -from ee.xml.bom_file_utils import find_pn, find_dpn, find_root_tag __all__ = [ "PartDb", @@ -17,10 +15,10 @@ class Entry(object): self.new = new self.part = part - self.pn = find_pn(part) + self.pn = next((p.valueProp for p in bom_file_utils.part_numbers(part)), None) def dpn(self, uri: str): - return find_dpn(self.part, uri) + return [spn for spn in bom_file_utils.supplier_part_numbers(self.part) if spn.supplierProp == uri] class PartDb(object): @@ -42,7 +40,7 @@ class PartDb(object): def iterparts(self, sort=False) -> Iterator[types.Part]: it = (e.part for e in self.parts) - return sorted(it, key=lambda p: p.idProp) if sort else it + return sorted(it, key=lambda p: p.uriProp) if sort else it def size(self) -> int: return len(self.parts) @@ -51,16 +49,6 @@ class PartDb(object): entry = self.pn_index.get(pn, None) return entry.part if entry else None - def find_by_dpn(self, distributor: str, pn: str) -> types.Part: - idx = self.dpn_indexes.get(distributor) - - if idx is None: - tmp = [(find_dpn(entry.part, distributor), entry) for entry in self.parts] - idx = {dpn: entry for dpn, entry in tmp if dpn is not None} - self.dpn_indexes[distributor] = idx - - return idx[pn].part - def load_db(path: Path) -> PartDb: db = PartDb() @@ -76,10 +64,10 @@ def load_db(path: Path) -> PartDb: return db -def save_db(path: Path, db: PartDb): +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=True)) + parts.partProp.extend(db.iterparts(sort=sort)) with path.open("w") as f: - part_db.export(outfile=f, level=0, name_=find_root_tag(part_db)) + part_db.export(outfile=f, level=0, name_=bom_file_utils.find_root_tag(part_db)) diff --git a/src/ee/part/create_distributor_search_list.py b/src/ee/part/create_distributor_search_list.py index 88e5a10..10160d4 100644 --- a/src/ee/part/create_distributor_search_list.py +++ b/src/ee/part/create_distributor_search_list.py @@ -1,8 +1,7 @@ from pathlib import Path from ee.part import PartDb, load_db, save_db -from ee.xml import types -from ee.xml.bom_file_utils import * +from ee.xml import types, bom_file_utils __all__ = ["create_distributor_search_list"] @@ -14,10 +13,11 @@ def create_distributor_search_list(in_path: Path, out_path: Path): print("loaded {} existing parts".format(in_parts.size())) for part in in_parts.iterparts(): - pn_value = find_pn(part) + pn_value = next((p.valueProp for p in bom_file_utils.part_numbers(part)), None) if pn_value is None: - print("Skipping part with no part number: id={}".format(part.idProp)) + # TODO: use schematic reference if found + print("Skipping part with no part number: uri={}".format(part.uriProp)) continue entry = out_parts.find_by_pn(pn_value) @@ -26,7 +26,7 @@ def create_distributor_search_list(in_path: Path, out_path: Path): continue new_part = types.Part(id=pn_value) - new_part.part_numbersProp = part.part_numbersProp + new_part.referencesProp = part.referencesProp out_parts.add_entry(new_part, True) diff --git a/src/ee/tools/create_order.py b/src/ee/tools/create_order.py index 8ca7e05..8941fcd 100644 --- a/src/ee/tools/create_order.py +++ b/src/ee/tools/create_order.py @@ -1,5 +1,4 @@ import argparse -import sys from pathlib import Path from ee.order import create_order @@ -24,6 +23,4 @@ args = parser.parse_args() part_db_dirs = [Path(part_db) for part_db in args.part_db] fail_on_missing_parts = False -ret = create_order(Path(args.schematic), Path(args.out), part_db_dirs, fail_on_missing_parts) - -sys.exit(1 if ret is False else 0) +create_order(Path(args.schematic), Path(args.out), part_db_dirs, fail_on_missing_parts) diff --git a/src/ee/xml/bom_file_utils.py b/src/ee/xml/bom_file_utils.py index 59a9b0e..207ac5a 100644 --- a/src/ee/xml/bom_file_utils.py +++ b/src/ee/xml/bom_file_utils.py @@ -5,8 +5,9 @@ from ee.xml import types __all__ = [ "facts", "find_root_tag", - "find_pn", - "find_dpn", + "schematic_references", + "part_numbers", + "supplier_part_numbers", ] @@ -14,25 +15,19 @@ def find_root_tag(root): return next((tag for tag, klass in types.GDSClassesMapping.items() if klass == type(root)), None) -def part_numbers(part: types.Part) -> List[types.PartNumber]: - pns = part.part_numbersProp # type: types.PartNumberList - - if pns is None: - return [] +def schematic_references(part: types.Part) -> List[types.SchematicReference]: + return [] if part.referencesProp is None or part.referencesProp.schematic_reference is None else \ + part.referencesProp.schematic_reference - return pns.part_numberProp - -def find_pn(part: types.Part) -> Optional[str]: - for pn in part_numbers(part): - if pn.distributor is None: - return pn.value +def part_numbers(part: types.Part) -> List[types.PartNumber]: + return [] if part.referencesProp is None or part.referencesProp.part_number is None else \ + part.referencesProp.part_number -def find_dpn(part: types.Part, distributor: str) -> Optional[str]: - for pn in part_numbers(part): - if pn.distributor == distributor: - return pn.value +def supplier_part_numbers(part: types.Part) -> List[types.SupplierPartNumber]: + return [] if part.referencesProp is None or part.referencesProp.supplier_part_number is None else \ + part.referencesProp.supplier_part_number def facts(part: types.Part, create=False) -> Optional[types.FactList]: diff --git a/src/ee/xml/types.py b/src/ee/xml/types.py index fec6884..35cd664 100644 --- a/src/ee/xml/types.py +++ b/src/ee/xml/types.py @@ -807,13 +807,12 @@ class PartDb(GeneratedsSuper): class Part(GeneratedsSuper): subclass = None superclass = None - def __init__(self, id=None, schema_reference=None, part_type=None, part_numbers=None, distributor_info=None, facts=None, price_breaks=None, **kwargs_): + def __init__(self, uri=None, part_type=None, references=None, distributor_info=None, facts=None, price_breaks=None, **kwargs_): self.original_tagname_ = None self.parent_object_ = kwargs_.get('parent_object_') - self.id = _cast(None, id) - self.schema_reference = schema_reference + self.uri = _cast(None, uri) self.part_type = part_type - self.part_numbers = part_numbers + self.references = references self.distributor_info = distributor_info self.facts = facts self.price_breaks = price_breaks @@ -828,21 +827,16 @@ class Part(GeneratedsSuper): else: return Part(*args_, **kwargs_) factory = staticmethod(factory) - def get_schema_reference(self): - return self.schema_reference - def set_schema_reference(self, schema_reference): - self.schema_reference = schema_reference - schema_referenceProp = property(get_schema_reference, set_schema_reference) def get_part_type(self): return self.part_type def set_part_type(self, part_type): self.part_type = part_type part_typeProp = property(get_part_type, set_part_type) - def get_part_numbers(self): - return self.part_numbers - def set_part_numbers(self, part_numbers): - self.part_numbers = part_numbers - part_numbersProp = property(get_part_numbers, set_part_numbers) + def get_references(self): + return self.references + def set_references(self, references): + self.references = references + referencesProp = property(get_references, set_references) def get_distributor_info(self): return self.distributor_info def set_distributor_info(self, distributor_info): @@ -858,16 +852,15 @@ class Part(GeneratedsSuper): def set_price_breaks(self, price_breaks): self.price_breaks = price_breaks price_breaksProp = property(get_price_breaks, set_price_breaks) - def get_id(self): - return self.id - def set_id(self, id): - self.id = id - idProp = property(get_id, set_id) + def get_uri(self): + return self.uri + def set_uri(self, uri): + self.uri = uri + uriProp = property(get_uri, set_uri) def hasContent_(self): if ( - self.schema_reference is not None or self.part_type is not None or - self.part_numbers is not None or + self.references is not None or self.distributor_info is not None or self.facts is not None or self.price_breaks is not None @@ -897,22 +890,19 @@ class Part(GeneratedsSuper): else: outfile.write('/>%s' % (eol_, )) def exportAttributes(self, outfile, level, already_processed, namespaceprefix_='', name_='Part'): - if self.id is not None and 'id' not in already_processed: - already_processed.add('id') - outfile.write(' id=%s' % (self.gds_encode(self.gds_format_string(quote_attrib(self.id), input_name='id')), )) + if self.uri is not None and 'uri' not in already_processed: + already_processed.add('uri') + outfile.write(' uri=%s' % (self.gds_encode(self.gds_format_string(quote_attrib(self.uri), input_name='uri')), )) def exportChildren(self, outfile, level, namespaceprefix_='', namespacedef_='', name_='Part', fromsubclass_=False, pretty_print=True): if pretty_print: eol_ = '\n' else: eol_ = '' - if self.schema_reference is not None: - showIndent(outfile, level, pretty_print) - outfile.write('<%sschema-reference>%s</%sschema-reference>%s' % (namespaceprefix_ , self.gds_encode(self.gds_format_string(quote_xml(self.schema_reference), input_name='schema-reference')), namespaceprefix_ , eol_)) if self.part_type is not None: showIndent(outfile, level, pretty_print) outfile.write('<%spart-type>%s</%spart-type>%s' % (namespaceprefix_ , self.gds_encode(self.gds_format_string(quote_xml(self.part_type), input_name='part-type')), namespaceprefix_ , eol_)) - if self.part_numbers is not None: - self.part_numbers.export(outfile, level, namespaceprefix_, namespacedef_='', name_='part-numbers', pretty_print=pretty_print) + if self.references is not None: + self.references.export(outfile, level, namespaceprefix_, namespacedef_='', name_='references', pretty_print=pretty_print) if self.distributor_info is not None: self.distributor_info.export(outfile, level, namespaceprefix_, namespacedef_='', name_='distributor-info', pretty_print=pretty_print) if self.facts is not None: @@ -927,24 +917,20 @@ class Part(GeneratedsSuper): self.buildChildren(child, node, nodeName_) return self def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('id', node) - if value is not None and 'id' not in already_processed: - already_processed.add('id') - self.id = value + value = find_attr_value_('uri', node) + if value is not None and 'uri' not in already_processed: + already_processed.add('uri') + self.uri = value def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == 'schema-reference': - schema_reference_ = child_.text - schema_reference_ = self.gds_validate_string(schema_reference_, node, 'schema_reference') - self.schema_reference = schema_reference_ - elif nodeName_ == 'part-type': + if nodeName_ == 'part-type': part_type_ = child_.text part_type_ = self.gds_validate_string(part_type_, node, 'part_type') self.part_type = part_type_ - elif nodeName_ == 'part-numbers': - obj_ = PartNumberList.factory(parent_object_=self) + elif nodeName_ == 'references': + obj_ = ReferencesList.factory(parent_object_=self) obj_.build(child_) - self.part_numbers = obj_ - obj_.original_tagname_ = 'part-numbers' + self.references = obj_ + obj_.original_tagname_ = 'references' elif nodeName_ == 'distributor-info': obj_ = DistributorInfo.factory(parent_object_=self) obj_.build(child_) @@ -1052,14 +1038,91 @@ class PartList(GeneratedsSuper): # end class PartList +class PartUri(GeneratedsSuper): + subclass = None + superclass = None + def __init__(self, value=None, **kwargs_): + self.original_tagname_ = None + self.parent_object_ = kwargs_.get('parent_object_') + self.value = value + def factory(*args_, **kwargs_): + if CurrentSubclassModule_ is not None: + subclass = getSubclassFromModule_( + CurrentSubclassModule_, PartUri) + if subclass is not None: + return subclass(*args_, **kwargs_) + if PartUri.subclass: + return PartUri.subclass(*args_, **kwargs_) + else: + return PartUri(*args_, **kwargs_) + factory = staticmethod(factory) + def get_value(self): + return self.value + def set_value(self, value): + self.value = value + valueProp = property(get_value, set_value) + def hasContent_(self): + if ( + self.value is not None + ): + return True + else: + return False + def export(self, outfile, level, namespaceprefix_='', namespacedef_='', name_='PartUri', pretty_print=True): + imported_ns_def_ = GenerateDSNamespaceDefs_.get('PartUri') + if imported_ns_def_ is not None: + namespacedef_ = imported_ns_def_ + if pretty_print: + eol_ = '\n' + else: + eol_ = '' + if self.original_tagname_ is not None: + name_ = self.original_tagname_ + showIndent(outfile, level, pretty_print) + outfile.write('<%s%s%s' % (namespaceprefix_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) + already_processed = set() + self.exportAttributes(outfile, level, already_processed, namespaceprefix_, name_='PartUri') + if self.hasContent_(): + outfile.write('>%s' % (eol_, )) + self.exportChildren(outfile, level + 1, namespaceprefix_, namespacedef_, name_='PartUri', pretty_print=pretty_print) + showIndent(outfile, level, pretty_print) + outfile.write('</%s%s>%s' % (namespaceprefix_, name_, eol_)) + else: + outfile.write('/>%s' % (eol_, )) + def exportAttributes(self, outfile, level, already_processed, namespaceprefix_='', name_='PartUri'): + pass + def exportChildren(self, outfile, level, namespaceprefix_='', namespacedef_='', name_='PartUri', fromsubclass_=False, pretty_print=True): + if pretty_print: + eol_ = '\n' + else: + eol_ = '' + if self.value is not None: + showIndent(outfile, level, pretty_print) + outfile.write('<%svalue>%s</%svalue>%s' % (namespaceprefix_ , self.gds_encode(self.gds_format_string(quote_xml(self.value), input_name='value')), namespaceprefix_ , eol_)) + def build(self, node): + already_processed = set() + self.buildAttributes(node, node.attrib, already_processed) + for child in node: + nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] + self.buildChildren(child, node, nodeName_) + return self + def buildAttributes(self, node, attrs, already_processed): + pass + def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): + if nodeName_ == 'value': + value_ = child_.text + value_ = self.gds_validate_string(value_, node, 'value') + self.value = value_ +# end class PartUri + + class PartNumber(GeneratedsSuper): subclass = None superclass = None - def __init__(self, value=None, distributor=None, **kwargs_): + def __init__(self, value=None, **kwargs_): self.original_tagname_ = None self.parent_object_ = kwargs_.get('parent_object_') self.value = value - self.distributor = distributor def factory(*args_, **kwargs_): if CurrentSubclassModule_ is not None: subclass = getSubclassFromModule_( @@ -1076,15 +1139,9 @@ class PartNumber(GeneratedsSuper): def set_value(self, value): self.value = value valueProp = property(get_value, set_value) - def get_distributor(self): - return self.distributor - def set_distributor(self, distributor): - self.distributor = distributor - distributorProp = property(get_distributor, set_distributor) def hasContent_(self): if ( - self.value is not None or - self.distributor is not None + self.value is not None ): return True else: @@ -1120,9 +1177,6 @@ class PartNumber(GeneratedsSuper): if self.value is not None: showIndent(outfile, level, pretty_print) outfile.write('<%svalue>%s</%svalue>%s' % (namespaceprefix_ , self.gds_encode(self.gds_format_string(quote_xml(self.value), input_name='value')), namespaceprefix_ , eol_)) - if self.distributor is not None: - showIndent(outfile, level, pretty_print) - outfile.write('<%sdistributor>%s</%sdistributor>%s' % (namespaceprefix_ , self.gds_encode(self.gds_format_string(quote_xml(self.distributor), input_name='distributor')), namespaceprefix_ , eol_)) def build(self, node): already_processed = set() self.buildAttributes(node, node.attrib, already_processed) @@ -1137,34 +1191,238 @@ class PartNumber(GeneratedsSuper): value_ = child_.text value_ = self.gds_validate_string(value_, node, 'value') self.value = value_ - elif nodeName_ == 'distributor': - distributor_ = child_.text - distributor_ = self.gds_validate_string(distributor_, node, 'distributor') - self.distributor = distributor_ # end class PartNumber -class PartNumberList(GeneratedsSuper): +class SupplierPartNumber(GeneratedsSuper): subclass = None superclass = None - def __init__(self, part_number=None, **kwargs_): + def __init__(self, value=None, supplier=None, **kwargs_): self.original_tagname_ = None self.parent_object_ = kwargs_.get('parent_object_') + self.value = value + self.supplier = supplier + def factory(*args_, **kwargs_): + if CurrentSubclassModule_ is not None: + subclass = getSubclassFromModule_( + CurrentSubclassModule_, SupplierPartNumber) + if subclass is not None: + return subclass(*args_, **kwargs_) + if SupplierPartNumber.subclass: + return SupplierPartNumber.subclass(*args_, **kwargs_) + else: + return SupplierPartNumber(*args_, **kwargs_) + factory = staticmethod(factory) + def get_value(self): + return self.value + def set_value(self, value): + self.value = value + valueProp = property(get_value, set_value) + def get_supplier(self): + return self.supplier + def set_supplier(self, supplier): + self.supplier = supplier + supplierProp = property(get_supplier, set_supplier) + def hasContent_(self): + if ( + self.value is not None or + self.supplier is not None + ): + return True + else: + return False + def export(self, outfile, level, namespaceprefix_='', namespacedef_='', name_='SupplierPartNumber', pretty_print=True): + imported_ns_def_ = GenerateDSNamespaceDefs_.get('SupplierPartNumber') + if imported_ns_def_ is not None: + namespacedef_ = imported_ns_def_ + if pretty_print: + eol_ = '\n' + else: + eol_ = '' + if self.original_tagname_ is not None: + name_ = self.original_tagname_ + showIndent(outfile, level, pretty_print) + outfile.write('<%s%s%s' % (namespaceprefix_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) + already_processed = set() + self.exportAttributes(outfile, level, already_processed, namespaceprefix_, name_='SupplierPartNumber') + if self.hasContent_(): + outfile.write('>%s' % (eol_, )) + self.exportChildren(outfile, level + 1, namespaceprefix_, namespacedef_, name_='SupplierPartNumber', pretty_print=pretty_print) + showIndent(outfile, level, pretty_print) + outfile.write('</%s%s>%s' % (namespaceprefix_, name_, eol_)) + else: + outfile.write('/>%s' % (eol_, )) + def exportAttributes(self, outfile, level, already_processed, namespaceprefix_='', name_='SupplierPartNumber'): + pass + def exportChildren(self, outfile, level, namespaceprefix_='', namespacedef_='', name_='SupplierPartNumber', fromsubclass_=False, pretty_print=True): + if pretty_print: + eol_ = '\n' + else: + eol_ = '' + if self.value is not None: + showIndent(outfile, level, pretty_print) + outfile.write('<%svalue>%s</%svalue>%s' % (namespaceprefix_ , self.gds_encode(self.gds_format_string(quote_xml(self.value), input_name='value')), namespaceprefix_ , eol_)) + if self.supplier is not None: + showIndent(outfile, level, pretty_print) + outfile.write('<%ssupplier>%s</%ssupplier>%s' % (namespaceprefix_ , self.gds_encode(self.gds_format_string(quote_xml(self.supplier), input_name='supplier')), namespaceprefix_ , eol_)) + def build(self, node): + already_processed = set() + self.buildAttributes(node, node.attrib, already_processed) + for child in node: + nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] + self.buildChildren(child, node, nodeName_) + return self + def buildAttributes(self, node, attrs, already_processed): + pass + def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): + if nodeName_ == 'value': + value_ = child_.text + value_ = self.gds_validate_string(value_, node, 'value') + self.value = value_ + elif nodeName_ == 'supplier': + supplier_ = child_.text + supplier_ = self.gds_validate_string(supplier_, node, 'supplier') + self.supplier = supplier_ +# end class SupplierPartNumber + + +class SchematicReference(GeneratedsSuper): + subclass = None + superclass = None + def __init__(self, reference=None, **kwargs_): + self.original_tagname_ = None + self.parent_object_ = kwargs_.get('parent_object_') + self.reference = reference + def factory(*args_, **kwargs_): + if CurrentSubclassModule_ is not None: + subclass = getSubclassFromModule_( + CurrentSubclassModule_, SchematicReference) + if subclass is not None: + return subclass(*args_, **kwargs_) + if SchematicReference.subclass: + return SchematicReference.subclass(*args_, **kwargs_) + else: + return SchematicReference(*args_, **kwargs_) + factory = staticmethod(factory) + def get_reference(self): + return self.reference + def set_reference(self, reference): + self.reference = reference + referenceProp = property(get_reference, set_reference) + def hasContent_(self): + if ( + self.reference is not None + ): + return True + else: + return False + def export(self, outfile, level, namespaceprefix_='', namespacedef_='', name_='SchematicReference', pretty_print=True): + imported_ns_def_ = GenerateDSNamespaceDefs_.get('SchematicReference') + if imported_ns_def_ is not None: + namespacedef_ = imported_ns_def_ + if pretty_print: + eol_ = '\n' + else: + eol_ = '' + if self.original_tagname_ is not None: + name_ = self.original_tagname_ + showIndent(outfile, level, pretty_print) + outfile.write('<%s%s%s' % (namespaceprefix_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) + already_processed = set() + self.exportAttributes(outfile, level, already_processed, namespaceprefix_, name_='SchematicReference') + if self.hasContent_(): + outfile.write('>%s' % (eol_, )) + self.exportChildren(outfile, level + 1, namespaceprefix_, namespacedef_, name_='SchematicReference', pretty_print=pretty_print) + showIndent(outfile, level, pretty_print) + outfile.write('</%s%s>%s' % (namespaceprefix_, name_, eol_)) + else: + outfile.write('/>%s' % (eol_, )) + def exportAttributes(self, outfile, level, already_processed, namespaceprefix_='', name_='SchematicReference'): + pass + def exportChildren(self, outfile, level, namespaceprefix_='', namespacedef_='', name_='SchematicReference', fromsubclass_=False, pretty_print=True): + if pretty_print: + eol_ = '\n' + else: + eol_ = '' + if self.reference is not None: + showIndent(outfile, level, pretty_print) + outfile.write('<%sreference>%s</%sreference>%s' % (namespaceprefix_ , self.gds_encode(self.gds_format_string(quote_xml(self.reference), input_name='reference')), namespaceprefix_ , eol_)) + def build(self, node): + already_processed = set() + self.buildAttributes(node, node.attrib, already_processed) + for child in node: + nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] + self.buildChildren(child, node, nodeName_) + return self + def buildAttributes(self, node, attrs, already_processed): + pass + def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): + if nodeName_ == 'reference': + reference_ = child_.text + reference_ = self.gds_validate_string(reference_, node, 'reference') + self.reference = reference_ +# end class SchematicReference + + +class ReferencesList(GeneratedsSuper): + subclass = None + superclass = None + def __init__(self, schematic_reference=None, part_uri=None, part_number=None, supplier_part_number=None, **kwargs_): + self.original_tagname_ = None + self.parent_object_ = kwargs_.get('parent_object_') + if schematic_reference is None: + self.schematic_reference = [] + else: + self.schematic_reference = schematic_reference + if part_uri is None: + self.part_uri = [] + else: + self.part_uri = part_uri if part_number is None: self.part_number = [] else: self.part_number = part_number + if supplier_part_number is None: + self.supplier_part_number = [] + else: + self.supplier_part_number = supplier_part_number def factory(*args_, **kwargs_): if CurrentSubclassModule_ is not None: subclass = getSubclassFromModule_( - CurrentSubclassModule_, PartNumberList) + CurrentSubclassModule_, ReferencesList) if subclass is not None: return subclass(*args_, **kwargs_) - if PartNumberList.subclass: - return PartNumberList.subclass(*args_, **kwargs_) + if ReferencesList.subclass: + return ReferencesList.subclass(*args_, **kwargs_) else: - return PartNumberList(*args_, **kwargs_) + return ReferencesList(*args_, **kwargs_) factory = staticmethod(factory) + def get_schematic_reference(self): + return self.schematic_reference + def set_schematic_reference(self, schematic_reference): + self.schematic_reference = schematic_reference + def add_schematic_reference(self, value): + self.schematic_reference.append(value) + def add_schematic_reference(self, value): + self.schematic_reference.append(value) + def insert_schematic_reference_at(self, index, value): + self.schematic_reference.insert(index, value) + def replace_schematic_reference_at(self, index, value): + self.schematic_reference[index] = value + schematic_referenceProp = property(get_schematic_reference, set_schematic_reference) + def get_part_uri(self): + return self.part_uri + def set_part_uri(self, part_uri): + self.part_uri = part_uri + def add_part_uri(self, value): + self.part_uri.append(value) + def add_part_uri(self, value): + self.part_uri.append(value) + def insert_part_uri_at(self, index, value): + self.part_uri.insert(index, value) + def replace_part_uri_at(self, index, value): + self.part_uri[index] = value + part_uriProp = property(get_part_uri, set_part_uri) def get_part_number(self): return self.part_number def set_part_number(self, part_number): @@ -1178,15 +1436,31 @@ class PartNumberList(GeneratedsSuper): def replace_part_number_at(self, index, value): self.part_number[index] = value part_numberProp = property(get_part_number, set_part_number) + def get_supplier_part_number(self): + return self.supplier_part_number + def set_supplier_part_number(self, supplier_part_number): + self.supplier_part_number = supplier_part_number + def add_supplier_part_number(self, value): + self.supplier_part_number.append(value) + def add_supplier_part_number(self, value): + self.supplier_part_number.append(value) + def insert_supplier_part_number_at(self, index, value): + self.supplier_part_number.insert(index, value) + def replace_supplier_part_number_at(self, index, value): + self.supplier_part_number[index] = value + supplier_part_numberProp = property(get_supplier_part_number, set_supplier_part_number) def hasContent_(self): if ( - self.part_number + self.schematic_reference or + self.part_uri or + self.part_number or + self.supplier_part_number ): return True else: return False - def export(self, outfile, level, namespaceprefix_='', namespacedef_='', name_='PartNumberList', pretty_print=True): - imported_ns_def_ = GenerateDSNamespaceDefs_.get('PartNumberList') + def export(self, outfile, level, namespaceprefix_='', namespacedef_='', name_='ReferencesList', pretty_print=True): + imported_ns_def_ = GenerateDSNamespaceDefs_.get('ReferencesList') if imported_ns_def_ is not None: namespacedef_ = imported_ns_def_ if pretty_print: @@ -1198,23 +1472,29 @@ class PartNumberList(GeneratedsSuper): showIndent(outfile, level, pretty_print) outfile.write('<%s%s%s' % (namespaceprefix_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) already_processed = set() - self.exportAttributes(outfile, level, already_processed, namespaceprefix_, name_='PartNumberList') + self.exportAttributes(outfile, level, already_processed, namespaceprefix_, name_='ReferencesList') if self.hasContent_(): outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespaceprefix_, namespacedef_, name_='PartNumberList', pretty_print=pretty_print) + self.exportChildren(outfile, level + 1, namespaceprefix_, namespacedef_, name_='ReferencesList', pretty_print=pretty_print) showIndent(outfile, level, pretty_print) outfile.write('</%s%s>%s' % (namespaceprefix_, name_, eol_)) else: outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespaceprefix_='', name_='PartNumberList'): + def exportAttributes(self, outfile, level, already_processed, namespaceprefix_='', name_='ReferencesList'): pass - def exportChildren(self, outfile, level, namespaceprefix_='', namespacedef_='', name_='PartNumberList', fromsubclass_=False, pretty_print=True): + def exportChildren(self, outfile, level, namespaceprefix_='', namespacedef_='', name_='ReferencesList', fromsubclass_=False, pretty_print=True): if pretty_print: eol_ = '\n' else: eol_ = '' + for schematic_reference_ in self.schematic_reference: + schematic_reference_.export(outfile, level, namespaceprefix_, namespacedef_='', name_='schematic-reference', pretty_print=pretty_print) + for part_uri_ in self.part_uri: + part_uri_.export(outfile, level, namespaceprefix_, namespacedef_='', name_='part-uri', pretty_print=pretty_print) for part_number_ in self.part_number: part_number_.export(outfile, level, namespaceprefix_, namespacedef_='', name_='part-number', pretty_print=pretty_print) + for supplier_part_number_ in self.supplier_part_number: + supplier_part_number_.export(outfile, level, namespaceprefix_, namespacedef_='', name_='supplier-part-number', pretty_print=pretty_print) def build(self, node): already_processed = set() self.buildAttributes(node, node.attrib, already_processed) @@ -1225,12 +1505,27 @@ class PartNumberList(GeneratedsSuper): def buildAttributes(self, node, attrs, already_processed): pass def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == 'part-number': + if nodeName_ == 'schematic-reference': + obj_ = SchematicReference.factory(parent_object_=self) + obj_.build(child_) + self.schematic_reference.append(obj_) + obj_.original_tagname_ = 'schematic-reference' + elif nodeName_ == 'part-uri': + obj_ = PartUri.factory(parent_object_=self) + obj_.build(child_) + self.part_uri.append(obj_) + obj_.original_tagname_ = 'part-uri' + elif nodeName_ == 'part-number': obj_ = PartNumber.factory(parent_object_=self) obj_.build(child_) self.part_number.append(obj_) obj_.original_tagname_ = 'part-number' -# end class PartNumberList + elif nodeName_ == 'supplier-part-number': + obj_ = SupplierPartNumber.factory(parent_object_=self) + obj_.build(child_) + self.supplier_part_number.append(obj_) + obj_.original_tagname_ = 'supplier-part-number' +# end class ReferencesList class Fact(GeneratedsSuper): @@ -1911,7 +2206,10 @@ __all__ = [ "PartDb", "PartList", "PartNumber", - "PartNumberList", + "PartUri", "PriceBreak", - "PriceBreakList" + "PriceBreakList", + "ReferencesList", + "SchematicReference", + "SupplierPartNumber" ] @@ -31,7 +31,7 @@ TODO: rename 'id' to 'url'. targetNamespace="http://purl.org/ee/bom-file" xmlns="http://purl.org/ee/bom-file"> - <xs:attribute name="id" type="xs:string"/> + <xs:attribute name="uri" type="xs:anyURI"/> <xs:element name="part-db" type="PartDb"/> <xs:element name="part" type="Part"/> @@ -44,14 +44,14 @@ TODO: rename 'id' to 'url'. <xs:complexType name="Part"> <xs:sequence> - <xs:element name="schema-reference" type="xs:string"/> + <!-- TODO: this should be a fact --> <xs:element name="part-type" type="xs:anyURI"/> - <xs:element name="part-numbers" type="PartNumberList"/> + <xs:element name="references" type="ReferencesList"/> <xs:element name="distributor-info" type="DistributorInfo"/> <xs:element name="facts" type="FactList"/> <xs:element name="price-breaks" type="PriceBreakList"/> </xs:sequence> - <xs:attribute ref="id" use="required"/> + <xs:attribute ref="uri"/> </xs:complexType> <xs:complexType name="PartList"> @@ -60,16 +60,39 @@ TODO: rename 'id' to 'url'. </xs:sequence> </xs:complexType> + <xs:complexType name="PartUri"> + <xs:sequence> + <xs:element name="value" type="xs:anyURI"/> + </xs:sequence> + </xs:complexType> + <xs:complexType name="PartNumber"> <xs:sequence> <xs:element name="value" type="xs:string"/> - <xs:element name="distributor" type="xs:anyURI"/> </xs:sequence> </xs:complexType> - <xs:complexType name="PartNumberList"> + <xs:complexType name="SupplierPartNumber"> + <xs:sequence> + <xs:element name="value" type="xs:string"/> + <xs:element name="supplier" type="xs:anyURI"/> + </xs:sequence> + </xs:complexType> + + <xs:complexType name="SchematicReference"> + <xs:sequence> + <xs:element name="reference" type="xs:string"/> + </xs:sequence> + </xs:complexType> + + <xs:complexType name="ReferencesList"> <xs:sequence> - <xs:element name="part-number" type="PartNumber" maxOccurs="unbounded"/> + <xs:choice maxOccurs="unbounded"> + <xs:element name="schematic-reference" type="SchematicReference"/> + <xs:element name="part-uri" type="PartUri"/> + <xs:element name="part-number" type="PartNumber"/> + <xs:element name="supplier-part-number" type="SupplierPartNumber"/> + </xs:choice> </xs:sequence> </xs:complexType> |