X-Git-Url: https://plomlompom.com/repos/?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: