home · contact · privacy
Initialize Days with links to their Todos as early as possible.
authorChristian Heller <c.heller@plomlompom.de>
Fri, 14 Jun 2024 13:17:19 +0000 (15:17 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Fri, 14 Jun 2024 13:17:19 +0000 (15:17 +0200)
plomtask/days.py
plomtask/db.py
plomtask/http.py

index 0815b9bde6e515381f644fd33a120b880b533abb..2531a011f1875a4819337adcd7e59c7a08355af4 100644 (file)
@@ -1,6 +1,9 @@
 """Collecting Day and date-related items."""
 from __future__ import annotations
 """Collecting Day and date-related items."""
 from __future__ import annotations
+from typing import Any
+from sqlite3 import Row
 from datetime import datetime, timedelta
 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)
 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']
 
     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
         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
 
 
     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]:
     @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]:
             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]:
         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:
         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
                         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)
 
         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]
index 2ea7421feec578dab3fb8ba9e1eecf547eb6a36c..bd609685096b9d2dbc3dd0b0ea4243ec47904058 100644 (file)
@@ -368,7 +368,7 @@ class BaseModel(Generic[BaseModelId]):
                                   date_col: str = 'day'
                                   ) -> tuple[list[BaseModelInstance], str,
                                              str]:
                                   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.
 
         If no range values provided, defaults them to 'yesterday' and
         'tomorrow'. Knows to properly interpret these and 'today' as value.
index 5ad3dd43332e3106d66a0327158d4aebcf690bdb..91db32601c24c91c49db75df4f9ca2b05fd9b944 100644 (file)
@@ -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)
         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}
 
         today = date_in_n_days(0)
         return {'start': start, 'end': end, 'days': days, 'today': today}