|
|
@@ -0,0 +1,102 @@
|
|
|
+from dataclasses import dataclass, field
|
|
|
+from util import *
|
|
|
+
|
|
|
+
|
|
|
+@dataclass
|
|
|
+class Class:
|
|
|
+ class_name: str
|
|
|
+ docs: str
|
|
|
+ properties: dict = field(default_factory=dict)
|
|
|
+ blocks: list = field(default_factory=list)
|
|
|
+ connections: list = field(default_factory=list)
|
|
|
+ ports: list = field(default_factory=list)
|
|
|
+
|
|
|
+ def get_properties(self):
|
|
|
+ return ", ".join(["%s=(%s)" % (k, v) for k, v in self.properties.items()])
|
|
|
+
|
|
|
+ def get_inputs(self):
|
|
|
+ return [p for d, p in self.ports if d == "IN"]
|
|
|
+
|
|
|
+ def get_outputs(self):
|
|
|
+ return [p for d, p in self.ports if d == "OUT"]
|
|
|
+
|
|
|
+ def is_empty(self):
|
|
|
+ return len(self.blocks) == 0 or len(self.connections) == 0
|
|
|
+
|
|
|
+
|
|
|
+@dataclass
|
|
|
+class Block:
|
|
|
+ class_name: str
|
|
|
+ block_name: str
|
|
|
+ args: dict
|
|
|
+
|
|
|
+ def get_properties(self):
|
|
|
+ return ", ".join(["%s=(%s)" % (k, v) for k, v in self.args.items()])
|
|
|
+
|
|
|
+
|
|
|
+@dataclass
|
|
|
+class Page:
|
|
|
+ name: str
|
|
|
+ classes: list = field(default_factory=list)
|
|
|
+ imports: dict = field(default_factory=dict)
|
|
|
+
|
|
|
+
|
|
|
+def collect_pages(drawio_file, formalism, inp, out, ignore, ignore_empty):
|
|
|
+ pages = []
|
|
|
+ for apage in drawio_file.pages:
|
|
|
+ page = Page(apage.name)
|
|
|
+
|
|
|
+ cbds_on_page = find_shapes_by_property(apage.root, "formalism", formalism)
|
|
|
+ for acbd in cbds_on_page:
|
|
|
+ cbd = Class(acbd.properties.get("class_name", ""), acbd.properties.get("__docstring__", ""))
|
|
|
+ for prop, val in acbd.properties.items():
|
|
|
+ if prop not in ignore:
|
|
|
+ cbd.properties[prop] = val
|
|
|
+
|
|
|
+ # Blocks
|
|
|
+ blocks = find_shapes(acbd, "class_name", False, False)
|
|
|
+ for ablock in blocks:
|
|
|
+ if ablock.properties.get("formalism", None) == formalism:
|
|
|
+ if ablock.properties.get("block_name", "") != "":
|
|
|
+ props = {k: v for k, v in ablock.properties.items() if k not in ignore}
|
|
|
+ block = Block(ablock.properties["class_name"], ablock.properties["block_name"], props)
|
|
|
+ cbd.blocks.append(block)
|
|
|
+ elif ablock.properties["class_name"] == inp:
|
|
|
+ cbd.ports.append(("IN", ablock.properties["name"]))
|
|
|
+ elif ablock.properties["class_name"] == out:
|
|
|
+ cbd.ports.append(("OUT", ablock.properties["name"]))
|
|
|
+ else:
|
|
|
+ props = {k: v for k, v in ablock.properties.items() if k not in ignore}
|
|
|
+ block = Block(ablock.properties["class_name"], ablock.properties["block_name"], props)
|
|
|
+ cbd.blocks.append(block)
|
|
|
+
|
|
|
+ if "__import__" in ablock.properties:
|
|
|
+ imp = ablock.properties["__import__"]
|
|
|
+ page.imports.setdefault(imp, []).append(ablock.properties["class_name"])
|
|
|
+
|
|
|
+ # Connections
|
|
|
+ edges = find_edges(acbd)
|
|
|
+ for edge in edges:
|
|
|
+ e = []
|
|
|
+ for el in [edge.source, edge.target]:
|
|
|
+ eblock = find_shapes_parent(el, "block_name", False)
|
|
|
+ if el.properties["class_name"] not in [inp, out]:
|
|
|
+ raise ConnectionError("Port %s is of invalid type %s in class %s" % \
|
|
|
+ (el.properties.get("name", "<<Undefined>>"),
|
|
|
+ el.properties.get("class_name", "<<Undefined>>"),
|
|
|
+ eblock.properties["class_name"]))
|
|
|
+
|
|
|
+ if eblock == acbd:
|
|
|
+ eblock = None
|
|
|
+ if eblock is not None:
|
|
|
+ src = eblock.properties["block_name"], el.properties["name"]
|
|
|
+ else:
|
|
|
+ src = el.properties["name"], None
|
|
|
+ e.append(src)
|
|
|
+
|
|
|
+ cbd.connections.append(e)
|
|
|
+
|
|
|
+ if not (ignore_empty and cbd.is_empty()):
|
|
|
+ page.classes.append(cbd)
|
|
|
+ pages.append(page)
|
|
|
+ return pages
|