aboutsummaryrefslogtreecommitdiff
path: root/src/ee/drawio.py
diff options
context:
space:
mode:
authorTrygve Laugstøl <trygvis@inamo.no>2019-05-11 14:48:15 +0200
committerTrygve Laugstøl <trygvis@inamo.no>2019-05-11 14:48:15 +0200
commit0149fcfa2bd9ac8c9f6b05851f7264f005aa2305 (patch)
tree3757a7148377bf18e32234d375444ffccbc5a8f0 /src/ee/drawio.py
parenteffb3470dd1be3a0dd1eaa83991cef45b5e08dab (diff)
downloadee-python-0149fcfa2bd9ac8c9f6b05851f7264f005aa2305.tar.gz
ee-python-0149fcfa2bd9ac8c9f6b05851f7264f005aa2305.tar.bz2
ee-python-0149fcfa2bd9ac8c9f6b05851f7264f005aa2305.tar.xz
ee-python-0149fcfa2bd9ac8c9f6b05851f7264f005aa2305.zip
drawio-to-parts: new tool.
ee.xsd: new type: Assembly and AssemblyPart. Should probably be its own file type. ee.part: Better DSL instead of using the raw xml types.
Diffstat (limited to 'src/ee/drawio.py')
-rw-r--r--src/ee/drawio.py153
1 files changed, 112 insertions, 41 deletions
diff --git a/src/ee/drawio.py b/src/ee/drawio.py
index de98986..b079979 100644
--- a/src/ee/drawio.py
+++ b/src/ee/drawio.py
@@ -2,10 +2,14 @@ import base64
import urllib.parse
import zlib
from pathlib import Path
-from typing import Mapping, MutableMapping
+from typing import Mapping, MutableMapping, List, Optional
from xml.dom import minidom
+
from lxml import etree
+from ee.db import ObjDb
+from ee.part import PartDb, save_db, load_db, Part, AssemblyPart
+
def decompress(input_stream, output_stream):
doc = minidom.parse(input_stream)
@@ -48,8 +52,8 @@ class GraphEdge(object):
self.target_id = target_id
self.value = value
- self.source: GraphObject = None
- self.target: GraphObject = None
+ self.source: Optional[GraphObject] = None
+ self.target: Optional[GraphObject] = None
def add_attr(self, key, value):
self.attrs[key] = value
@@ -60,6 +64,10 @@ class GraphModel(object):
self.objects = objects
self.edges = edges
+ @property
+ def roots(self):
+ return [o for o in self.objects.values() if len(o.incoming) == 0]
+
@staticmethod
def create(objects: Mapping[str, GraphObject], edges: Mapping[str, GraphEdge]) -> "GraphModel":
for id_, edge in edges.items():
@@ -130,10 +138,72 @@ def load_graph(doc) -> GraphModel:
return GraphModel.create(objects, edges)
-def to_parts(in_path: Path, out_path: Path):
+def to_parts(in_path: Path, out_path: Path, part_dbs: List[Path]):
+ parts: ObjDb[Part] = ObjDb[Part]()
+ description_idx = parts.add_index("description", lambda p: p.underlying.descriptionProp)
+
+ def find_part(o: GraphObject):
+ if "part" in o.attrs:
+ d = o.attrs["part"]
+ else:
+ d = o.value
+
+ hits = description_idx.get(d)
+ if len(hits) == 0:
+ # print("No part with description found in database: '{}'".format(d))
+ return
+ elif len(hits) == 1:
+ found = hits[0]
+ return found
+ else:
+ # print("Found multiple parts with description '{}'".format(d))
+ return
+
+ def add_part(o: GraphObject):
+ print("obj: {}".format(o.value))
+
+ p = find_part(o)
+
+ uri = p.uri if p else None
+ ap = AssemblyPart(uri)
+
+ if uri:
+ ap.references.add_part_reference(uri)
+
+ ap.references.add_description_reference(o.value)
+
+ for out in o.outgoing.values():
+ sub_part = add_part(out.target)
+ ap.add_sub_part(sub_part)
+
+ # description = out.target.value
+ # print(" out: {}".format(description))
+ #
+ # p = find_part(out.target)
+ #
+ # if p is None:
+ # continue
+ #
+ # ap.add_sub_part(p.uri)
+
+ return ap
+
+ for part_db in part_dbs:
+ for xml in load_db(part_db).iterparts():
+ parts.add(Part(xml))
+
doc = etree.parse(str(in_path))
+ print(doc)
graph = load_graph(doc)
+ db = PartDb()
+ a = db.assembly
+
+ for root in graph.roots:
+ a.parts.append(add_part(root))
+
+ save_db(out_path, db)
+
def to_dot(in_path: Path, out_path: Path):
def to_id(s: str):
@@ -145,43 +215,44 @@ def to_dot(in_path: Path, out_path: Path):
doc = etree.parse(str(in_path))
graph = load_graph(doc)
- print("digraph parts {")
- for id_, obj in graph.objects.items():
- if len(obj.attrs):
- attr_str = "\\n".join(["{}={}".format(k, quote(v)) for k, v in obj.attrs.items()])
- print(" {}_attrs [shape=plaintext, label=\"{}\"]".format(to_id(obj.id), quote(attr_str)))
- print(" {}_attrs -> {} [arrowhead=none,style=dotted]".format(to_id(obj.id), to_id(obj.id)))
-
- attrs = {}
- if obj.value:
- attrs["label"] = obj.value
-
- attr_str = ",".join(["{}=\"{}\"".format(k, quote(v)) for k, v in attrs.items()])
- print(" {} [{}];".format(to_id(obj.id), attr_str))
-
- for id_, edge in graph.edges.items():
- source_id = edge.source.id
- target_id = edge.target.id
-
- if len(edge.attrs):
- print(" // source={}, target={}".format(source_id, target_id))
- attr_str = "\\n".join(["{}={}".format(k, quote(v)) for k, v in edge.attrs.items()])
-
- print(" {}_fake [shape=plaintext, label=\"{}\"]".format(to_id(edge.target.id), attr_str))
- print(" {}_fake -> {}".format(to_id(edge.target.id), to_id(edge.target.id)))
- # source_id = "{}_fake".format(to_id(edge.id))
- target_id = "{}_fake".format(to_id(edge.target.id))
- arrowhead="none"
- else:
- arrowhead="normal"
+ with open(str(out_path), "w") as f:
+ print("digraph parts {", file=f)
+ for id_, obj in graph.objects.items():
+ if len(obj.attrs):
+ attr_str = "\\n".join(["{}={}".format(k, quote(v)) for k, v in obj.attrs.items()])
+ print(" {}_attrs [shape=plaintext, label=\"{}\"]".format(to_id(obj.id), quote(attr_str)), file=f)
+ print(" {}_attrs -> {} [arrowhead=none,style=dotted]".format(to_id(obj.id), to_id(obj.id)), file=f)
+
+ attrs = {}
+ if obj.value:
+ attrs["label"] = obj.value
+
+ attr_str = ",".join(["{}=\"{}\"".format(k, quote(v)) for k, v in attrs.items()])
+ print(" {} [{}];".format(to_id(obj.id), attr_str), file=f)
+
+ for id_, edge in graph.edges.items():
+ source_id = edge.source.id
+ target_id = edge.target.id
+
+ if len(edge.attrs):
+ print(" // source={}, target={}".format(source_id, target_id), file=f)
+ attr_str = "\\n".join(["{}={}".format(k, quote(v)) for k, v in edge.attrs.items()])
- attrs = {}
- # if edge.value:
- # attrs["label"] = edge.value
+ print(" {}_fake [shape=plaintext, label=\"{}\"]".format(to_id(edge.target.id), attr_str), file=f)
+ print(" {}_fake -> {}".format(to_id(edge.target.id), to_id(edge.target.id)), file=f)
+ # source_id = "{}_fake".format(to_id(edge.id))
+ target_id = "{}_fake".format(to_id(edge.target.id))
+ arrowhead = "none"
+ else:
+ arrowhead = "normal"
+
+ attrs = {}
+ # if edge.value:
+ # attrs["label"] = edge.value
- # attr_str = ",".join(["{}=\"{}\"".format(k, quote(v)) for k, v in attrs.items()])
+ # attr_str = ",".join(["{}=\"{}\"".format(k, quote(v)) for k, v in attrs.items()])
- print(" {} -> {} [arrowhead={}];".format(to_id(source_id), to_id(target_id), arrowhead))
- for k, v in edge.attrs.items():
- print(" // {}={}".format(k, v))
- print("}")
+ print(" {} -> {} [arrowhead={}];".format(to_id(source_id), to_id(target_id), arrowhead), file=f)
+ for k, v in edge.attrs.items():
+ print(" // {}={}".format(k, v))
+ print("}")