import psycopg import pydot wkf_id = 231 db = psycopg.connect('dbname=terp', serialize=0) cr=db.cursor() def graph_get(cr, graph, wkf_id, nested=True, workitem={}): cr.execute('select * from wkf_activity where wkf_id=%d', (wkf_id,)) nodes = cr.dictfetchall() activities = {} actfrom = {} actto = {} for n in nodes: activities[n['id']] = n if n['subflow_id'] and nested: cr.execute('select * from wkf where id=%d', (n['subflow_id'],)) wkfinfo = cr.dictfetchone() graph2 = pydot.Cluster('subflow'+str(n['subflow_id']), fontsize=10, label = "Subflow: "+n['name']+'\\nOSV: '+wkfinfo['osv']) (s1,s2) = graph_get(cr, graph2, n['subflow_id'], nested,workitem) graph.add_subgraph(graph2) actfrom[n['id']] = s2 actto[n['id']] = s1 else: args = {} if n['flow_start'] or n['flow_stop']: args['style']='filled' args['color']='lightgrey' args['label']=n['name'] if n['action']: args['label']+='\\n'+n['action'] if n['subflow_id']: args['shape'] = 'box' if n['id'] in workitem: args['label']+='\\nx '+str(workitem[n['id']]) args['color'] = "red" graph.add_node(pydot.Node(n['id'], **args)) actfrom[n['id']] = n['id'] actto[n['id']] = n['id'] cr.execute('select * from wkf_transition where act_from in ('+','.join(map(lambda x: str(x['id']),nodes))+')') transitions = cr.dictfetchall() for t in transitions: args = {} args['label'] = str(t['condition']) if t['signal']: args['label'] += '\\n'+str(t['signal']) args['style'] = 'bold' if activities[t['act_from']]['split_mode']=='AND': args['arrowtail']='box' elif str(activities[t['act_from']]['split_mode'])=='OR ': args['arrowtail']='inv' if activities[t['act_to']]['join_mode']=='AND': args['arrowhead']='crow' graph.add_edge(pydot.Edge(actfrom[t['act_from']],actto[t['act_to']], fontsize=8, **args)) nodes = cr.dictfetchall() cr.execute('select id from wkf_activity where flow_start=True limit 1') start = cr.fetchone()[0] cr.execute('select id from wkf_activity where flow_stop=True limit 1') stop = cr.fetchone()[0] return (start,stop) def graph_instance_get(cr, graph, inst_id, nested=False): workitems = {} cr.execute('select * from wkf_instance where id=%d', (inst_id,)) inst = cr.dictfetchone() def workitem_get(instance): cr.execute('select act_id,count(*) from wkf_workitem where inst_id=%d group by act_id', (instance,)) workitems = dict(cr.fetchall()) cr.execute('select subflow_id from wkf_workitem where inst_id=%d', (instance,)) for (subflow_id,) in cr.fetchall(): workitems.update(workitem_get(subflow_id)) return workitems graph_get(cr, graph, inst['wkf_id'], nested, workitem_get(inst_id)) cr.execute('select * from wkf where id=%d', (wkf_id,)) wkfinfo = cr.dictfetchone() graph = pydot.Dot(fontsize = 16, label = "\\n\\nWorkflow: %s\\n OSV: %s"% (wkfinfo['name'],wkfinfo['osv'])) graph_instance_get(cr, graph, 1155, True) graph.write_ps('/tmp/a.ps', prog='dot')