diff options
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | src/ee/digikey/import_parts.py | 100 | ||||
-rw-r--r-- | src/ee/digikey/search_parts.py (renamed from src/ee/digikey/refresh_parts.py) | 25 | ||||
-rw-r--r-- | src/ee/kicad/make_bom.py | 32 | ||||
-rw-r--r-- | src/ee/part/__init__.py | 103 | ||||
-rw-r--r-- | src/ee/part/create_distributor_search_list.py | 33 | ||||
-rw-r--r-- | src/ee/tools/digikey_search_parts.py (renamed from src/ee/tools/digikey_refresh_parts.py) | 4 | ||||
-rw-r--r-- | src/ee/tools/kicad_make_bom.py | 3 | ||||
-rw-r--r-- | src/ee/tools/part_create_distributor_search_list.py (renamed from src/ee/tools/digikey_import_parts.py) | 8 | ||||
-rw-r--r-- | src/ee/xml/bomFile.py | 5 | ||||
-rw-r--r-- | src/ee/xml/bom_file_utils.py | 13 | ||||
-rw-r--r-- | src/ee/xml/indexFile.py (renamed from src/ee/xml/catalogFile.py) | 218 | ||||
-rw-r--r-- | xsd/ee-bom.xsd | 1 | ||||
-rw-r--r-- | xsd/ee-catalog.xsd | 26 | ||||
-rw-r--r-- | xsd/ee-index.xsd | 24 |
15 files changed, 316 insertions, 285 deletions
@@ -1,5 +1,5 @@ -XSDS = xsd/ee-bom.xsd xsd/ee-catalog.xsd -XSD_PYS = src/ee/xml/bomFile.py src/ee/xml/catalogFile.py +XSDS = xsd/ee-bom.xsd xsd/ee-index.xsd +XSD_PYS = src/ee/xml/bomFile.py src/ee/xml/indexFile.py all: env/pip.cookie $(XSD_PYS) @@ -19,8 +19,8 @@ src/ee/xml/%File.py: xsd/ee-%.xsd -f \ --no-dates \ --no-versions \ - --one-file-per-xsd \ --output-directory=src/ee/xml \ + -o $@ \ -m $< $(XSDS): env/pip.cookie src/ee/xml/__init__.py diff --git a/src/ee/digikey/import_parts.py b/src/ee/digikey/import_parts.py deleted file mode 100644 index 748bbef..0000000 --- a/src/ee/digikey/import_parts.py +++ /dev/null @@ -1,100 +0,0 @@ -import os -from typing import List, MutableMapping - -from ee.xml import bomFile -from ee.xml.bom_file_utils import * -from ee.xml.uris import DIGIKEY_URI - -__all__ = ["import_parts"] - - -class Entry(object): - def __init__(self, new: bool, part: bomFile.Part): - self.new = new - self.part = part - - self.pn = find_pn(part) - self.dpn = find_dpn(part, DIGIKEY_URI) - - -def import_parts(in_path, out_path): - print("in: {}, out: {}".format(in_path, out_path)) - - in_file = bomFile.parse(in_path, True) - if in_file.partsProp is None: - in_file.partsProp = bomFile.PartList() - in_part_list = in_file.partsProp.partProp # type: List[bomFile.Part] - - print("in file: {} parts".format(len(in_part_list))) - - if os.path.isfile(out_path): - out_file = bomFile.parse(out_path, True) - else: - out_file = bomFile.BomFile() - - if out_file.partsProp is None: - out_file.partsProp = bomFile.PartList() - out_part_list = out_file.partsProp.partProp # type: List[bomFile.Part] - print("out file: {} parts".format(len(out_part_list))) - - existing_parts = [] # type: List[Entry] - pn_index = {} # type: MutableMapping[str, Entry] - dpn_index = {} # type: MutableMapping[str, Entry] - new_entry_added = 0 - - def add_entry(e: Entry): - existing_parts.append(e) - pn_index[e.pn] = e - dpn_index[e.dpn] = e - - if e.new: - out_part_list.append(e.part) - nonlocal new_entry_added - new_entry_added = new_entry_added + 1 - - print("len(out_part_list)={}".format(len(out_part_list))) - for part in out_part_list: # type: bomFile.Part - entry = Entry(False, part) - add_entry(entry) - - print("loaded {} existing parts".format(len(existing_parts))) - - for part in in_part_list: - pn_value = find_pn(part) - - if pn_value is None: - print("Skipping part with no part number: id={}".format(part.idProp)) - continue - - entry = pn_index.get(pn_value) - - if entry is not None: - print("Already imported pn_value={}".format(pn_value)) - continue - - print("Importing {}".format(pn_value)) - - pns = bomFile.PartNumberList() - - if pn_value is not None: - pns.add_part_number(bomFile.PartNumber(value=pn_value)) - - dpn_value = find_dpn(part, DIGIKEY_URI) - if dpn_value is not None: - pns.add_part_number(bomFile.PartNumber(value=dpn_value, distributor=DIGIKEY_URI)) - - if len(pns.part_numberProp) == 0: - continue - - new_part = bomFile.Part(part_numbers=pns) - entry = Entry(True, new_part) - add_entry(entry) - - if new_entry_added: - print("Imported {} entries".format(new_entry_added)) - tmp_path = out_path + ".tmp" - with open(tmp_path, "w") as f: - out_file.export(f, 0, name_="bom-file") - os.rename(tmp_path, out_path) - else: - print("no new entries") diff --git a/src/ee/digikey/refresh_parts.py b/src/ee/digikey/search_parts.py index 87edf2f..62bb4ee 100644 --- a/src/ee/digikey/refresh_parts.py +++ b/src/ee/digikey/search_parts.py @@ -1,13 +1,13 @@ -import os 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__ = ["refresh_parts"] +__all__ = ["search_parts"] def resolved(di: DigikeyDistributorInfo, part: bomFile.Part, p: DigikeyProduct): @@ -23,17 +23,16 @@ def resolved(di: DigikeyDistributorInfo, part: bomFile.Part, p: DigikeyProduct): facts.append(bomFile.Fact(key=a.attribute_type.id, label=a.attribute_type.label, value=a.value)) -def refresh_parts(in_path: Path, out_path: Path, cache_dir: Path, force_refresh: bool): - print("in: {}, out: {}".format(in_path, out_path)) +def search_parts(in_dir: Path, out_dir: Path, cache_dir: Path, force_refresh: bool): + print("in: {}, out: {}".format(in_dir, out_dir)) - in_file = bomFile.parse(str(in_path), True) - if in_file.partsProp is None: - in_file.partsProp = bomFile.PartList() + in_db = load_db(in_dir) + out_parts = PartDb() parser = DigikeyParser(Digikey()) client = DigikeyClient(cache_dir) - for part in in_file.partsProp.partProp: # type: bomFile.Part + for part in in_db.iterparts(): dpn = bom_file_utils.find_dpn(part, DIGIKEY_URI) mpn = bom_file_utils.find_pn(part) @@ -89,9 +88,7 @@ def refresh_parts(in_path: Path, out_path: Path, cache_dir: Path, force_refresh: elif response.response_type == SearchResponseTypes.NO_MATCHES: di.stateProp = "not-found" - out_path = in_path - out_file = in_file - tmp_path = str(out_path) + ".tmp" - with open(tmp_path, "w") as f: - out_file.export(f, 0, name_="bom-file") - os.rename(tmp_path, str(out_path)) + out_parts.add_entry(part, True) + + print("Saving {} work parts".format(out_parts.size())) + save_db(out_dir, out_parts) diff --git a/src/ee/kicad/make_bom.py b/src/ee/kicad/make_bom.py index 2f5a2ac..00e9ae3 100644 --- a/src/ee/kicad/make_bom.py +++ b/src/ee/kicad/make_bom.py @@ -1,4 +1,5 @@ -import sys +import pydoc +from pathlib import Path from typing import Optional, List, Callable, Mapping from xml.dom import minidom from xml.etree import ElementTree @@ -7,7 +8,7 @@ from ee import EeException from ee.kicad.model import Component from ee.kicad.read_schematic import read_schematics from ee.kicad.to_bom import to_bom, to_bom_xml -from ee.tools import mk_parents +from ee.part import PartDb, save_db from ee.xml import bomFile, uris __all__ = [ @@ -97,7 +98,7 @@ class MakeBomStrategy(): return apply_strategies(component, part, self.default_strategies) -def work(sch, out_file, strategy: MakeBomStrategy, new_mode, pretty): +def work(sch, out: Path, strategy: MakeBomStrategy, new_mode, pretty): if not new_mode: bom = to_bom_xml(sch) xml = ElementTree.tostring(bom, encoding="unicode") @@ -105,13 +106,9 @@ def work(sch, out_file, strategy: MakeBomStrategy, new_mode, pretty): if pretty: xml = minidom.parseString(xml).toprettyxml(indent=" ") - print(xml, file=out_file) + print(xml) else: - file = bomFile.BomFile() - - parts = bomFile.PartList() - file.partsProp = parts - + parts = PartDb() components = to_bom(sch) for c in components: part = bomFile.Part(id=c.ref) @@ -124,16 +121,14 @@ def work(sch, out_file, strategy: MakeBomStrategy, new_mode, pretty): part.part_numbersProp = None if part is not None: - parts.add_part(part) + parts.add_entry(part, True) - file.export(out_file, 0, name_="bom-file", namespacedef_="xmlns='http://purl.org/ee/bom-file'", - pretty_print=pretty) + save_db(out, parts) -def make_bom(sch_file: str, out_file: Optional[str], strategy_name: str, new_mode: bool, pretty: bool): - sch = read_schematics(sch_file) +def make_bom(sch_file: Path, out_dir: Path, strategy_name: str, new_mode: bool, pretty: bool): + sch = read_schematics(str(sch_file)) - import pydoc make_bom_strategy_factory = pydoc.locate(strategy_name) if not callable(make_bom_strategy_factory): @@ -144,9 +139,4 @@ def make_bom(sch_file: str, out_file: Optional[str], strategy_name: str, new_mod if not isinstance(make_bom_strategy, MakeBomStrategy): raise EeException("Not a MakeBomStrategy: {}, is a {}".format(strategy_name, type(make_bom_strategy))) - if out_file: - mk_parents(out_file) - with open(out_file, "w") as f: - work(sch, f, make_bom_strategy, new_mode, pretty) - else: - work(sch, sys.stdout, make_bom_strategy, new_mode, pretty) + work(sch, out_dir, make_bom_strategy, new_mode, pretty) diff --git a/src/ee/part/__init__.py b/src/ee/part/__init__.py new file mode 100644 index 0000000..84a6174 --- /dev/null +++ b/src/ee/part/__init__.py @@ -0,0 +1,103 @@ +from pathlib import Path +from typing import List, MutableMapping, Optional, Iterator + +from ee import EeException +from ee.xml import bomFile, indexFile +from ee.xml.bom_file_utils import find_pn, find_dpn, find_root_tag + +__all__ = [ + "PartDb", + "load_db", + "save_db", +] + + +class Entry(object): + def __init__(self, new: bool, part: bomFile.Part): + self.new = new + self.part = part + + self.pn = find_pn(part) + + def dpn(self, uri: str): + return find_dpn(self.part, uri) + + +class PartDb(object): + def __init__(self): + self.parts = [] # type: List[Entry] + self.pn_index = {} # type: MutableMapping[str, Entry] + self.dpn_indexes = {} # type: MutableMapping[str, MutableMapping[str, Entry]] + self.new_entries = 0 + + def add_entry(self, part: bomFile.Part, new: bool): + 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 + + def iterparts(self) -> Iterator[bomFile.Part]: + return [e.part for e in self.parts] + + def size(self) -> int: + return len(self.parts) + + def find_by_pn(self, pn: str) -> Optional[bomFile.Part]: + entry = self.pn_index.get(pn, None) + return entry.part if entry else None + + def find_by_dpn(self, distributor: str, pn: str) -> bomFile.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(dir_path: Path) -> PartDb: + db = PartDb() + + for file in dir_path.iterdir(): + if not file.is_file() or not file.name.endswith(".xml") or file.name == "index.xml": + continue + + part = bomFile.parse(str(file), silence=True) # type: bomFile.Part + db.add_entry(part, False) + + return db + + +def save_db(dir_path: Path, db: PartDb): + if dir_path.exists(): + if not dir_path.is_dir(): + raise EeException("The given db path is not a directory") + + idx_path = dir_path / "index.xml" + if not idx_path.is_file(): + raise EeException("The given db directory exists, but does not look like a part db dir") + + dir_path.rmdir() + + dir_path.mkdir(parents=True, exist_ok=True) + + idx = indexFile.IndexFile() + idx.filesProp = indexFile.FileList() + files = idx.filesProp.fileProp + + for part in db.iterparts(): + id_ = part.id + path = dir_path / "{}.xml".format(id_) + with path.open("w") as f: + part.export(outfile=f, level=0, name_=find_root_tag(part)) + + files.append(indexFile.File(path=str(path))) + + with (dir_path / "index.xml").open("w") as f: + idx.export(f, level=0, name_=find_root_tag(idx)) diff --git a/src/ee/part/create_distributor_search_list.py b/src/ee/part/create_distributor_search_list.py new file mode 100644 index 0000000..ef91e1f --- /dev/null +++ b/src/ee/part/create_distributor_search_list.py @@ -0,0 +1,33 @@ +from pathlib import Path + +from ee.part import PartDb, load_db, save_db +from ee.xml.bom_file_utils import * + +__all__ = ["create_distributor_search_list"] + + +def create_distributor_search_list(in_dir: Path, out_dir: Path): + print("in: {}, out: {}".format(in_dir, out_dir)) + + in_parts = load_db(in_dir) + out_parts = PartDb() + + print("loaded {} existing parts".format(in_parts.size())) + + for part in in_parts.iterparts(): + pn_value = find_pn(part) + + if pn_value is None: + print("Skipping part with no part number: id={}".format(part.idProp)) + continue + + entry = out_parts.find_by_pn(pn_value) + + if entry is not None: + continue + + part.id = pn_value + out_parts.add_entry(part, True) + + print("Saving {} work parts".format(out_parts.size())) + save_db(out_dir, out_parts) diff --git a/src/ee/tools/digikey_refresh_parts.py b/src/ee/tools/digikey_search_parts.py index e3e3b35..80393eb 100644 --- a/src/ee/tools/digikey_refresh_parts.py +++ b/src/ee/tools/digikey_search_parts.py @@ -1,7 +1,7 @@ import argparse from pathlib import Path -from ee.digikey.refresh_parts import refresh_parts +from ee.digikey.search_parts import search_parts parser = argparse.ArgumentParser() @@ -19,4 +19,4 @@ args = parser.parse_args() cache_dir = ".ee/cache" force = True -refresh_parts(Path(args.in_), Path(args.out), Path(cache_dir), force) +search_parts(Path(args.in_), Path(args.out), Path(cache_dir), force) diff --git a/src/ee/tools/kicad_make_bom.py b/src/ee/tools/kicad_make_bom.py index 769ea0d..c4a1dd8 100644 --- a/src/ee/tools/kicad_make_bom.py +++ b/src/ee/tools/kicad_make_bom.py @@ -1,4 +1,5 @@ import argparse +from pathlib import Path from ee.kicad.make_bom import make_bom @@ -24,4 +25,4 @@ new_mode = True strategy = args.strategy if args.strategy else "ee.kicad.make_bom.MakeBomStrategy" -make_bom(args.sch, args.out, strategy, new_mode, pretty) +make_bom(Path(args.sch), Path(args.out), strategy, new_mode, pretty) diff --git a/src/ee/tools/digikey_import_parts.py b/src/ee/tools/part_create_distributor_search_list.py index 77f87e8..22b4c3f 100644 --- a/src/ee/tools/digikey_import_parts.py +++ b/src/ee/tools/part_create_distributor_search_list.py @@ -1,7 +1,9 @@ import argparse -from ee.digikey.import_parts import import_parts +from pathlib import Path -parser = argparse.ArgumentParser(description="Import all parts in XML file into Digi-Key parts list") +from ee.part.create_distributor_search_list import create_distributor_search_list + +parser = argparse.ArgumentParser() parser.add_argument("--in", dest="in_", @@ -14,4 +16,4 @@ parser.add_argument("--out", args = parser.parse_args() -import_parts(args.in_, args.out) +create_distributor_search_list(Path(args.in_), Path(args.out)) diff --git a/src/ee/xml/bomFile.py b/src/ee/xml/bomFile.py index 5a78173..2e2b5a7 100644 --- a/src/ee/xml/bomFile.py +++ b/src/ee/xml/bomFile.py @@ -9,15 +9,15 @@ # ('-f', '') # ('--no-dates', '') # ('--no-versions', '') -# ('--one-file-per-xsd', '') # ('--output-directory', 'src/ee/xml') +# ('-o', 'src/ee/xml/bomFile.py') # ('-m', '') # # Command line arguments: # xsd/ee-bom.xsd # # Command line: -# env/bin/generateDS.py -f --no-dates --no-versions --one-file-per-xsd --output-directory="src/ee/xml" -m xsd/ee-bom.xsd +# env/bin/generateDS.py -f --no-dates --no-versions --output-directory="src/ee/xml" -o "src/ee/xml/bomFile.py" -m xsd/ee-bom.xsd # # Current working directory (os.getcwd()): # ee-python @@ -1765,6 +1765,7 @@ class DigikeyDistributorInfo(DistributorInfo): GDSClassesMapping = { 'bom-file': BomFile, + 'part': Part, } diff --git a/src/ee/xml/bom_file_utils.py b/src/ee/xml/bom_file_utils.py index f09a3dd..15f99b2 100644 --- a/src/ee/xml/bom_file_utils.py +++ b/src/ee/xml/bom_file_utils.py @@ -1,14 +1,23 @@ from typing import List, Optional -from ee.xml import bomFile +from ee.xml import bomFile, indexFile __all__ = [ - "part_numbers", + "find_root_tag", "find_pn", "find_dpn", ] +def find_root_tag(root): + tag = next((tag for tag, klass in bomFile.GDSClassesMapping.items() if klass == type(root)), None) + + if tag is not None: + return tag + + return next((tag for tag, klass in indexFile.GDSClassesMapping.items() if klass == type(root))) + + def part_numbers(part: bomFile.Part) -> List[bomFile.PartNumber]: pns = part.part_numbersProp # type: bomFile.PartNumberList diff --git a/src/ee/xml/catalogFile.py b/src/ee/xml/indexFile.py index bda29ae..d460db3 100644 --- a/src/ee/xml/catalogFile.py +++ b/src/ee/xml/indexFile.py @@ -9,15 +9,15 @@ # ('-f', '') # ('--no-dates', '') # ('--no-versions', '') -# ('--one-file-per-xsd', '') # ('--output-directory', 'src/ee/xml') +# ('-o', 'src/ee/xml/indexFile.py') # ('-m', '') # # Command line arguments: -# xsd/ee-catalog.xsd +# xsd/ee-index.xsd # # Command line: -# env/bin/generateDS.py -f --no-dates --no-versions --one-file-per-xsd --output-directory="src/ee/xml" -m xsd/ee-catalog.xsd +# env/bin/generateDS.py -f --no-dates --no-versions --output-directory="src/ee/xml" -o "src/ee/xml/indexFile.py" -m xsd/ee-index.xsd # # Current working directory (os.getcwd()): # ee-python @@ -726,38 +726,38 @@ def _cast(typ, value): # -class CatalogFile(GeneratedsSuper): +class IndexFile(GeneratedsSuper): subclass = None superclass = None - def __init__(self, products=None, **kwargs_): + def __init__(self, files=None, **kwargs_): self.original_tagname_ = None self.parent_object_ = kwargs_.get('parent_object_') - self.products = products + self.files = files def factory(*args_, **kwargs_): if CurrentSubclassModule_ is not None: subclass = getSubclassFromModule_( - CurrentSubclassModule_, CatalogFile) + CurrentSubclassModule_, IndexFile) if subclass is not None: return subclass(*args_, **kwargs_) - if CatalogFile.subclass: - return CatalogFile.subclass(*args_, **kwargs_) + if IndexFile.subclass: + return IndexFile.subclass(*args_, **kwargs_) else: - return CatalogFile(*args_, **kwargs_) + return IndexFile(*args_, **kwargs_) factory = staticmethod(factory) - def get_products(self): - return self.products - def set_products(self, products): - self.products = products - productsProp = property(get_products, set_products) + def get_files(self): + return self.files + def set_files(self, files): + self.files = files + filesProp = property(get_files, set_files) def hasContent_(self): if ( - self.products is not None + self.files is not None ): return True else: return False - def export(self, outfile, level, namespaceprefix_='', namespacedef_='', name_='CatalogFile', pretty_print=True): - imported_ns_def_ = GenerateDSNamespaceDefs_.get('CatalogFile') + def export(self, outfile, level, namespaceprefix_='', namespacedef_='', name_='IndexFile', pretty_print=True): + imported_ns_def_ = GenerateDSNamespaceDefs_.get('IndexFile') if imported_ns_def_ is not None: namespacedef_ = imported_ns_def_ if pretty_print: @@ -769,23 +769,23 @@ class CatalogFile(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_='CatalogFile') + self.exportAttributes(outfile, level, already_processed, namespaceprefix_, name_='IndexFile') if self.hasContent_(): outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespaceprefix_, namespacedef_, name_='CatalogFile', pretty_print=pretty_print) + self.exportChildren(outfile, level + 1, namespaceprefix_, namespacedef_, name_='IndexFile', 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_='CatalogFile'): + def exportAttributes(self, outfile, level, already_processed, namespaceprefix_='', name_='IndexFile'): pass - def exportChildren(self, outfile, level, namespaceprefix_='', namespacedef_='', name_='CatalogFile', fromsubclass_=False, pretty_print=True): + def exportChildren(self, outfile, level, namespaceprefix_='', namespacedef_='', name_='IndexFile', fromsubclass_=False, pretty_print=True): if pretty_print: eol_ = '\n' else: eol_ = '' - if self.products is not None: - self.products.export(outfile, level, namespaceprefix_, namespacedef_='', name_='products', pretty_print=pretty_print) + if self.files is not None: + self.files.export(outfile, level, namespaceprefix_, namespacedef_='', name_='files', pretty_print=pretty_print) def build(self, node): already_processed = set() self.buildAttributes(node, node.attrib, already_processed) @@ -796,46 +796,46 @@ class CatalogFile(GeneratedsSuper): def buildAttributes(self, node, attrs, already_processed): pass def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == 'products': - obj_ = ProductList.factory(parent_object_=self) + if nodeName_ == 'files': + obj_ = FileList.factory(parent_object_=self) obj_.build(child_) - self.products = obj_ - obj_.original_tagname_ = 'products' -# end class CatalogFile + self.files = obj_ + obj_.original_tagname_ = 'files' +# end class IndexFile -class Product(GeneratedsSuper): +class File(GeneratedsSuper): subclass = None superclass = None - def __init__(self, ref=None, **kwargs_): + def __init__(self, path=None, **kwargs_): self.original_tagname_ = None self.parent_object_ = kwargs_.get('parent_object_') - self.ref = ref + self.path = _cast(None, path) def factory(*args_, **kwargs_): if CurrentSubclassModule_ is not None: subclass = getSubclassFromModule_( - CurrentSubclassModule_, Product) + CurrentSubclassModule_, File) if subclass is not None: return subclass(*args_, **kwargs_) - if Product.subclass: - return Product.subclass(*args_, **kwargs_) + if File.subclass: + return File.subclass(*args_, **kwargs_) else: - return Product(*args_, **kwargs_) + return File(*args_, **kwargs_) factory = staticmethod(factory) - def get_ref(self): - return self.ref - def set_ref(self, ref): - self.ref = ref - refProp = property(get_ref, set_ref) + def get_path(self): + return self.path + def set_path(self, path): + self.path = path + pathProp = property(get_path, set_path) def hasContent_(self): if ( - self.ref is not None + ): return True else: return False - def export(self, outfile, level, namespaceprefix_='', namespacedef_='', name_='Product', pretty_print=True): - imported_ns_def_ = GenerateDSNamespaceDefs_.get('Product') + def export(self, outfile, level, namespaceprefix_='', namespacedef_='', name_='File', pretty_print=True): + imported_ns_def_ = GenerateDSNamespaceDefs_.get('File') if imported_ns_def_ is not None: namespacedef_ = imported_ns_def_ if pretty_print: @@ -847,24 +847,19 @@ class Product(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_='Product') + self.exportAttributes(outfile, level, already_processed, namespaceprefix_, name_='File') if self.hasContent_(): outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespaceprefix_, namespacedef_, name_='Product', pretty_print=pretty_print) - showIndent(outfile, level, pretty_print) + self.exportChildren(outfile, level + 1, namespaceprefix_, namespacedef_, name_='File', pretty_print=pretty_print) outfile.write('</%s%s>%s' % (namespaceprefix_, name_, eol_)) else: outfile.write('/>%s' % (eol_, )) - def exportAttributes(self, outfile, level, already_processed, namespaceprefix_='', name_='Product'): + def exportAttributes(self, outfile, level, already_processed, namespaceprefix_='', name_='File'): + if self.path is not None and 'path' not in already_processed: + already_processed.add('path') + outfile.write(' path=%s' % (self.gds_encode(self.gds_format_string(quote_attrib(self.path), input_name='path')), )) + def exportChildren(self, outfile, level, namespaceprefix_='', namespacedef_='', name_='File', fromsubclass_=False, pretty_print=True): pass - def exportChildren(self, outfile, level, namespaceprefix_='', namespacedef_='', name_='Product', fromsubclass_=False, pretty_print=True): - if pretty_print: - eol_ = '\n' - else: - eol_ = '' - if self.ref is not None: - showIndent(outfile, level, pretty_print) - outfile.write('<%sref>%s</%sref>%s' % (namespaceprefix_ , self.gds_encode(self.gds_format_string(quote_xml(self.ref), input_name='ref')), namespaceprefix_ , eol_)) def build(self, node): already_processed = set() self.buildAttributes(node, node.attrib, already_processed) @@ -873,58 +868,58 @@ class Product(GeneratedsSuper): self.buildChildren(child, node, nodeName_) return self def buildAttributes(self, node, attrs, already_processed): - pass + value = find_attr_value_('path', node) + if value is not None and 'path' not in already_processed: + already_processed.add('path') + self.path = value def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == 'ref': - ref_ = child_.text - ref_ = self.gds_validate_string(ref_, node, 'ref') - self.ref = ref_ -# end class Product + pass +# end class File -class ProductList(GeneratedsSuper): +class FileList(GeneratedsSuper): subclass = None superclass = None - def __init__(self, product=None, **kwargs_): + def __init__(self, file=None, **kwargs_): self.original_tagname_ = None self.parent_object_ = kwargs_.get('parent_object_') - if product is None: - self.product = [] + if file is None: + self.file = [] else: - self.product = product + self.file = file def factory(*args_, **kwargs_): if CurrentSubclassModule_ is not None: subclass = getSubclassFromModule_( - CurrentSubclassModule_, ProductList) + CurrentSubclassModule_, FileList) if subclass is not None: return subclass(*args_, **kwargs_) - if ProductList.subclass: - return ProductList.subclass(*args_, **kwargs_) + if FileList.subclass: + return FileList.subclass(*args_, **kwargs_) else: - return ProductList(*args_, **kwargs_) + return FileList(*args_, **kwargs_) factory = staticmethod(factory) - def get_product(self): - return self.product - def set_product(self, product): - self.product = product - def add_product(self, value): - self.product.append(value) - def add_product(self, value): - self.product.append(value) - def insert_product_at(self, index, value): - self.product.insert(index, value) - def replace_product_at(self, index, value): - self.product[index] = value - productProp = property(get_product, set_product) + def get_file(self): + return self.file + def set_file(self, file): + self.file = file + def add_file(self, value): + self.file.append(value) + def add_file(self, value): + self.file.append(value) + def insert_file_at(self, index, value): + self.file.insert(index, value) + def replace_file_at(self, index, value): + self.file[index] = value + fileProp = property(get_file, set_file) def hasContent_(self): if ( - self.product + self.file ): return True else: return False - def export(self, outfile, level, namespaceprefix_='', namespacedef_='', name_='ProductList', pretty_print=True): - imported_ns_def_ = GenerateDSNamespaceDefs_.get('ProductList') + def export(self, outfile, level, namespaceprefix_='', namespacedef_='', name_='FileList', pretty_print=True): + imported_ns_def_ = GenerateDSNamespaceDefs_.get('FileList') if imported_ns_def_ is not None: namespacedef_ = imported_ns_def_ if pretty_print: @@ -936,23 +931,23 @@ class ProductList(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_='ProductList') + self.exportAttributes(outfile, level, already_processed, namespaceprefix_, name_='FileList') if self.hasContent_(): outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespaceprefix_, namespacedef_, name_='ProductList', pretty_print=pretty_print) + self.exportChildren(outfile, level + 1, namespaceprefix_, namespacedef_, name_='FileList', 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_='ProductList'): + def exportAttributes(self, outfile, level, already_processed, namespaceprefix_='', name_='FileList'): pass - def exportChildren(self, outfile, level, namespaceprefix_='', namespacedef_='', name_='ProductList', fromsubclass_=False, pretty_print=True): + def exportChildren(self, outfile, level, namespaceprefix_='', namespacedef_='', name_='FileList', fromsubclass_=False, pretty_print=True): if pretty_print: eol_ = '\n' else: eol_ = '' - for product_ in self.product: - product_.export(outfile, level, namespaceprefix_, namespacedef_='', name_='product', pretty_print=pretty_print) + for file_ in self.file: + file_.export(outfile, level, namespaceprefix_, namespacedef_='', name_='file', pretty_print=pretty_print) def build(self, node): already_processed = set() self.buildAttributes(node, node.attrib, already_processed) @@ -963,15 +958,16 @@ class ProductList(GeneratedsSuper): def buildAttributes(self, node, attrs, already_processed): pass def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): - if nodeName_ == 'product': - obj_ = Product.factory(parent_object_=self) + if nodeName_ == 'file': + obj_ = File.factory(parent_object_=self) obj_.build(child_) - self.product.append(obj_) - obj_.original_tagname_ = 'product' -# end class ProductList + self.file.append(obj_) + obj_.original_tagname_ = 'file' +# end class FileList GDSClassesMapping = { + 'file-index': IndexFile, } @@ -999,8 +995,8 @@ def parse(inFileName, silence=False): rootNode = doc.getroot() rootTag, rootClass = get_root_tag(rootNode) if rootClass is None: - rootTag = 'CatalogFile' - rootClass = CatalogFile + rootTag = 'IndexFile' + rootClass = IndexFile rootObj = rootClass.factory() rootObj.build(rootNode) # Enable Python to collect the space used by the DOM. @@ -1020,8 +1016,8 @@ def parseEtree(inFileName, silence=False): rootNode = doc.getroot() rootTag, rootClass = get_root_tag(rootNode) if rootClass is None: - rootTag = 'CatalogFile' - rootClass = CatalogFile + rootTag = 'IndexFile' + rootClass = IndexFile rootObj = rootClass.factory() rootObj.build(rootNode) # Enable Python to collect the space used by the DOM. @@ -1051,8 +1047,8 @@ def parseString(inString, silence=False): rootNode= parsexmlstring_(inString, parser) rootTag, rootClass = get_root_tag(rootNode) if rootClass is None: - rootTag = 'CatalogFile' - rootClass = CatalogFile + rootTag = 'IndexFile' + rootClass = IndexFile rootObj = rootClass.factory() rootObj.build(rootNode) # Enable Python to collect the space used by the DOM. @@ -1070,15 +1066,15 @@ def parseLiteral(inFileName, silence=False): rootNode = doc.getroot() rootTag, rootClass = get_root_tag(rootNode) if rootClass is None: - rootTag = 'CatalogFile' - rootClass = CatalogFile + rootTag = 'IndexFile' + rootClass = IndexFile rootObj = rootClass.factory() rootObj.build(rootNode) # Enable Python to collect the space used by the DOM. doc = None if not silence: - sys.stdout.write('#from catalogFile import *\n\n') - sys.stdout.write('import catalogFile as model_\n\n') + sys.stdout.write('#from indexFile import *\n\n') + sys.stdout.write('import indexFile as model_\n\n') sys.stdout.write('rootObj = model_.rootClass(\n') rootObj.exportLiteral(sys.stdout, 0, name_=rootTag) sys.stdout.write(')\n') @@ -1099,7 +1095,7 @@ if __name__ == '__main__': __all__ = [ - "CatalogFile", - "Product", - "ProductList" + "File", + "FileList", + "IndexFile" ] diff --git a/xsd/ee-bom.xsd b/xsd/ee-bom.xsd index 16d18bb..a357deb 100644 --- a/xsd/ee-bom.xsd +++ b/xsd/ee-bom.xsd @@ -6,6 +6,7 @@ <xs:attribute name="id" type="xs:string"/> <xs:element name="bom-file" type="BomFile"/> + <xs:element name="part" type="Part"/> <xs:complexType name="BomFile"> <xs:sequence> diff --git a/xsd/ee-catalog.xsd b/xsd/ee-catalog.xsd deleted file mode 100644 index 6da3558..0000000 --- a/xsd/ee-catalog.xsd +++ /dev/null @@ -1,26 +0,0 @@ -<xsd:schema - xmlns:xsd="http://www.w3.org/2001/XMLSchema" - targetNamespace="http://purl.org/ee/bom-file" - xmlns="http://purl.org/ee/bom-file"> - - <xsd:element name="catalog-file" type="CatalogFile"/> - - <xsd:complexType name="CatalogFile"> - <xsd:sequence> - <xsd:element name="products" type="ProductList" minOccurs="0" maxOccurs="1"/> - </xsd:sequence> - </xsd:complexType> - - <xsd:complexType name="Product"> - <xsd:sequence> - <xsd:element name="ref" type="xsd:string"/> - </xsd:sequence> - </xsd:complexType> - - <xsd:complexType name="ProductList"> - <xsd:sequence> - <xsd:element name="product" type="Product" maxOccurs="unbounded"/> - </xsd:sequence> - </xsd:complexType> - -</xsd:schema> diff --git a/xsd/ee-index.xsd b/xsd/ee-index.xsd new file mode 100644 index 0000000..21dbeb2 --- /dev/null +++ b/xsd/ee-index.xsd @@ -0,0 +1,24 @@ +<xs:schema + xmlns:xs="http://www.w3.org/2001/XMLSchema" + targetNamespace="http://purl.org/ee/bom-file" + xmlns="http://purl.org/ee/bom-file"> + + <xs:element name="file-index" type="IndexFile"/> + + <xs:complexType name="IndexFile"> + <xs:sequence> + <xs:element name="files" type="FileList" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + + <xs:complexType name="File"> + <xs:attribute name="path" use="required" type="xs:string"/> + </xs:complexType> + + <xs:complexType name="FileList"> + <xs:sequence> + <xs:element name="file" type="File" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + +</xs:schema> |