From: Christian Heller Date: Fri, 14 Jun 2024 13:17:19 +0000 (+0200) Subject: Initialize Days with links to their Todos as early as possible. X-Git-Url: https://plomlompom.com/repos/%7B%7Bdb.prefix%7D%7D/static/new_day?a=commitdiff_plain;h=5ced0155ad11f5fb87aaa0848402e95f8ff49acd;p=plomtask Initialize Days with links to their Todos as early as possible. --- diff --git a/plomtask/days.py b/plomtask/days.py index 0815b9b..2531a01 100644 --- a/plomtask/days.py +++ b/plomtask/days.py @@ -1,6 +1,9 @@ """Collecting Day and date-related items.""" from __future__ import annotations +from typing import Any +from sqlite3 import Row from datetime import datetime, timedelta +from plomtask.exceptions import HandledException from plomtask.db import DatabaseConnection, BaseModel from plomtask.todos import Todo from plomtask.dating import (DATE_FORMAT, valid_date) @@ -11,16 +14,29 @@ class Day(BaseModel[str]): table_name = 'days' to_save = ['comment'] - def __init__(self, date: str, comment: str = '') -> None: + def __init__(self, + date: str, + comment: str = '', + init_empty_todo_list: bool = False + ) -> None: id_ = valid_date(date) super().__init__(id_) self.datetime = datetime.strptime(self.date, DATE_FORMAT) self.comment = comment - self.calendarized_todos: list[Todo] = [] + self.todos: list[Todo] | None = [] if init_empty_todo_list else None def __lt__(self, other: Day) -> bool: return self.date < other.date + @classmethod + def from_table_row(cls, db_conn: DatabaseConnection, row: Row | list[Any] + ) -> Day: + """Make from DB row, with linked Todos.""" + day = super().from_table_row(db_conn, row) + assert isinstance(day.id_, str) + day.todos = Todo.by_date(db_conn, day.id_) + return day + @classmethod def by_date_range_filled(cls, db_conn: DatabaseConnection, start: str, end: str) -> list[Day]: @@ -37,16 +53,16 @@ class Day(BaseModel[str]): return days days.sort() if start_date not in [d.date for d in days]: - days[:] = [Day(start_date)] + days + days[:] = [Day(start_date, init_empty_todo_list=True)] + days if end_date not in [d.date for d in days]: - days += [Day(end_date)] + days += [Day(end_date, init_empty_todo_list=True)] if len(days) > 1: gapless_days = [] for i, day in enumerate(days): gapless_days += [day] if i < len(days) - 1: while day.next_date != days[i+1].date: - day = Day(day.next_date) + day = Day(day.next_date, init_empty_todo_list=True) gapless_days += [day] days[:] = gapless_days return days @@ -85,7 +101,12 @@ class Day(BaseModel[str]): next_datetime = self.datetime + timedelta(days=1) return next_datetime.strftime(DATE_FORMAT) - def collect_calendarized_todos(self, db_conn: DatabaseConnection) -> None: - """Fill self.calendarized_todos.""" - self.calendarized_todos = [t for t in Todo.by_date(db_conn, self.date) - if t.calendarize] + @property + def calendarized_todos(self) -> list[Todo]: + """Return only those of self.todos that have .calendarize set.""" + if self.todos is None: + msg = 'Trying to return from un-initialized Day.todos.' + raise HandledException(msg) + # pylint: disable=not-an-iterable + # (after the above is-None test, self.todos _should_ be iterable!) + return [t for t in self.todos if t.calendarize] diff --git a/plomtask/db.py b/plomtask/db.py index 2ea7421..bd60968 100644 --- a/plomtask/db.py +++ b/plomtask/db.py @@ -368,7 +368,7 @@ class BaseModel(Generic[BaseModelId]): date_col: str = 'day' ) -> tuple[list[BaseModelInstance], str, str]: - """Return list of Days in database within (open) date_range interval. + """Return list of items in database within (open) date_range interval. If no range values provided, defaults them to 'yesterday' and 'tomorrow'. Knows to properly interpret these and 'today' as value. diff --git a/plomtask/http.py b/plomtask/http.py index 5ad3dd4..91db326 100644 --- a/plomtask/http.py +++ b/plomtask/http.py @@ -191,8 +191,6 @@ class TaskHandler(BaseHTTPRequestHandler): ret = Day.by_date_range_with_limits(self.conn, (start, end), 'id') days, start, end = ret days = Day.with_filled_gaps(days, start, end) - for day in days: - day.collect_calendarized_todos(self.conn) today = date_in_n_days(0) return {'start': start, 'end': end, 'days': days, 'today': today}