diff --git a/epdb/legacy_api.py b/epdb/legacy_api.py index 1fed91fc..b340bd21 100644 --- a/epdb/legacy_api.py +++ b/epdb/legacy_api.py @@ -1967,6 +1967,9 @@ def add_pathway_edge(request, package_uuid, pathway_uuid, e: Form[CreateEdge]): description=e.edgeReason, ) + # Update depths as sideeffect of above operation + pw.update_depths() + return redirect(new_e.url) except ValueError: return 403, {"message": "Adding Edge failed!"} diff --git a/epdb/logic.py b/epdb/logic.py index 842f8678..6de2b73a 100644 --- a/epdb/logic.py +++ b/epdb/logic.py @@ -995,52 +995,9 @@ class PackageManager(object): print("Fixing Node depths...") total_pws = Pathway.objects.filter(package=pack).count() + for p, pw in enumerate(Pathway.objects.filter(package=pack)): - in_count = defaultdict(lambda: 0) - out_count = defaultdict(lambda: 0) - - for e in pw.edges: - # TODO check if this will remain - for react in e.start_nodes.all(): - out_count[str(react.uuid)] += 1 - - for prod in e.end_nodes.all(): - in_count[str(prod.uuid)] += 1 - - root_nodes = [] - for n in pw.nodes: - num_parents = in_count[str(n.uuid)] - if num_parents == 0: - # must be a root node or unconnected node - if n.depth != 0: - n.depth = 0 - n.save() - - # Only root node may have children - if out_count[str(n.uuid)] > 0: - root_nodes.append(n) - - levels = [root_nodes] - seen = set() - # Do a bfs to determine depths starting with level 0 a.k.a. root nodes - for i, level_nodes in enumerate(levels): - new_level = [] - for n in level_nodes: - for e in n.out_edges.all(): - for prod in e.end_nodes.all(): - if str(prod.uuid) not in seen: - old_depth = prod.depth - if old_depth != i + 1: - prod.depth = i + 1 - prod.save() - - new_level.append(prod) - - seen.add(str(n.uuid)) - - if new_level: - levels.append(new_level) - + pw.update_depths() print(f"{p + 1}/{total_pws} fixed.", end="\r") return pack diff --git a/epdb/models.py b/epdb/models.py index 311b148c..52930ad3 100644 --- a/epdb/models.py +++ b/epdb/models.py @@ -2178,6 +2178,52 @@ class Pathway(EnviPathModel, AliasMixin, ScenarioMixin, AdditionalInformationMix ): return Edge.create(self, start_nodes, end_nodes, rule, name=name, description=description) + def update_depths(self): + in_count = defaultdict(lambda: 0) + out_count = defaultdict(lambda: 0) + + for e in self.edges: + # TODO check if this will remain + for react in e.start_nodes.all(): + out_count[str(react.uuid)] += 1 + + for prod in e.end_nodes.all(): + in_count[str(prod.uuid)] += 1 + + root_nodes = [] + for n in self.nodes: + num_parents = in_count[str(n.uuid)] + if num_parents == 0: + # must be a root node or unconnected node + if n.depth != 0: + n.depth = 0 + n.save() + + # Only root node may have children + if out_count[str(n.uuid)] > 0: + root_nodes.append(n) + + levels = [root_nodes] + seen = set() + # Do a bfs to determine depths starting with level 0 a.k.a. root nodes + for i, level_nodes in enumerate(levels): + new_level = [] + for n in level_nodes: + for e in n.out_edges.all(): + for prod in e.end_nodes.all(): + if str(prod.uuid) not in seen: + old_depth = prod.depth + if old_depth != i + 1: + prod.depth = i + 1 + prod.save() + + new_level.append(prod) + + seen.add(str(n.uuid)) + + if new_level: + levels.append(new_level) + class Node(EnviPathModel, AliasMixin, ScenarioMixin, AdditionalInformationMixin): pathway = models.ForeignKey( diff --git a/epdb/views.py b/epdb/views.py index 0801540e..50385576 100644 --- a/epdb/views.py +++ b/epdb/views.py @@ -2506,6 +2506,9 @@ def package_pathway_edges(request, package_uuid, pathway_uuid): substrate_nodes, product_nodes, name=edge_name, description=edge_description ) + # Update depths as sideeffect of above operation + current_pathway.update_depths() + return redirect(current_pathway.url) else: