from ..iGraph.graph import Graph from .nodes import StemNode import networkx as nx from .nodes import SubTaskNode class ITaskerGraph(Graph): CONNECTION_KEY = 'CONNECTION' def __init__(self, user=None): super(ITaskerGraph, self).__init__(user=user) @classmethod def parse_graph(cls, json_graph, nodes_cls={}, common_params={}): graph = super(ITaskerGraph, cls).parse_graph(json_graph, StemNode, common_params=common_params) # Convert StemNodes to specific types for node in graph.nodes: node_obj = graph.nodes[node] node_type = node_obj.params_dict[Graph.NODE_TYPE_KEY] if node_type == cls.CONNECTION_KEY: # EL ORDEN IMPORTA ####################################################### if node_obj.is_root() and node_obj.is_leave(): new_node = nodes_cls['ONLY_ONE'](node_obj.id, node_obj.parent_graph, node_obj.params_dict) elif 'tolocal' in node_obj.params_dict['connectionParams'].keys() and \ node_obj.params_dict['connectionParams']['tolocal'] and node_obj.is_root(): new_node = nodes_cls['NONLOCALROOT'](node_obj.id, node_obj.parent_graph, node_obj.params_dict) elif 'tolocal' in node_obj.params_dict['connectionParams'].keys() and \ node_obj.params_dict['connectionParams']['tolocal'] and node_obj.is_leave(): new_node = nodes_cls['NONLOCALLEAVE'](node_obj.id, node_obj.parent_graph, node_obj.params_dict) elif 'temporal' in node_obj.params_dict['connectionParams'].keys() and \ node_obj.params_dict['connectionParams']['temporal']: new_node = nodes_cls['TMP'](node_obj.id, node_obj.parent_graph, node_obj.params_dict) elif node_obj.is_root(): new_node = nodes_cls['ROOT'](node_obj.id, node_obj.parent_graph, node_obj.params_dict) elif node_obj.is_leave(): new_node = nodes_cls['LEAVE'](node_obj.id, node_obj.parent_graph, node_obj.params_dict) else: new_node = nodes_cls['LINKER'](node_obj.id, node_obj.parent_graph, node_obj.params_dict) ######################################################################## else: node_obj.params_dict.update({'id': node_obj.id}) new_node = nodes_cls[node_type].parse(node_obj.params_dict, node_obj.parent_graph) graph.change_node(node, new_node) return graph def run(self, task, info_dict): # Lineal execution. Study graph theory for more complexity. ############## topo_order = list(nx.topological_sort(self.nx_graph)) for node in topo_order: info_dict[node] = {'progress': 0, 'status': task.KEY_PAUSE, 'description': "{} waiting".format(self.nodes[node].id)} for node in topo_order: print(node, 'EXECUTING NODE ------------------------') while task.FLAG_PAUSED: continue self.nodes[node].super_run(task.task_list, info_dict) ########################################################################## def clean_execution(self): leave_nodes = self.get_leaves() nodes_to_remove = [] for leave_node in [leave_node for leave_node in leave_nodes if not isinstance(self.nodes[leave_node], SubTaskNode)]: leave_node_obj = self.nodes[leave_node] for node in self.nodes: if isinstance(self.nodes[node], SubTaskNode): continue is_neighbour = nx.has_path(self.nx_graph, node, leave_node) if is_neighbour and not leave_node_obj.layer['is_map_server_element']: nodes_to_remove.append(node) self.nodes[node].layer.clean_layer() self.nodes[node].layer.clean_residuals()