From bd33b778f17e5751a14160baeae6cdcd41ce1ca7 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Thu, 15 Aug 2019 12:01:17 +0200 Subject: datasheet: wip --- src/ee/digikey/__init__.py | 9 +- src/ee/digikey/search_parts.py | 11 +- src/ee/tools/part_download_datasheets.py | 117 +++++++++++++++ src/ee/tools/templates/build.ninja.j2 | 11 +- src/ee/xml/types.py | 248 +++++++++++++++++++++---------- src/ee/xml/uris.py | 4 + xsd/ee.xsd | 3 +- 7 files changed, 319 insertions(+), 84 deletions(-) create mode 100644 src/ee/tools/part_download_datasheets.py diff --git a/src/ee/digikey/__init__.py b/src/ee/digikey/__init__.py index 15eb5e6..b46ba85 100644 --- a/src/ee/digikey/__init__.py +++ b/src/ee/digikey/__init__.py @@ -126,8 +126,9 @@ class PriceBreak(object): class Document(object): - def __init__(self, kind: str, title: str, url: str): - self.kind = kind + def __init__(self, section: str, classes: List[str], title: str, url: str): + self.section = section + self.classes = classes self.title = title self.url = url @@ -464,7 +465,9 @@ class DigikeyParser(object): if href.startswith("//"): href = "https:" + href - docs.append(Document(kind, title, href)) + classes = [cls[3:].lower() for cls in a.get("class", "").split(" ") if cls.startswith("lnk")] + + docs.append(Document(kind, classes, title, href)) return docs diff --git a/src/ee/digikey/search_parts.py b/src/ee/digikey/search_parts.py index a1236bb..c0da731 100644 --- a/src/ee/digikey/search_parts.py +++ b/src/ee/digikey/search_parts.py @@ -6,7 +6,7 @@ from ee.db import ObjDb from ee.digikey import Digikey, DigikeyParser, DigikeyClient, SearchResponseTypes, DigikeyProduct, DigikeyStore from ee.part import PartDb, load_db, save_db, Part from ee.tools import mk_parents -from ee.xml import types +from ee.xml import types, uris from ee.xml.uris import make_digikey_fact_key __all__ = ["search_parts"] @@ -157,8 +157,13 @@ def resolved(supplier, p: DigikeyProduct) -> Part: part.get_links().append(types.Link(url=p.url, relation="canonical", media_type="text/html")) for d in p.documents: - title = "{}: {}".format(d.kind, d.title) - part.get_links().append(types.Link(url=d.url, relation="http://purl.org/ee/link-relation#documentation", + title = "{}: {}".format(d.section, d.title) + relations = ["http://purl.org/ee/link-relation#documentation"] + + if "datasheet" in d.classes: + relations.append(uris.make_link_rel("datasheet")) + + part.get_links().append(types.Link(url=d.url, relation=" ".join(relations), media_type="text/html", title=title)) part.add_spn(p.part_number) diff --git a/src/ee/tools/part_download_datasheets.py b/src/ee/tools/part_download_datasheets.py new file mode 100644 index 0000000..1689502 --- /dev/null +++ b/src/ee/tools/part_download_datasheets.py @@ -0,0 +1,117 @@ +import argparse +import time +from pathlib import Path + +import requests +from selenium import webdriver +from selenium.webdriver.support.wait import WebDriverWait + +from ee.part import Part, load_db +from ee.xml import uris + + +class Job(object): + def __init__(self, url, title): + self.url = url + self.title = title + + self.path = Path(url).name + + +def work(in_path: Path, out_dir: Path, index_path: Path): + in_parts = load_db(in_path) + + ds_rel = uris.make_link_rel("datasheet") + + jobs = {} + for xml in in_parts.iterparts(): + part = Part(xml) + + for link in part.get_links(): + rels = link.relationProp.split(" ") + if ds_rel not in rels: + continue + + jobs[link.urlProp] = (Job(link.urlProp, link.titleProp)) + + options = webdriver.ChromeOptions() + print("out_dir={}".format(out_dir)) + options.add_experimental_option("prefs", { + "download.default_directory": str(out_dir), + }) + driver = webdriver.Chrome(options=options) + + # FILE_SAVER_MIN_JS_URL = "https://raw.githubusercontent.com/eligrey/FileSaver.js/1.2.1/FileSaver.js" + FILE_SAVER_MIN_JS_URL = "https://raw.githubusercontent.com/eligrey/FileSaver.js/v2.0.2/dist/FileSaver.js" + file_saver_min_js = requests.get(FILE_SAVER_MIN_JS_URL).text + + # print("---------------------- file_saver_min_js ----------------------") + # print(file_saver_min_js) + # print("---------------------- file_saver_min_js ----------------------") + driver.execute_script(file_saver_min_js) + + for j in jobs.values(): + print("Fetching {}".format(j.url)) + + driver.execute_script(''' + window.done = false; + var args = arguments; + function work() { + console.log("WORK"); + return fetch(args[0], { + "credentials": "same-origin", + "referrerPolicy": "no-referrer-when-downgrade", + "body": null, + "method": "HEAD", + "mode": "no-cors" + }).then(resp => { + window.resp = resp; + return resp; + }); + } + setTimeout(work, 2000); + + return fetch(arguments[0], { + "credentials": "same-origin", + "referrerPolicy": "no-referrer-when-downgrade", + "body": null, + "method": "GET", + "mode": "no-cors" + }).then(resp => { + return resp.blob(); + }).then(blob => { + saveAs(blob, arguments[1]); + window.done = true; + }); + ''', j.url, j.path) + + timeout = 5 * 1000 + done = WebDriverWait(driver, timeout).until(lambda d: d.execute_script('return window.done')) + print("done={}".format(done)) + + time.sleep(1000) + + break + + with index_path.open("w") as f: + print("", file=f) + + +parser = argparse.ArgumentParser() + +parser.add_argument("--in", + dest="in_path", + required=True, + metavar="PART DB") + +parser.add_argument("--destination", + required=True, + metavar="DIRECTORY") + +parser.add_argument("--index", + required=True, + metavar="INDEX") + +args = parser.parse_args() + +work(Path(args.in_path), Path(args.destination), Path(args.index)) diff --git a/src/ee/tools/templates/build.ninja.j2 b/src/ee/tools/templates/build.ninja.j2 index c68f505..492363d 100644 --- a/src/ee/tools/templates/build.ninja.j2 +++ b/src/ee/tools/templates/build.ninja.j2 @@ -1,4 +1,5 @@ {% set reports=[] -%} +{% set datasheets=[] -%} ee = {{ ee }} uuid = {{ project.uuid }} public_dir = {{ project.public_dir }} @@ -49,6 +50,9 @@ rule part-apply-souffle-post rule part-find-requirements command = $ee part-find-requirements {{ log }} --in $in --out $out $report +rule part-download-datasheets + command = $ee part-download-datasheets --in $in --destination $dir --index $out + rule part-validate-parts command = $ee part-validate-parts {{ log }} --bom $bom --sch $sch --report $out --part-db $part_dbs @@ -135,6 +139,10 @@ build $public_dir/{{ s.key }}/pn-part-search-list.xml: pn-part-search-list $publ build $public_dir/{{ s.key }}/downloaded.xml | $public_dir/{{ s.key }}/downloaded.rst: {{ s.key }}-search-parts $public_dir/{{ s.key }}/pn-part-search-list.xml {%- set reports=reports+["$report_dir/" + s.key + "/downloaded.rst"] %} +build $public_dir/{{ s.key }}/datasheets.xml: part-download-datasheets $public_dir/{{ s.key }}/downloaded.xml + dir = $public_dir/{{ s.key }}/datasheets +{%- set _=datasheets.append("$public_dir/" + s.key + "/datasheets.xml") %} + {# build $public_dir/{{ s.key }}/parts.xml: part-apply-function $public_dir/{{ s.key }}/downloaded.xml execution = {{ s.key }} @@ -206,6 +214,7 @@ default ee.ninja # Reports build ee-reports: phony {{ " ".join(reports) }} +build ee-download-datasheets: phony {{ " ".join(datasheets) }} 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 +build ee-all: phony ee-reports ee-download-datasheets ee-part-dbs ee-orders diff --git a/src/ee/xml/types.py b/src/ee/xml/types.py index 9409cf2..afc7e72 100644 --- a/src/ee/xml/types.py +++ b/src/ee/xml/types.py @@ -3,7 +3,7 @@ # # Generated by generateDS.py. -# Python 3.7.3rc1 (default, Mar 13 2019, 11:01:15) [GCC 8.3.0] +# Python 3.7.3 (default, Apr 3 2019, 05:39:12) [GCC 8.3.0] # # Command line options: # ('-f', '') @@ -23,11 +23,13 @@ # ee-python # +import os +import sys +import re as re_ import base64 import datetime as datetime_ -import re as re_ -import sys - +import warnings as warnings_ +import decimal as decimal_ try: from lxml import etree as etree_ except ImportError: @@ -50,6 +52,11 @@ def parsexml_(infile, parser=None, **kwargs): except AttributeError: # fallback to xml.etree parser = etree_.XMLParser() + try: + if isinstance(infile, os.PathLike): + infile = os.path.join(infile) + except AttributeError: + pass doc = etree_.parse(infile, parser=parser, **kwargs) return doc @@ -74,7 +81,7 @@ def parsexmlstring_(instring, parser=None, **kwargs): # definitions. The export method for any class for which there is # a namespace prefix definition, will export that definition in the # XML representation of that element. See the export method of -# any generated element type class for a example of the use of this +# any generated element type class for an example of the use of this # table. # A sample table is: # @@ -85,11 +92,39 @@ def parsexmlstring_(instring, parser=None, **kwargs): # "ElementtypeB": "http://www.xxx.com/namespaceB", # } # +# Additionally, the generatedsnamespaces module can contain a python +# dictionary named GenerateDSNamespaceTypePrefixes that associates element +# types with the namespace prefixes that are to be added to the +# "xsi:type" attribute value. See the exportAttributes method of +# any generated element type and the generation of "xsi:type" for an +# example of the use of this table. +# An example table: +# +# # File: generatedsnamespaces.py +# +# GenerateDSNamespaceTypePrefixes = { +# "ElementtypeC": "aaa:", +# "ElementtypeD": "bbb:", +# } +# try: from generatedsnamespaces import GenerateDSNamespaceDefs as GenerateDSNamespaceDefs_ except ImportError: GenerateDSNamespaceDefs_ = {} +try: + from generatedsnamespaces import GenerateDSNamespaceTypePrefixes as GenerateDSNamespaceTypePrefixes_ +except ImportError: + GenerateDSNamespaceTypePrefixes_ = {} + +# +# The super-class for enum types +# + +try: + from enum import Enum +except ImportError: + Enum = object # # The root super-class for element type classes @@ -116,6 +151,8 @@ except ImportError as exp: return None def gds_format_string(self, input_data, input_name=''): return input_data + def gds_parse_string(self, input_data, node=None, input_name=''): + return input_data def gds_validate_string(self, input_data, node=None, input_name=''): if not input_data: return '' @@ -127,6 +164,12 @@ except ImportError as exp: return input_data def gds_format_integer(self, input_data, input_name=''): return '%d' % input_data + def gds_parse_integer(self, input_data, node=None, input_name=''): + try: + ival = int(input_data) + except (TypeError, ValueError) as exp: + raise_parse_error(node, 'requires integer: %s' % exp) + return ival def gds_validate_integer(self, input_data, node=None, input_name=''): return input_data def gds_format_integer_list(self, input_data, input_name=''): @@ -142,8 +185,18 @@ except ImportError as exp: return values def gds_format_float(self, input_data, input_name=''): return ('%.15f' % input_data).rstrip('0') + def gds_parse_float(self, input_data, node=None, input_name=''): + try: + fval_ = float(input_data) + except (TypeError, ValueError) as exp: + raise_parse_error(node, 'requires float or double: %s' % exp) + return fval_ def gds_validate_float(self, input_data, node=None, input_name=''): - return input_data + try: + value = float(input_data) + except (TypeError, ValueError): + raise_parse_error(node, 'Requires sequence of floats') + return value def gds_format_float_list(self, input_data, input_name=''): return '%s' % ' '.join(input_data) def gds_validate_float_list( @@ -155,8 +208,39 @@ except ImportError as exp: except (TypeError, ValueError): raise_parse_error(node, 'Requires sequence of floats') return values + def gds_format_decimal(self, input_data, input_name=''): + return ('%0.10f' % input_data).rstrip('0') + def gds_parse_decimal(self, input_data, node=None, input_name=''): + try: + decimal_.Decimal(input_data) + except (TypeError, ValueError): + raise_parse_error(node, 'Requires decimal value') + return input_data + def gds_validate_decimal(self, input_data, node=None, input_name=''): + try: + value = decimal_.Decimal(input_data) + except (TypeError, ValueError): + raise_parse_error(node, 'Requires decimal value') + return value + def gds_format_decimal_list(self, input_data, input_name=''): + return '%s' % ' '.join(input_data) + def gds_validate_decimal_list( + self, input_data, node=None, input_name=''): + values = input_data.split() + for value in values: + try: + decimal_.Decimal(value) + except (TypeError, ValueError): + raise_parse_error(node, 'Requires sequence of decimal values') + return values def gds_format_double(self, input_data, input_name=''): return '%e' % input_data + def gds_parse_double(self, input_data, node=None, input_name=''): + try: + fval_ = float(input_data) + except (TypeError, ValueError) as exp: + raise_parse_error(node, 'requires float or double: %s' % exp) + return fval_ def gds_validate_double(self, input_data, node=None, input_name=''): return input_data def gds_format_double_list(self, input_data, input_name=''): @@ -172,6 +256,14 @@ except ImportError as exp: return values def gds_format_boolean(self, input_data, input_name=''): return ('%s' % input_data).lower() + def gds_parse_boolean(self, input_data, node=None, input_name=''): + if input_data in ('true', '1'): + bval = True + elif input_data in ('false', '0'): + bval = False + else: + raise_parse_error(node, 'requires boolean') + return bval def gds_validate_boolean(self, input_data, node=None, input_name=''): return input_data def gds_format_boolean_list(self, input_data, input_name=''): @@ -563,7 +655,8 @@ class GDSParseError(Exception): def raise_parse_error(node, msg): - msg = '%s (element %s/line %d)' % (msg, node.tag, node.sourceline, ) + if node is not None: + msg = '%s (element %s/line %d)' % (msg, node.tag, node.sourceline, ) raise GDSParseError(msg) @@ -779,7 +872,7 @@ class PartDb(GeneratedsSuper): self.exportAttributes(outfile, level, already_processed, namespaceprefix_, name_='PartDb') if self.hasContent_(): outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespaceprefix_, namespacedef_, name_='PartDb', pretty_print=pretty_print) + self.exportChildren(outfile, level + 1, '', namespacedef_, name_='PartDb', pretty_print=pretty_print) showIndent(outfile, level, pretty_print) outfile.write('%s' % (namespaceprefix_, name_, eol_)) else: @@ -905,7 +998,7 @@ class Part(GeneratedsSuper): self.exportAttributes(outfile, level, already_processed, namespaceprefix_, name_='Part') if self.hasContent_(): outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespaceprefix_, namespacedef_, name_='Part', pretty_print=pretty_print) + self.exportChildren(outfile, level + 1, '', namespacedef_, name_='Part', pretty_print=pretty_print) showIndent(outfile, level, pretty_print) outfile.write('%s' % (namespaceprefix_, name_, eol_)) else: @@ -947,13 +1040,15 @@ class Part(GeneratedsSuper): self.uri = value def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): if nodeName_ == 'supplier': - supplier_ = child_.text - supplier_ = self.gds_validate_string(supplier_, node, 'supplier') - self.supplier = supplier_ + value_ = child_.text + value_ = self.gds_parse_string(value_, node, 'supplier') + value_ = self.gds_validate_string(value_, node, 'supplier') + self.supplier = value_ elif nodeName_ == 'description': - description_ = child_.text - description_ = self.gds_validate_string(description_, node, 'description') - self.description = description_ + value_ = child_.text + value_ = self.gds_parse_string(value_, node, 'description') + value_ = self.gds_validate_string(value_, node, 'description') + self.description = value_ elif nodeName_ == 'links': obj_ = LinkList.factory(parent_object_=self) obj_.build(child_) @@ -1004,8 +1099,6 @@ class PartList(GeneratedsSuper): self.part = part def add_part(self, value): self.part.append(value) - def add_part(self, value): - self.part.append(value) def insert_part_at(self, index, value): self.part.insert(index, value) def replace_part_at(self, index, value): @@ -1034,7 +1127,7 @@ class PartList(GeneratedsSuper): self.exportAttributes(outfile, level, already_processed, namespaceprefix_, name_='PartList') if self.hasContent_(): outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespaceprefix_, namespacedef_, name_='PartList', pretty_print=pretty_print) + self.exportChildren(outfile, level + 1, '', namespacedef_, name_='PartList', pretty_print=pretty_print) showIndent(outfile, level, pretty_print) outfile.write('%s' % (namespaceprefix_, name_, eol_)) else: @@ -1112,7 +1205,7 @@ class PartReference(GeneratedsSuper): self.exportAttributes(outfile, level, already_processed, namespaceprefix_, name_='PartReference') if self.hasContent_(): outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespaceprefix_, namespacedef_, name_='PartReference', pretty_print=pretty_print) + self.exportChildren(outfile, level + 1, '', namespacedef_, name_='PartReference', pretty_print=pretty_print) showIndent(outfile, level, pretty_print) outfile.write('%s' % (namespaceprefix_, name_, eol_)) else: @@ -1138,9 +1231,10 @@ class PartReference(GeneratedsSuper): pass def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): if nodeName_ == 'part-uri': - part_uri_ = child_.text - part_uri_ = self.gds_validate_string(part_uri_, node, 'part_uri') - self.part_uri = part_uri_ + value_ = child_.text + value_ = self.gds_parse_string(value_, node, 'part_uri') + value_ = self.gds_validate_string(value_, node, 'part_uri') + self.part_uri = value_ # end class PartReference @@ -1190,7 +1284,7 @@ class PartNumber(GeneratedsSuper): self.exportAttributes(outfile, level, already_processed, namespaceprefix_, name_='PartNumber') if self.hasContent_(): outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespaceprefix_, namespacedef_, name_='PartNumber', pretty_print=pretty_print) + self.exportChildren(outfile, level + 1, '', namespacedef_, name_='PartNumber', pretty_print=pretty_print) showIndent(outfile, level, pretty_print) outfile.write('%s' % (namespaceprefix_, name_, eol_)) else: @@ -1217,6 +1311,7 @@ class PartNumber(GeneratedsSuper): def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): if nodeName_ == 'value': value_ = child_.text + value_ = self.gds_parse_string(value_, node, 'value') value_ = self.gds_validate_string(value_, node, 'value') self.value = value_ # end class PartNumber @@ -1268,7 +1363,7 @@ class SupplierPartNumber(GeneratedsSuper): 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) + self.exportChildren(outfile, level + 1, '', namespacedef_, name_='SupplierPartNumber', pretty_print=pretty_print) showIndent(outfile, level, pretty_print) outfile.write('%s' % (namespaceprefix_, name_, eol_)) else: @@ -1295,6 +1390,7 @@ class SupplierPartNumber(GeneratedsSuper): def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): if nodeName_ == 'value': value_ = child_.text + value_ = self.gds_parse_string(value_, node, 'value') value_ = self.gds_validate_string(value_, node, 'value') self.value = value_ # end class SupplierPartNumber @@ -1346,7 +1442,7 @@ class SchematicReference(GeneratedsSuper): 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) + self.exportChildren(outfile, level + 1, '', namespacedef_, name_='SchematicReference', pretty_print=pretty_print) showIndent(outfile, level, pretty_print) outfile.write('%s' % (namespaceprefix_, name_, eol_)) else: @@ -1372,9 +1468,10 @@ class SchematicReference(GeneratedsSuper): 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_ + value_ = child_.text + value_ = self.gds_parse_string(value_, node, 'reference') + value_ = self.gds_validate_string(value_, node, 'reference') + self.reference = value_ # end class SchematicReference @@ -1421,8 +1518,6 @@ class ReferenceList(GeneratedsSuper): self.part_reference = part_reference def add_part_reference(self, value): self.part_reference.append(value) - def add_part_reference(self, value): - self.part_reference.append(value) def insert_part_reference_at(self, index, value): self.part_reference.insert(index, value) def replace_part_reference_at(self, index, value): @@ -1434,8 +1529,6 @@ class ReferenceList(GeneratedsSuper): 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): @@ -1447,8 +1540,6 @@ class ReferenceList(GeneratedsSuper): self.part_number = part_number def add_part_number(self, value): self.part_number.append(value) - def add_part_number(self, value): - self.part_number.append(value) def insert_part_number_at(self, index, value): self.part_number.insert(index, value) def replace_part_number_at(self, index, value): @@ -1460,8 +1551,6 @@ class ReferenceList(GeneratedsSuper): 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): @@ -1473,8 +1562,6 @@ class ReferenceList(GeneratedsSuper): self.description = description def add_description(self, value): self.description.append(value) - def add_description(self, value): - self.description.append(value) def insert_description_at(self, index, value): self.description.insert(index, value) def replace_description_at(self, index, value): @@ -1507,7 +1594,7 @@ class ReferenceList(GeneratedsSuper): self.exportAttributes(outfile, level, already_processed, namespaceprefix_, name_='ReferenceList') if self.hasContent_(): outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespaceprefix_, namespacedef_, name_='ReferenceList', pretty_print=pretty_print) + self.exportChildren(outfile, level + 1, '', namespacedef_, name_='ReferenceList', pretty_print=pretty_print) showIndent(outfile, level, pretty_print) outfile.write('%s' % (namespaceprefix_, name_, eol_)) else: @@ -1561,9 +1648,10 @@ class ReferenceList(GeneratedsSuper): self.supplier_part_number.append(obj_) obj_.original_tagname_ = 'supplier-part-number' elif nodeName_ == 'description': - description_ = child_.text - description_ = self.gds_validate_string(description_, node, 'description') - self.description.append(description_) + value_ = child_.text + value_ = self.gds_parse_string(value_, node, 'description') + value_ = self.gds_validate_string(value_, node, 'description') + self.description.append(value_) # end class ReferenceList @@ -1627,7 +1715,7 @@ class Fact(GeneratedsSuper): self.exportAttributes(outfile, level, already_processed, namespaceprefix_, name_='Fact') if self.hasContent_(): outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespaceprefix_, namespacedef_, name_='Fact', pretty_print=pretty_print) + self.exportChildren(outfile, level + 1, '', namespacedef_, name_='Fact', pretty_print=pretty_print) showIndent(outfile, level, pretty_print) outfile.write('%s' % (namespaceprefix_, name_, eol_)) else: @@ -1659,15 +1747,18 @@ class Fact(GeneratedsSuper): pass def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): if nodeName_ == 'key': - key_ = child_.text - key_ = self.gds_validate_string(key_, node, 'key') - self.key = key_ + value_ = child_.text + value_ = self.gds_parse_string(value_, node, 'key') + value_ = self.gds_validate_string(value_, node, 'key') + self.key = value_ elif nodeName_ == 'label': - label_ = child_.text - label_ = self.gds_validate_string(label_, node, 'label') - self.label = label_ + value_ = child_.text + value_ = self.gds_parse_string(value_, node, 'label') + value_ = self.gds_validate_string(value_, node, 'label') + self.label = value_ elif nodeName_ == 'value': value_ = child_.text + value_ = self.gds_parse_string(value_, node, 'value') value_ = self.gds_validate_string(value_, node, 'value') self.value = value_ # end class Fact @@ -1700,8 +1791,6 @@ class FactList(GeneratedsSuper): self.fact = fact def add_fact(self, value): self.fact.append(value) - def add_fact(self, value): - self.fact.append(value) def insert_fact_at(self, index, value): self.fact.insert(index, value) def replace_fact_at(self, index, value): @@ -1730,7 +1819,7 @@ class FactList(GeneratedsSuper): self.exportAttributes(outfile, level, already_processed, namespaceprefix_, name_='FactList') if self.hasContent_(): outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespaceprefix_, namespacedef_, name_='FactList', pretty_print=pretty_print) + self.exportChildren(outfile, level + 1, '', namespacedef_, name_='FactList', pretty_print=pretty_print) showIndent(outfile, level, pretty_print) outfile.write('%s' % (namespaceprefix_, name_, eol_)) else: @@ -1814,12 +1903,12 @@ class Amount(GeneratedsSuper): self.exportAttributes(outfile, level, already_processed, namespaceprefix_, name_='Amount') if self.hasContent_(): outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespaceprefix_, namespacedef_, name_='Amount', pretty_print=pretty_print) + self.exportChildren(outfile, level + 1, '', namespacedef_, name_='Amount', pretty_print=pretty_print) outfile.write('%s' % (namespaceprefix_, name_, eol_)) else: outfile.write('/>%s' % (eol_, )) def exportAttributes(self, outfile, level, already_processed, namespaceprefix_='', name_='Amount'): - if self.value is not None and 'value' not in already_processed: + if 'value' not in already_processed: already_processed.add('value') outfile.write(' value=%s' % (self.gds_encode(self.gds_format_string(quote_attrib(self.value), input_name='value')), )) if self.currency is not None and 'currency' not in already_processed: @@ -1901,7 +1990,7 @@ class PriceBreak(GeneratedsSuper): self.exportAttributes(outfile, level, already_processed, namespaceprefix_, name_='PriceBreak') if self.hasContent_(): outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespaceprefix_, namespacedef_, name_='PriceBreak', pretty_print=pretty_print) + self.exportChildren(outfile, level + 1, '', namespacedef_, name_='PriceBreak', pretty_print=pretty_print) showIndent(outfile, level, pretty_print) outfile.write('%s' % (namespaceprefix_, name_, eol_)) else: @@ -1929,9 +2018,10 @@ class PriceBreak(GeneratedsSuper): pass def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): if nodeName_ == 'quantity': - quantity_ = child_.text - quantity_ = self.gds_validate_string(quantity_, node, 'quantity') - self.quantity = quantity_ + value_ = child_.text + value_ = self.gds_parse_string(value_, node, 'quantity') + value_ = self.gds_validate_string(value_, node, 'quantity') + self.quantity = value_ elif nodeName_ == 'amount': obj_ = Amount.factory(parent_object_=self) obj_.build(child_) @@ -1967,8 +2057,6 @@ class PriceBreakList(GeneratedsSuper): self.price_break = price_break def add_price_break(self, value): self.price_break.append(value) - def add_price_break(self, value): - self.price_break.append(value) def insert_price_break_at(self, index, value): self.price_break.insert(index, value) def replace_price_break_at(self, index, value): @@ -1997,7 +2085,7 @@ class PriceBreakList(GeneratedsSuper): self.exportAttributes(outfile, level, already_processed, namespaceprefix_, name_='PriceBreakList') if self.hasContent_(): outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespaceprefix_, namespacedef_, name_='PriceBreakList', pretty_print=pretty_print) + self.exportChildren(outfile, level + 1, '', namespacedef_, name_='PriceBreakList', pretty_print=pretty_print) showIndent(outfile, level, pretty_print) outfile.write('%s' % (namespaceprefix_, name_, eol_)) else: @@ -2032,13 +2120,14 @@ class PriceBreakList(GeneratedsSuper): class Link(GeneratedsSuper): subclass = None superclass = None - def __init__(self, url=None, relation=None, media_type=None, title=None, **kwargs_): + def __init__(self, url=None, relation=None, media_type=None, title=None, cache_url=None, **kwargs_): self.original_tagname_ = None self.parent_object_ = kwargs_.get('parent_object_') self.url = _cast(None, url) self.relation = _cast(None, relation) self.media_type = _cast(None, media_type) self.title = _cast(None, title) + self.cache_url = _cast(None, cache_url) def factory(*args_, **kwargs_): if CurrentSubclassModule_ is not None: subclass = getSubclassFromModule_( @@ -2070,6 +2159,11 @@ class Link(GeneratedsSuper): def set_title(self, title): self.title = title titleProp = property(get_title, set_title) + def get_cache_url(self): + return self.cache_url + def set_cache_url(self, cache_url): + self.cache_url = cache_url + cache_urlProp = property(get_cache_url, set_cache_url) def hasContent_(self): if ( @@ -2093,7 +2187,7 @@ class Link(GeneratedsSuper): self.exportAttributes(outfile, level, already_processed, namespaceprefix_, name_='Link') if self.hasContent_(): outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespaceprefix_, namespacedef_, name_='Link', pretty_print=pretty_print) + self.exportChildren(outfile, level + 1, '', namespacedef_, name_='Link', pretty_print=pretty_print) outfile.write('%s' % (namespaceprefix_, name_, eol_)) else: outfile.write('/>%s' % (eol_, )) @@ -2110,6 +2204,9 @@ class Link(GeneratedsSuper): if self.title is not None and 'title' not in already_processed: already_processed.add('title') outfile.write(' title=%s' % (self.gds_encode(self.gds_format_string(quote_attrib(self.title), input_name='title')), )) + if self.cache_url is not None and 'cache_url' not in already_processed: + already_processed.add('cache_url') + outfile.write(' cache-url=%s' % (self.gds_encode(self.gds_format_string(quote_attrib(self.cache_url), input_name='cache-url')), )) def exportChildren(self, outfile, level, namespaceprefix_='', namespacedef_='', name_='Link', fromsubclass_=False, pretty_print=True): pass def build(self, node): @@ -2136,6 +2233,10 @@ class Link(GeneratedsSuper): if value is not None and 'title' not in already_processed: already_processed.add('title') self.title = value + value = find_attr_value_('cache-url', node) + if value is not None and 'cache-url' not in already_processed: + already_processed.add('cache-url') + self.cache_url = value def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): pass # end class Link @@ -2168,8 +2269,6 @@ class LinkList(GeneratedsSuper): self.link = link def add_link(self, value): self.link.append(value) - def add_link(self, value): - self.link.append(value) def insert_link_at(self, index, value): self.link.insert(index, value) def replace_link_at(self, index, value): @@ -2198,7 +2297,7 @@ class LinkList(GeneratedsSuper): self.exportAttributes(outfile, level, already_processed, namespaceprefix_, name_='LinkList') if self.hasContent_(): outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespaceprefix_, namespacedef_, name_='LinkList', pretty_print=pretty_print) + self.exportChildren(outfile, level + 1, '', namespacedef_, name_='LinkList', pretty_print=pretty_print) showIndent(outfile, level, pretty_print) outfile.write('%s' % (namespaceprefix_, name_, eol_)) else: @@ -2290,7 +2389,7 @@ class AssemblyPart(GeneratedsSuper): self.exportAttributes(outfile, level, already_processed, namespaceprefix_, name_='AssemblyPart') if self.hasContent_(): outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespaceprefix_, namespacedef_, name_='AssemblyPart', pretty_print=pretty_print) + self.exportChildren(outfile, level + 1, '', namespacedef_, name_='AssemblyPart', pretty_print=pretty_print) showIndent(outfile, level, pretty_print) outfile.write('%s' % (namespaceprefix_, name_, eol_)) else: @@ -2326,11 +2425,8 @@ class AssemblyPart(GeneratedsSuper): obj_.original_tagname_ = 'references' elif nodeName_ == 'count' and child_.text: sval_ = child_.text - try: - fval_ = float(sval_) - except (TypeError, ValueError) as exp: - raise_parse_error(child_, 'requires float or double: %s' % exp) - fval_ = self.gds_validate_float(fval_, node, 'count') + fval_ = self.gds_parse_double(sval_, node, 'count') + fval_ = self.gds_validate_double(fval_, node, 'count') self.count = fval_ elif nodeName_ == 'sub-parts': obj_ = AssemblyPartList.factory(parent_object_=self) @@ -2367,8 +2463,6 @@ class AssemblyPartList(GeneratedsSuper): self.assembly_part = assembly_part def add_assembly_part(self, value): self.assembly_part.append(value) - def add_assembly_part(self, value): - self.assembly_part.append(value) def insert_assembly_part_at(self, index, value): self.assembly_part.insert(index, value) def replace_assembly_part_at(self, index, value): @@ -2397,7 +2491,7 @@ class AssemblyPartList(GeneratedsSuper): self.exportAttributes(outfile, level, already_processed, namespaceprefix_, name_='AssemblyPartList') if self.hasContent_(): outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespaceprefix_, namespacedef_, name_='AssemblyPartList', pretty_print=pretty_print) + self.exportChildren(outfile, level + 1, '', namespacedef_, name_='AssemblyPartList', pretty_print=pretty_print) showIndent(outfile, level, pretty_print) outfile.write('%s' % (namespaceprefix_, name_, eol_)) else: @@ -2475,7 +2569,7 @@ class Assembly(GeneratedsSuper): self.exportAttributes(outfile, level, already_processed, namespaceprefix_, name_='Assembly') if self.hasContent_(): outfile.write('>%s' % (eol_, )) - self.exportChildren(outfile, level + 1, namespaceprefix_, namespacedef_, name_='Assembly', pretty_print=pretty_print) + self.exportChildren(outfile, level + 1, '', namespacedef_, name_='Assembly', pretty_print=pretty_print) showIndent(outfile, level, pretty_print) outfile.write('%s' % (namespaceprefix_, name_, eol_)) else: @@ -2635,6 +2729,8 @@ if __name__ == '__main__': #import pdb; pdb.set_trace() main() +RenameMappings_ = { +} __all__ = [ "Amount", diff --git a/src/ee/xml/uris.py b/src/ee/xml/uris.py index 97c3fa3..7095da3 100644 --- a/src/ee/xml/uris.py +++ b/src/ee/xml/uris.py @@ -16,6 +16,10 @@ MOUNTING_HOLE = "http://purl.org/ee/part-type#mounting-hole" _DIGIKEY_FACT_KEY_PREFIX = "http://purl.org/ee/digikey-fact-key#" +def make_link_rel(cls): + return "http://purl.org/ee/link-rel#{}".format(cls) + + def make_digikey_fact_key(key: int) -> str: return _DIGIKEY_FACT_KEY_PREFIX + str(key) diff --git a/xsd/ee.xsd b/xsd/ee.xsd index 6b7260b..87f072d 100644 --- a/xsd/ee.xsd +++ b/xsd/ee.xsd @@ -29,7 +29,7 @@ TODO: rename 'id' to 'url'. + > @@ -134,6 +134,7 @@ TODO: rename 'id' to 'url'. + -- cgit v1.2.3