aboutsummaryrefslogtreecommitdiff
path: root/trygvis/eda/cli/kicad_import_project.py
diff options
context:
space:
mode:
authorTrygve Laugstøl <trygvis@inamo.no>2017-01-07 14:00:46 +0100
committerTrygve Laugstøl <trygvis@inamo.no>2017-01-07 14:00:46 +0100
commit0958273a71dd19c2a90471a182ccc5b90b14e5b4 (patch)
tree8e33385ca9df94b80ce9b1f8ba06438b807f137a /trygvis/eda/cli/kicad_import_project.py
parent5d7fc9c4b14536006f2435b1379887f95937e096 (diff)
downloadeda-rdf-0958273a71dd19c2a90471a182ccc5b90b14e5b4.tar.gz
eda-rdf-0958273a71dd19c2a90471a182ccc5b90b14e5b4.tar.bz2
eda-rdf-0958273a71dd19c2a90471a182ccc5b90b14e5b4.tar.xz
eda-rdf-0958273a71dd19c2a90471a182ccc5b90b14e5b4.zip
Renaming 'schematic' to 'project'.
Renaming 'kicad-bom-to-ttl' to 'kicad-import-project'. Renaming 'digikey-download-for-schematic' to 'digikey-download-for-project'. Splitting out the Export xml file code into its own module. init: putting project.url and project.file in config.ini. init: putting db.update-url in config.ini if given on the command line. kicad-import-project: by default, assume that the user want to update local database, optionally write the ttl file to disk. cli.write_graph: create any missing parent directories.
Diffstat (limited to 'trygvis/eda/cli/kicad_import_project.py')
-rwxr-xr-xtrygvis/eda/cli/kicad_import_project.py173
1 files changed, 173 insertions, 0 deletions
diff --git a/trygvis/eda/cli/kicad_import_project.py b/trygvis/eda/cli/kicad_import_project.py
new file mode 100755
index 0000000..288b7fc
--- /dev/null
+++ b/trygvis/eda/cli/kicad_import_project.py
@@ -0,0 +1,173 @@
+import os.path
+from operator import attrgetter
+import itertools
+
+import rdflib
+from rdflib import Literal, URIRef
+from rdflib.namespace import RDF, RDFS
+
+# from ..kicad import rdf as kicad_rdf
+from . import *
+from ..kicad.export import *
+
+
+class KicadImportProjectCommand(CliCommand):
+ def __init__(self):
+ super().__init__("kicad-import-project", "Import a KiCAD project")
+
+ def run(self, argv):
+ p = argparse.ArgumentParser(prog=self.key, description=self.description)
+ p.add_argument("-o", "--output-dir", dest="output_dir", required=False)
+ p.add_argument("-i", "--input", required=False)
+ args = p.parse_args(argv)
+
+ run(args)
+
+
+def run(args):
+ config = read_config()
+
+ if args.input is "-":
+ src = sys.stdin
+ else:
+ if args.input is None:
+ (filename, _) = os.path.splitext(config['project']['file'])
+ filename += '.xml'
+ else:
+ filename = args.input
+
+ if not isfile(filename):
+ raise CliException("No such file: %s. Did you export the BOM?" % filename)
+
+ src = open(filename, 'r')
+
+ project_url = config['project']['url']
+
+ with src:
+ project = export_to_graph(src, project_url)
+
+ debug('Loaded %s tuples' % len(project))
+
+ if args.output_dir is not None:
+ parent = args.output_dir
+ if not os.path.exists(parent):
+ os.mkdir(parent)
+ output_file = os.path.join(parent, "project.ttl")
+ with open(output_file, 'wb') as dst:
+ project.serialize(destination=dst, encoding='utf-8', format='turtle')
+
+ def import_project(g):
+ for idx, t in enumerate(project.triples((None, None, None))):
+ g.add(t)
+
+ with_database(import_project)
+
+
+def export_to_graph(src: object, project_url: str) -> rdflib.Graph:
+ export = Export.from_xml_file(src)
+
+ # print('components:')
+ # for c in export.components:
+ # print(c)
+
+ # for name in export.component_fields():
+ # cli.info(name)
+
+ # cli.info('components:')
+ # fmt = '%2s%3s'
+ # cli.info(fmt % ('Ref', ''))
+
+ components = sorted(export.components, key=attrgetter('ref'))
+
+ component_count = 0
+ part_count = 0
+ has_part = 0
+ has_digikey = 0
+
+ for cls, cs in itertools.groupby(components, key=attrgetter('ref_class')):
+ # cli.info('--- Class: %s ---' % cls)
+ cs = sorted(cs, key=attrgetter('value'))
+ for c in cs:
+ component_count += 1
+
+ value = str(c.value)
+ part = c.find_field('part')
+ digikey = c.find_field('digikey')
+ footprint = c.footprint
+
+ if c.ref_class is not None:
+ ref_class = c.ref_class
+ ref_instance = c.ref_instance
+ else:
+ ref_class = c.ref
+ ref_instance = ''
+
+ # cli.info(fmt % (ref_class, ref_instance))
+ # cli.info(' Value: %s' % c.value.text)
+ # if c.footprint:
+ # cli.info(' Footprint: %s' % c.footprint)
+
+ if part is not None:
+ if part != 'NA':
+ has_part += 1 if part is not None else 0
+ part_count += 1
+
+ if digikey is not None:
+ has_digikey += 1
+ else:
+ part = None
+ else:
+ part_count += 1
+ part = 'MISSING'
+
+ # if part is not None:
+ # cli.info(' Part: %s' % part)
+ # if digikey is not None:
+ # cli.info(' Digikey: %s' % digikey)
+
+ # cli.info()
+ # cli.info('=== Summary ===')
+ # cli.info('Project URL: %s' % project_url)
+ # cli.info('Number of components: %d' % component_count)
+ # cli.info('Number of parts: %d' % part_count)
+ # cli.info('Assigned part: %d / %2.f%%' % (has_part, (has_part / part_count) * 100))
+ # cli.info('Assigned digikey: %d / %2.f%%' % (has_digikey, (has_digikey / part_count) * 100))
+
+ g = create_graph(kicad=True)
+
+ project = URIRef(project_url)
+ g.add((project, RDF.type, kicad_rdf.KICAD_TYPE.project))
+
+ # The components and fields could/should have been a BNodes. Their generated names are not very nice.
+ # TODO: try using a hash of the current value and put that under a special generated namespace.
+ # 'http://example.org/my-board' + ref='C10' => 'http://example.org/my-boardC10'
+ # hash('http://example.org/my-boardC10') => 123456
+ # add_prefix(hash) => 'https://trygvis.io/purl/kicad/generated#123456'
+ footprints = set()
+ for c in export.components:
+ ns = rdflib.Namespace(project_url)
+ node = ns[c.ref]
+ g.add((project, kicad_rdf.KICAD.component, node))
+
+ g.add((node, RDF.type, kicad_rdf.KICAD_TYPE.schematic_component))
+ g.add((node, RDFS.label, Literal(c.ref)))
+ g.add((node, kicad_rdf.KICAD.value, Literal(c.value.text)))
+
+ footprint_uri = URIRef(kicad_rdf.KICAD_FOOTPRINT[quote_plus(c.footprint)])
+ if not footprint_uri in footprints:
+ g.add((footprint_uri, RDF.type, kicad_rdf.KICAD_TYPE.footprint))
+ g.add((footprint_uri, RDFS.label, Literal(c.footprint)))
+ footprints.add(footprint_uri)
+
+ g.add((node, kicad_rdf.KICAD.footprint, footprint_uri))
+
+ for name, value in c.fields.items():
+ f = ns['%s-%s' % (c.ref, name)]
+ g.add((node, kicad_rdf.KICAD.field, f))
+ g.add((f, RDF.type, kicad_rdf.KICAD_TYPE.field))
+ g.add((f, kicad_rdf.KICAD.field_name, Literal(name)))
+ g.add((f, kicad_rdf.KICAD.field_value, Literal(value)))
+
+ # TODO: serialize the data from <design> too
+
+ return g