class ExperimentTimelinePresenter(PresenterBase): def __init__(self, site = None): PresenterBase.__init__(self) self.site = site self.v = ExperimentsVisitor(self.site) def present(self, meta): self.v.visit(meta) self.experiments = [(exp.get_date(), exp.get_site(), exp.get_scenario().get_name()) for exp in self.v.get_result()] self.experiments.sort(key = lambda tup: (date.parse(tup[0]), tup[2])) def dump(self, out): out.write('^ Date ^ Site ^ Scenario ^') for exp in self.experiments: out.write('| %s | %s | %s |' % exp)
class ExperimentTimelinePresenter(PresenterBase): def __init__(self, site=None): PresenterBase.__init__(self) self.site = site self.v = ExperimentsVisitor(self.site) def present(self, meta): self.v.visit(meta) self.experiments = [(exp.get_date(), exp.get_site(), exp.get_scenario().get_name()) for exp in self.v.get_result()] self.experiments.sort(key=lambda tup: (date.parse(tup[0]), tup[2])) def dump(self, out): out.write('^ Date ^ Site ^ Scenario ^') for exp in self.experiments: out.write('| %s | %s | %s |' % exp)
class DependencyPresenter(PresenterBase): def __init__(self, scenario, site = None, relations = ['USES']): PresenterBase.__init__(self) self.scenario = scenario self.site = site self.relations = relations self.ev = ExperimentsVisitor(site = self.site, scenario = self.scenario) self.dv = DependencyVisitor(self.relations) self.design = { 'labeljust': 'left', 'labelloc': 'top', 'fontsize': 8, 'APP_fillcolor': '#fff2cc', 'APP_color': '#efbc00', 'SE_fillcolor': '#deebf7', 'SE_color': '#4a76ca', 'GE_fillcolor': '#e2f0d9', 'GE_color': '#548235', 'EDGE_tailport': 's', 'EDGE_color': '#000000', 'EDGE_USES_style': 'solid', 'EDGE_WILL_USE_style': 'dashed', 'EDGE_MAY_USE_style': 'dashed', 'EDGE_MAY_USE_color': '#838383', 'splines': 'spline' } self.indent = ' ' def present(self, meta): self.ev.visit(meta) # TODO: handle multiple apps per experiment self.apps = [exp.application for exp in self.ev.get_result()] # print(self.apps) for a in self.apps: self.dv.visit(a) self.deployments = [exp.deployment for exp in self.ev.result] def dump_node(self, node, label = lambda node: node.identifier): stripid = self.cleanid('%s_%s' % (node.entity, node.identifier)) # print("%s -> %s" % (node.identifier, stripid)) self.nodemap[node] = stripid self.dump_line('%s [label = "%s"];' % (stripid, label(node)), indent=2) def dump_edge(self, node1, node2, edge): # App10913 -> GhiGE; id1 = self.nodemap[node1] id2 = self.nodemap[node2] # TODO: select appearance depending on edge sedge = edge.replace(' ', '_') self.dump_line('%s:%s -> %s [style = %s, color = "%s", fontsize = %s, fontcolor = "%s", label = "%s"];' % ( id1, self.lookup_design('tailport', ['EDGE_%s' % sedge, 'EDGE']), id2, self.lookup_design('style', ['EDGE_%s' % sedge, 'EDGE']), self.lookup_design('color', ['EDGE_%s' % sedge, 'EDGE']), self.lookup_design('fontsize', ['EDGE_%s' % sedge, 'EDGE']), self.lookup_design('color', ['EDGE_%s' % sedge, 'EDGE']), self.lookup_timing(node1, node2, edge) ), indent=1) def dump_line(self, line, indent = 0): self.out.write(self.indent * indent + line) def cleanid(self, id): return re.sub(r'[^a-zA-Z_]+', '', id) def lookup_design(self, var, prefix): if not type(prefix) is list: prefix = [prefix] val = ['%s_%s' % (p, var) for p in prefix] for v in val: if v in self.design: return self.design[v] if var in self.design: return self.design[var] return None def lookup_timing(self, node1, node2, edge): if edge == 'USES': return " " if node2 not in node1.timing: logging.fatal("Missing timing information!") timing = node1.timing[node2] if timing is None: if node1.entity == 'SE': responsible = node1.provider elif node1.entity == 'APP': responsible = node1.developer else: logging.fatal("Unknown entity (neither APP nor SE)") self.fixme( responsible[0].identifier, 'Provide a timeframe for the integration of enabler "%s" in enabler/application "%s"' % (node2.identifier, node1.identifier), deadline = 'ASAP' ) return "No timeframe" return timing[0] def dump_cluster(self, label, type, nodelabel = lambda node: node.identifier): self.dump_line('subgraph cluster_%s {' % type, indent=1) self.dump_line('rank = same;', indent=2) self.dump_line('style = filled;', indent=2) self.dump_line('color = "%s";' % self.lookup_design('color', type), indent=2) self.dump_line('label = "%s";' % label, indent=2) self.dump_line('labeljust = %s;' % self.lookup_design('labeljust', type), indent=2) self.dump_line('labelloc = %s;' % self.lookup_design('labelloc', type), indent=2) self.dump_line('node [fillcolor = "%s"];' % self.lookup_design('fillcolor', type), indent=2) self.dump_line('') for n in [node for node in self.dv.nodes if node.entity == type]: self.dump_node(n, nodelabel) # self.dump_line('cluster_%s_DUMMY [style = invis, shape = point]' % type, indent=2) self.dump_line('};', indent=1) self.dump_line('') def lookup_deployment(self, enabler): locs = [] for deployment in self.deployments: if enabler in deployment.keys(): locs.append(deployment[enabler]) if len(locs) == 0: self.fixme( [exp.conductor[0].identifier for exp in self.ev.result], 'Provide deployment information for enabler "%s" in scenario "%s" on site %s' % (enabler.identifier, self.scenario, self.site), deadline = 'ASAP' ) return "no deployment info" return ', '.join([l.identifier for l in set(locs)]) def dump(self, out): self.nodemap = {} self.out = out self.dump_line('<graphviz dot center>') self.dump_line('digraph scenario_%s {' % self.cleanid(self.scenario)) self.dump_line('rankdir = TB;', indent=1) self.dump_line('compound = true;', indent=1) self.dump_line('outputorder = edgesfirst;', indent=2) self.dump_line('fontsize = %s;' % self.design['fontsize'], indent=1) self.dump_line('splines = %s;' % self.design['splines'], indent=1) self.dump_line('node [shape = box fontsize=%s style=filled fillcolor=grey];' % self.design['fontsize'], indent=1) self.dump_line('') selabel = lambda node: '%s SE\\n(%s)' % (node.identifier, self.lookup_deployment(node)) gelabel = lambda node: '%s GE\\n(%s)' % (node.identifier, self.lookup_deployment(node)) self.dump_cluster('Applications', 'APP') self.dump_cluster('Specific Enablers', 'SE', nodelabel = selabel) self.dump_cluster('Generic Enablers', 'GE', nodelabel = gelabel) for e in self.dv.edges: self.dump_edge(e[0], e[1], e[2]) # self.dump_line('cluster_APP_DUMMY -> cluster_SE_DUMMY [style = invis];') # self.dump_line('cluster_SE_DUMMY -> cluster_GE_DUMMY [style = invis];') self.dump_line('}') self.dump_line('</graphviz>') self.dump_fixmes(out) self.out = None
class DependencyPresenter(PresenterBase): def __init__(self, scenario, site=None, relations=['USES']): PresenterBase.__init__(self) self.scenario = scenario self.site = site self.relations = relations self.ev = ExperimentsVisitor(site=self.site, scenario=self.scenario) self.dv = DependencyVisitor(self.relations) self.design = { 'labeljust': 'left', 'labelloc': 'top', 'fontsize': 8, 'APP_fillcolor': '#fff2cc', 'APP_color': '#efbc00', 'SE_fillcolor': '#deebf7', 'SE_color': '#4a76ca', 'GE_fillcolor': '#e2f0d9', 'GE_color': '#548235', 'EDGE_tailport': 's', 'EDGE_color': '#000000', 'EDGE_USES_style': 'solid', 'EDGE_WILL_USE_style': 'dashed', 'EDGE_MAY_USE_style': 'dashed', 'EDGE_MAY_USE_color': '#838383', 'splines': 'spline' } self.indent = ' ' def present(self, meta): self.ev.visit(meta) # TODO: handle multiple apps per experiment self.apps = [exp.application for exp in self.ev.get_result()] # print(self.apps) for a in self.apps: self.dv.visit(a) self.deployments = [exp.deployment for exp in self.ev.result] def dump_node(self, node, label=lambda node: node.identifier): stripid = self.cleanid('%s_%s' % (node.entity, node.identifier)) # print("%s -> %s" % (node.identifier, stripid)) self.nodemap[node] = stripid self.dump_line('%s [label = "%s"];' % (stripid, label(node)), indent=2) def dump_edge(self, node1, node2, edge): # App10913 -> GhiGE; id1 = self.nodemap[node1] id2 = self.nodemap[node2] # TODO: select appearance depending on edge sedge = edge.replace(' ', '_') self.dump_line( '%s:%s -> %s [style = %s, color = "%s", fontsize = %s, fontcolor = "%s", label = "%s"];' % (id1, self.lookup_design('tailport', ['EDGE_%s' % sedge, 'EDGE']), id2, self.lookup_design('style', ['EDGE_%s' % sedge, 'EDGE']), self.lookup_design('color', ['EDGE_%s' % sedge, 'EDGE']), self.lookup_design('fontsize', ['EDGE_%s' % sedge, 'EDGE']), self.lookup_design('color', ['EDGE_%s' % sedge, 'EDGE']), self.lookup_timing(node1, node2, edge)), indent=1) def dump_line(self, line, indent=0): self.out.write(self.indent * indent + line) def cleanid(self, id): return re.sub(r'[^a-zA-Z_]+', '', id) def lookup_design(self, var, prefix): if not type(prefix) is list: prefix = [prefix] val = ['%s_%s' % (p, var) for p in prefix] for v in val: if v in self.design: return self.design[v] if var in self.design: return self.design[var] return None def lookup_timing(self, node1, node2, edge): if edge == 'USES': return " " if node2 not in node1.timing: logging.fatal("Missing timing information!") timing = node1.timing[node2] if timing is None: if node1.entity == 'SE': responsible = node1.provider elif node1.entity == 'APP': responsible = node1.developer else: logging.fatal("Unknown entity (neither APP nor SE)") self.fixme( responsible[0].identifier, 'Provide a timeframe for the integration of enabler "%s" in enabler/application "%s"' % (node2.identifier, node1.identifier), deadline='ASAP') return "No timeframe" return timing[0] def dump_cluster(self, label, type, nodelabel=lambda node: node.identifier): self.dump_line('subgraph cluster_%s {' % type, indent=1) self.dump_line('rank = same;', indent=2) self.dump_line('style = filled;', indent=2) self.dump_line('color = "%s";' % self.lookup_design('color', type), indent=2) self.dump_line('label = "%s";' % label, indent=2) self.dump_line('labeljust = %s;' % self.lookup_design('labeljust', type), indent=2) self.dump_line('labelloc = %s;' % self.lookup_design('labelloc', type), indent=2) self.dump_line('node [fillcolor = "%s"];' % self.lookup_design('fillcolor', type), indent=2) self.dump_line('') for n in [node for node in self.dv.nodes if node.entity == type]: self.dump_node(n, nodelabel) # self.dump_line('cluster_%s_DUMMY [style = invis, shape = point]' % type, indent=2) self.dump_line('};', indent=1) self.dump_line('') def lookup_deployment(self, enabler): locs = [] for deployment in self.deployments: if enabler in deployment.keys(): locs.append(deployment[enabler]) if len(locs) == 0: self.fixme( [exp.conductor[0].identifier for exp in self.ev.result], 'Provide deployment information for enabler "%s" in scenario "%s" on site %s' % (enabler.identifier, self.scenario, self.site), deadline='ASAP') return "no deployment info" return ', '.join([l.identifier for l in set(locs)]) def dump(self, out): self.nodemap = {} self.out = out self.dump_line('<graphviz dot center>') self.dump_line('digraph scenario_%s {' % self.cleanid(self.scenario)) self.dump_line('rankdir = TB;', indent=1) self.dump_line('compound = true;', indent=1) self.dump_line('outputorder = edgesfirst;', indent=2) self.dump_line('fontsize = %s;' % self.design['fontsize'], indent=1) self.dump_line('splines = %s;' % self.design['splines'], indent=1) self.dump_line( 'node [shape = box fontsize=%s style=filled fillcolor=grey];' % self.design['fontsize'], indent=1) self.dump_line('') selabel = lambda node: '%s SE\\n(%s)' % (node.identifier, self.lookup_deployment(node)) gelabel = lambda node: '%s GE\\n(%s)' % (node.identifier, self.lookup_deployment(node)) self.dump_cluster('Applications', 'APP') self.dump_cluster('Specific Enablers', 'SE', nodelabel=selabel) self.dump_cluster('Generic Enablers', 'GE', nodelabel=gelabel) for e in self.dv.edges: self.dump_edge(e[0], e[1], e[2]) # self.dump_line('cluster_APP_DUMMY -> cluster_SE_DUMMY [style = invis];') # self.dump_line('cluster_SE_DUMMY -> cluster_GE_DUMMY [style = invis];') self.dump_line('}') self.dump_line('</graphviz>') self.dump_fixmes(out) self.out = None