X-Git-Url: https://plomlompom.com/repos/foo.html?a=blobdiff_plain;f=plomtask%2Ftodos.py;h=336ec0350830ce5dfbdf5e85a92b3945608835d9;hb=54e6c8bccace28583cf9926aa00917a796628a00;hp=d060e230381d69dc53cacde6ab28fc37e6afefe6;hpb=c2004503dc42449f1fa129b8e56eeef0a6df4712;p=plomtask
diff --git a/plomtask/todos.py b/plomtask/todos.py
index d060e23..336ec03 100644
--- a/plomtask/todos.py
+++ b/plomtask/todos.py
@@ -1,5 +1,6 @@
"""Actionables."""
from __future__ import annotations
+from collections import namedtuple
from typing import Any
from sqlite3 import Row
from plomtask.db import DatabaseConnection, BaseModel
@@ -9,6 +10,10 @@ from plomtask.exceptions import (NotFoundException, BadFormatException,
HandledException)
+TodoStepsNode = namedtuple('TodoStepsNode',
+ ('item', 'is_todo', 'children', 'seen'))
+
+
class Todo(BaseModel, ConditionsRelations):
"""Individual actionable."""
@@ -134,6 +139,36 @@ class Todo(BaseModel, ConditionsRelations):
for condition in self.disables:
condition.is_active = False
+ def get_step_tree(self, seen_todos: set[int],
+ seen_conditions: set[int]) -> TodoStepsNode:
+ """Return tree of depended-on Todos and Conditions."""
+
+ def make_node(step: Todo | Condition) -> TodoStepsNode:
+ assert isinstance(step.id_, int)
+ is_todo = isinstance(step, Todo)
+ children = []
+ if is_todo:
+ assert isinstance(step, Todo)
+ seen = step.id_ in seen_todos
+ seen_todos.add(step.id_)
+ potentially_enabled = set()
+ for child in step.children:
+ for condition in child.enables:
+ potentially_enabled.add(condition)
+ children += [make_node(child)]
+ for condition in [c for c in step.conditions
+ if (not c.is_active)
+ and (c not in potentially_enabled)]:
+ children += [make_node(condition)]
+ else:
+ assert isinstance(step, Condition)
+ seen = step.id_ in seen_conditions
+ seen_conditions.add(step.id_)
+ return TodoStepsNode(step, is_todo, children, seen)
+
+ node = make_node(self)
+ return node
+
def add_child(self, child: Todo) -> None:
"""Add child to self.children, guard against recursion"""
def walk_steps(node: Todo) -> None: