aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrygve Laugstøl <trygvis@inamo.no>2019-08-15 12:01:17 +0200
committerTrygve Laugstøl <trygvis@inamo.no>2019-08-15 12:01:17 +0200
commitbd33b778f17e5751a14160baeae6cdcd41ce1ca7 (patch)
tree93b49f405703991bd54624f77316e64ff8e86d1a
parentbab23db8bb13832ea326af5e1a847640ccb04cce (diff)
downloadee-python-bd33b778f17e5751a14160baeae6cdcd41ce1ca7.tar.gz
ee-python-bd33b778f17e5751a14160baeae6cdcd41ce1ca7.tar.bz2
ee-python-bd33b778f17e5751a14160baeae6cdcd41ce1ca7.tar.xz
ee-python-bd33b778f17e5751a14160baeae6cdcd41ce1ca7.zip
datasheet: wip
-rw-r--r--src/ee/digikey/__init__.py9
-rw-r--r--src/ee/digikey/search_parts.py11
-rw-r--r--src/ee/tools/part_download_datasheets.py117
-rw-r--r--src/ee/tools/templates/build.ninja.j211
-rw-r--r--src/ee/xml/types.py248
-rw-r--r--src/ee/xml/uris.py4
-rw-r--r--xsd/ee.xsd3
7 files changed, 319 insertions, 84 deletions
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("<root/>", 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%s>%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%s>%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%s>%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%s>%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%s>%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%s>%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%s>%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%s>%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%s>%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%s>%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%s>%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%s>%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%s>%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%s>%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%s>%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%s>%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%s>%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%s>%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'.
<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:attribute name="uri" type="xs:anyURI"/>
@@ -134,6 +134,7 @@ TODO: rename 'id' to 'url'.
<xs:attribute name="relation" type="xs:string"/>
<xs:attribute name="media-type" type="xs:string"/>
<xs:attribute name="title" type="xs:string"/>
+ <xs:attribute name="cache-url" type="xs:string"/>
</xs:complexType>
<xs:complexType name="LinkList">