def render_for_model(self, model_label, **options): app_label, model, field = model_label.split(".") try: Model = get_model(app_label, model) except LookupError: Model = None STATE_MACHINE = getattr(Model(), "get_%s_machine" % field)() name = six.text_type(Model._meta.verbose_name) g = Graph("state_machine_graph_%s" % model_label, False) g.label = "State Machine Graph %s" % name nodes = {} edges = {} for state in STATE_MACHINE.states: nodes[state] = g.add_node(state, label=state.upper(), shape="rect", fontname="Arial") logger.debug("Created node for %s", state) def find(f, a): for i in a: if f(i): return i return None for trion_name, trion in six.iteritems(STATE_MACHINE.transitions): for from_state in trion.from_states: edge = g.add_edge(nodes[from_state], nodes[trion.to_state]) edge.dir = "forward" edge.arrowhead = "normal" edge.label = "\n_".join(trion.get_name().split("_")) edge.fontsize = 8 edge.fontname = "Arial" if getattr(trion, "confirm_needed", False): edge.style = "dotted" edges[u"%s-->%s" % (from_state, trion.to_state)] = edge logger.debug("Created %d edges for %s", len(trion.from_states), trion.get_name()) # if trion.next_function_name is not None: # tr = find(lambda t: t.function_name == trion.next_function_name and t.from_state == trion.to_state, STATE_MACHINE.trions) # while tr.next_function_name is not None: # tr = find(lambda t: t.function_name == tr.next_function_name and t.from_state == tr.to_state, STATE_MACHINE.trions) # if tr is not None: # meta_edge = g.add_edge(nodes[trion.from_state], nodes[tr.to_state]) # meta_edge.arrowhead = 'empty' # meta_edge.label = '\n_'.join(trion.function_name.split('_')) + '\n(compound)' # meta_edge.fontsize = 8 # meta_edge.fontname = 'Arial' # meta_edge.color = 'blue' # if any(lambda t: (t.next_function_name == trion.function_name), STATE_MACHINE.trions): # edge.color = 'red' # edge.style = 'dashed' # edge.label += '\n(auto)' logger.info("Creating state graph for %s with %d nodes and %d edges" % (name, len(nodes), len(edges))) loc = "state_machine_%s" % (model_label,) if options["create_dot"]: g.write("%s.dot" % loc) logger.debug("Setting layout %s" % options["layout"]) g.layout(options["layout"]) format = options["format"] logger.debug("Trying to render %s" % loc) g.render(loc + "." + format, format, None) logger.info("Created state graph for %s at %s" % (name, loc))
def render_for_model(self, model_label, **options): app_label,model,field = model_label.split('.') try: Model = get_model(app_label, model) except LookupError: Model = None STATE_MACHINE = getattr(Model(), 'get_%s_machine' % field)() name = six.text_type(Model._meta.verbose_name) g = Graph('state_machine_graph_%s' % model_label, False) g.label = '%s State Machine' % name g.rankdir = "TB" g.ranksep = "0.5" nodes = {} edges = {} for state, state_machine in STATE_MACHINE.states.items(): label = state.capitalize() if hasattr(state_machine, 'description'): label = state_machine.description if len(state_machine.description) > 32: label = state_machine.description[:29] + "..." label += "\n (%s)" % state shape = 'rect' color = 'lightgrey' if hasattr(state_machine, 'initial') and state_machine.initial: shape = 'invtrapezium' if hasattr(state_machine, 'public') and state_machine.public: color = 'black' nodes[state] = g.add_node( state, label=label, shape=shape, color=color, fontname='Arial') logger.debug('Created node for %s', state) def find(f, a): for i in a: if f(i): return i return None for trion_name,trion in six.iteritems(STATE_MACHINE.transitions): for from_state in trion.from_states: edge = g.add_edge(nodes[from_state], nodes[trion.to_state]) edge.dir = 'forward' edge.arrowhead = 'normal' edge.label = '\n'.join(trion.get_name().split('_')) edge.fontsize = 8 edge.fontname = 'Arial' if getattr(trion, 'confirm_needed', False): edge.style = 'dotted' edges[u'%s-->%s' % (from_state, trion.to_state)] = edge logger.debug('Created %d edges for %s', len(trion.from_states), trion.get_name()) #if trion.next_function_name is not None: # tr = find(lambda t: t.function_name == trion.next_function_name and t.from_state == trion.to_state, STATE_MACHINE.trions) # while tr.next_function_name is not None: # tr = find(lambda t: t.function_name == tr.next_function_name and t.from_state == tr.to_state, STATE_MACHINE.trions) # if tr is not None: # meta_edge = g.add_edge(nodes[trion.from_state], nodes[tr.to_state]) # meta_edge.arrowhead = 'empty' # meta_edge.label = '\n_'.join(trion.function_name.split('_')) + '\n(compound)' # meta_edge.fontsize = 8 # meta_edge.fontname = 'Arial' # meta_edge.color = 'blue' #if any(lambda t: (t.next_function_name == trion.function_name), STATE_MACHINE.trions): # edge.color = 'red' # edge.style = 'dashed' # edge.label += '\n(auto)' logger.info('Creating state graph for %s with %d nodes and %d edges' % (name, len(nodes), len(edges))) loc = 'state_machine_%s' % (model_label,) if options['create_dot']: g.write('%s.dot' % loc) logger.debug('Setting layout %s' % options['layout']) g.layout(options['layout']) format = options['format'] logger.debug('Trying to render %s' % loc) g.render(loc + '.' + format, format, None) logger.info('Created state graph for %s at %s' % (name, loc))
def render_for_model(self, model_label, **options): app_label, model, field = model_label.split('.') Model = get_model(app_label, model) STATE_MACHINE = getattr(Model(), 'get_%s_machine' % field)() name = unicode(Model._meta.verbose_name) g = Graph('state_machine_graph_%s' % model_label, False) g.label = 'State Machine Graph %s' % name nodes = {} edges = {} for state in STATE_MACHINE.states: nodes[state] = g.add_node(state, label=state.upper(), shape='rect', fontname='Arial') logger.debug('Created node for %s', state) def find(f, a): for i in a: if f(i): return i return None for trion_name, trion in STATE_MACHINE.transitions.iteritems(): for from_state in trion.from_states: edge = g.add_edge(nodes[from_state], nodes[trion.to_state]) edge.dir = 'forward' edge.arrowhead = 'normal' edge.label = '\n_'.join(trion.get_name().split('_')) edge.fontsize = 8 edge.fontname = 'Arial' if getattr(trion, 'confirm_needed', False): edge.style = 'dotted' edges[u'%s-->%s' % (from_state, trion.to_state)] = edge logger.debug('Created %d edges for %s', len(trion.from_states), trion.get_name()) #if trion.next_function_name is not None: # tr = find(lambda t: t.function_name == trion.next_function_name and t.from_state == trion.to_state, STATE_MACHINE.trions) # while tr.next_function_name is not None: # tr = find(lambda t: t.function_name == tr.next_function_name and t.from_state == tr.to_state, STATE_MACHINE.trions) # if tr is not None: # meta_edge = g.add_edge(nodes[trion.from_state], nodes[tr.to_state]) # meta_edge.arrowhead = 'empty' # meta_edge.label = '\n_'.join(trion.function_name.split('_')) + '\n(compound)' # meta_edge.fontsize = 8 # meta_edge.fontname = 'Arial' # meta_edge.color = 'blue' #if any(lambda t: (t.next_function_name == trion.function_name), STATE_MACHINE.trions): # edge.color = 'red' # edge.style = 'dashed' # edge.label += '\n(auto)' logger.info('Creating state graph for %s with %d nodes and %d edges' % (name, len(nodes), len(edges))) loc = 'state_machine_%s' % (model_label, ) if options['create_dot']: g.write('%s.dot' % loc) logger.debug('Setting layout %s' % options['layout']) g.layout(options['layout']) format = options['format'] logger.debug('Trying to render %s' % loc) g.render(loc + '.' + format, format, None) logger.info('Created state graph for %s at %s' % (name, loc))
def handle(self, *args, **options): directory = (options.get('directory', ['']) or [''])[0] exclude_directory = (options.get('exclude_directory', []) or []) g = Graph('Template dependencies', True) g.layout('neato') g.landscape = True g.rotate = 90 g.label = str(datetime.datetime.now()) #g.scale = 0.7 #g.overlap = 'prism' #g.overlap = False g.overlap = 'scale' g.ranksep = 1.8 g.overlap = 'compress' g.ratio = 1. / math.sqrt(2) g.sep = 0.1 g.mindist = 0.1 nodes = set() edges = [] nodes_in_edges = set() # Retreive all nodes/edges for dir, t in template_iterator(): if t.startswith(directory) and not any( [t.startswith(x) for x in exclude_directory]): nodes.add(t) # {% include "..." %} includes = self._make_output_path(t) + '-c-includes' if os.path.exists(includes): for t2 in open(includes, 'r').read().split('\n'): if t2: nodes.add(t2) edges.append((t, t2, False)) nodes_in_edges.add(t) nodes_in_edges.add(t2) # {% extends "..." %} extends = self._make_output_path(t) + '-c-extends' if os.path.exists(extends): for t2 in open(extends, 'r').read().split('\n'): if t2: nodes.add(t2) edges.append((t, t2, True)) nodes_in_edges.add(t) nodes_in_edges.add(t2) # Remove orphan nodes for n in list(nodes): if not n in nodes_in_edges: nodes.remove(n) # Create graphvis nodes nodes2 = {} for t in nodes: node = self._create_node(t, g, nodes2) # Create graphvis edges for t1, t2, is_extends in edges: print 'from ', t1, ' to ', t2 node_a = self._create_node(t1, g, nodes2) node_b = self._create_node(t2, g, nodes2) edge = g.add_edge(node_a, node_b) edge.color = 'black' edge.arrowhead = 'normal' edge.arrowsize = 1.1 if is_extends: edge.style = 'solid' else: edge.style = 'dotted' #g.layout('neato') g.layout('twopi') g.render(settings.ROOT + 'template_dependency_graph.pdf', 'pdf', None) g.render(settings.ROOT + 'template_dependency_graph.jpg', 'jpg', None)
def handle(self, *args, **options): directory = (options.get('directory', ['']) or [''])[0] exclude_directory = (options.get('exclude_directory', []) or []) g = Graph('Template dependencies', True) g.layout('neato') g.landscape = True g.rotate = 90 g.label = str(datetime.datetime.now()) #g.scale = 0.7 #g.overlap = 'prism' #g.overlap = False g.overlap = 'scale' g.ranksep = 1.8 g.overlap = 'compress' g.ratio = 1. / math.sqrt(2) g.sep = 0.1 g.mindist = 0.1 nodes = set() edges = [ ] nodes_in_edges = set() # Retreive all nodes/edges for dir, t in template_iterator(): if t.startswith(directory) and not any([ t.startswith(x) for x in exclude_directory ]): nodes.add(t) # {% include "..." %} includes = self._make_output_path(t) + '-c-includes' if os.path.exists(includes): for t2 in open(includes, 'r').read().split('\n'): if t2: nodes.add(t2) edges.append( (t, t2, False) ) nodes_in_edges.add(t) nodes_in_edges.add(t2) # {% extends "..." %} extends = self._make_output_path(t) + '-c-extends' if os.path.exists(extends): for t2 in open(extends, 'r').read().split('\n'): if t2: nodes.add(t2) edges.append( (t, t2, True) ) nodes_in_edges.add(t) nodes_in_edges.add(t2) # Remove orphan nodes for n in list(nodes): if not n in nodes_in_edges: nodes.remove(n) # Create graphvis nodes nodes2 = { } for t in nodes: node = self._create_node(t, g, nodes2) # Create graphvis edges for t1, t2, is_extends in edges: print 'from ', t1, ' to ', t2 node_a = self._create_node(t1, g, nodes2) node_b = self._create_node(t2, g, nodes2) edge = g.add_edge(node_a, node_b) edge.color = 'black' edge.arrowhead = 'normal' edge.arrowsize = 1.1 if is_extends: edge.style = 'solid' else: edge.style = 'dotted' #g.layout('neato') g.layout('twopi') g.render(settings.ROOT + 'template_dependency_graph.pdf', 'pdf', None) g.render(settings.ROOT + 'template_dependency_graph.jpg', 'jpg', None)
def render_for_model(self, model_label, **options): app_label, model, field = model_label.split(".") try: Model = get_model(app_label, model) except LookupError: Model = None STATE_MACHINE = getattr(Model(), "get_{}_machine".format(field))() name = Model._meta.verbose_name g = Graph("state_machine_graph_{}".format(model_label), False) g.label = "State Machine Graph {}".format(name) nodes = {} edges = {} for state in STATE_MACHINE.states: nodes[state] = g.add_node(state, label=state.upper(), shape="rect", fontname="Arial") logger.debug("Created node for {}".format(state)) def find(f, a): for i in a: if f(i): return i return None for trion_name, trion in STATE_MACHINE.transitions.items(): for from_state in trion.from_states: edge = g.add_edge(nodes[from_state], nodes[trion.to_state]) edge.dir = "forward" edge.arrowhead = "normal" edge.label = "\n_".join(trion.get_name().split("_")) edge.fontsize = 8 edge.fontname = "Arial" if getattr(trion, "confirm_needed", False): edge.style = "dotted" edges["{}-->{}".format(from_state, trion.to_state)] = edge logger.debug("Created {} edges for {}".format( len(trion.from_states), trion.get_name())) # if trion.next_function_name is not None: # tr = find(lambda t: t.function_name == trion.next_function_name and t.from_state == trion.to_state, STATE_MACHINE.trions) # while tr.next_function_name is not None: # tr = find(lambda t: t.function_name == tr.next_function_name and t.from_state == tr.to_state, STATE_MACHINE.trions) # if tr is not None: # meta_edge = g.add_edge(nodes[trion.from_state], nodes[tr.to_state]) # meta_edge.arrowhead = 'empty' # meta_edge.label = '\n_'.join(trion.function_name.split('_')) + '\n(compound)' # meta_edge.fontsize = 8 # meta_edge.fontname = 'Arial' # meta_edge.color = 'blue' # if any(lambda t: (t.next_function_name == trion.function_name), STATE_MACHINE.trions): # edge.color = 'red' # edge.style = 'dashed' # edge.label += '\n(auto)' logger.info( "Creating state graph for {} with {} nodes and {} edges".format( name, len(nodes), len(edges))) loc = "state_machine_{}".format(model_label) if options["create_dot"]: g.write("{}.dot".format(loc)) logger.debug("Setting layout {}".format(options["layout"])) g.layout(options["layout"]) format = options["format"] logger.debug("Trying to render {}".format(loc)) g.render(loc + "." + format, format, None) logger.info("Created state graph for {} at {}".format(name, loc))
def render_for_model(self, model_label, **options): app_label,model,field = model_label.split('.') Model = get_model(app_label, model) STATE_MACHINE = getattr(Model(), 'get_%s_machine' % field)() name = unicode(Model._meta.verbose_name) g = Graph('state_machine_graph_%s' % model_label, False) g.label = 'State Machine Graph %s' % name nodes = {} edges = {} for state in STATE_MACHINE.states: nodes[state] = g.add_node(state, label=state.upper(), shape='rect', fontname='Arial') logger.debug('Created node for %s', state) def find(f, a): for i in a: if f(i): return i return None for trion_name,trion in STATE_MACHINE.transitions.iteritems(): for from_state in trion.from_states: edge = g.add_edge(nodes[from_state], nodes[trion.to_state]) edge.dir = 'forward' edge.arrowhead = 'normal' edge.label = '\n_'.join(trion.get_name().split('_')) edge.fontsize = 8 edge.fontname = 'Arial' if getattr(trion, 'confirm_needed', False): edge.style = 'dotted' edges[u'%s-->%s' % (from_state, trion.to_state)] = edge logger.debug('Created %d edges for %s', len(trion.from_states), trion.get_name()) #if trion.next_function_name is not None: # tr = find(lambda t: t.function_name == trion.next_function_name and t.from_state == trion.to_state, STATE_MACHINE.trions) # while tr.next_function_name is not None: # tr = find(lambda t: t.function_name == tr.next_function_name and t.from_state == tr.to_state, STATE_MACHINE.trions) # if tr is not None: # meta_edge = g.add_edge(nodes[trion.from_state], nodes[tr.to_state]) # meta_edge.arrowhead = 'empty' # meta_edge.label = '\n_'.join(trion.function_name.split('_')) + '\n(compound)' # meta_edge.fontsize = 8 # meta_edge.fontname = 'Arial' # meta_edge.color = 'blue' #if any(lambda t: (t.next_function_name == trion.function_name), STATE_MACHINE.trions): # edge.color = 'red' # edge.style = 'dashed' # edge.label += '\n(auto)' logger.info('Creating state graph for %s with %d nodes and %d edges' % (name, len(nodes), len(edges))) loc = 'state_machine_%s' % (model_label,) if options['create_dot']: g.write('%s.dot' % loc) logger.debug('Setting layout %s' % options['layout']) g.layout(options['layout']) format = options['format'] logger.debug('Trying to render %s' % loc) g.render(loc + '.' + format, format, None) logger.info('Created state graph for %s at %s' % (name, loc))