X-Git-Url: https://plomlompom.com/repos/%7B%7B%20web_path%20%7D%7D/decks/%7B%7Bdeck_id%7D%7D/cards/%7B%7Bcard_id%7D%7D/form?a=blobdiff_plain;f=plomtask%2Ftodos.py;h=705bd725e2ff662ab4f9f2e370e61169a413ff03;hb=HEAD;hp=af45f720ca6e2011fb52bd5af18582a2feca76f1;hpb=f0f10048714c1bbcf23a7fa6a934d126408845f3;p=plomtask diff --git a/plomtask/todos.py b/plomtask/todos.py index af45f72..f5388b5 100644 --- a/plomtask/todos.py +++ b/plomtask/todos.py @@ -1,7 +1,6 @@ """Actionables.""" from __future__ import annotations -from dataclasses import dataclass -from typing import Any +from typing import Any, Set from sqlite3 import Row from plomtask.db import DatabaseConnection, BaseModel from plomtask.processes import Process, ProcessStepsNode @@ -12,17 +11,33 @@ from plomtask.exceptions import (NotFoundException, BadFormatException, from plomtask.dating import valid_date -@dataclass class TodoNode: """Collects what's useful to know for Todo/Condition tree display.""" + # pylint: disable=too-few-public-methods todo: Todo seen: bool children: list[TodoNode] + def __init__(self, + todo: Todo, + seen: bool, + children: list[TodoNode]) -> None: + self.todo = todo + self.seen = seen + self.children = children + + @property + def as_dict(self) -> dict[str, object]: + """Return self as (json.dumps-coompatible) dict.""" + return {'todo': self.todo.id_, + 'seen': self.seen, + 'children': [c.as_dict for c in self.children]} + class Todo(BaseModel[int], ConditionsRelations): """Individual actionable.""" # pylint: disable=too-many-instance-attributes + # pylint: disable=too-many-public-methods table_name = 'todos' to_save = ['process_id', 'is_done', 'date', 'comment', 'effort', 'calendarize'] @@ -33,6 +48,13 @@ class Todo(BaseModel[int], ConditionsRelations): ('todo_children', 'parent', 'children', 0), ('todo_children', 'child', 'parents', 1)] to_search = ['comment'] + days_to_update: Set[str] = set() + children: list[Todo] + parents: list[Todo] + sorters = {'doneness': lambda t: t.is_done, + 'title': lambda t: t.title_then, + 'comment': lambda t: t.comment, + 'date': lambda t: t.date} # pylint: disable=too-many-arguments def __init__(self, id_: int | None, @@ -50,8 +72,8 @@ class Todo(BaseModel[int], ConditionsRelations): self.date = valid_date(date) self.comment = comment self.effort = effort - self.children: list[Todo] = [] - self.parents: list[Todo] = [] + self.children = [] + self.parents = [] self.calendarize = calendarize if not self.id_: self.calendarize = self.process.calendarize @@ -128,11 +150,9 @@ class Todo(BaseModel[int], ConditionsRelations): assert isinstance(todo.id_, int) for t_id in db_conn.column_where('todo_children', 'child', 'parent', todo.id_): - # pylint: disable=no-member todo.children += [cls.by_id(db_conn, t_id)] for t_id in db_conn.column_where('todo_children', 'parent', 'child', todo.id_): - # pylint: disable=no-member todo.parents += [cls.by_id(db_conn, t_id)] for name in ('conditions', 'blockers', 'enables', 'disables'): table = f'todo_{name}' @@ -258,7 +278,7 @@ class Todo(BaseModel[int], ConditionsRelations): """Return sum of performed efforts of self and all descendants.""" def walk_tree(node: Todo) -> float: - local_effort = 0 + local_effort = 0.0 for child in node.children: local_effort += walk_tree(child) return node.performed_effort + local_effort @@ -296,12 +316,17 @@ class Todo(BaseModel[int], ConditionsRelations): if self.effort and self.effort < 0 and self.is_deletable: self.remove(db_conn) return + if self.id_ is None: + self.__class__.days_to_update.add(self.date) super().save(db_conn) + for condition in self.enables + self.disables + self.conditions: + condition.save(db_conn) def remove(self, db_conn: DatabaseConnection) -> None: """Remove from DB, including relations.""" if not self.is_deletable: raise HandledException('Cannot remove non-deletable Todo.') + self.__class__.days_to_update.add(self.date) children_to_remove = self.children[:] parents_to_remove = self.parents[:] for child in children_to_remove: