From: Christian Heller Date: Sat, 18 May 2024 06:04:10 +0000 (+0200) Subject: Add Todo. and Process.calendarize to identify what Todos to show in calendar. X-Git-Url: https://plomlompom.com/repos/%7B%7B%20web_path%20%7D%7D/decks/%7B%7Bdeck_id%7D%7D/ledger?a=commitdiff_plain;h=e150bee233a648950061b716dc1780581105ede6;p=plomtask Add Todo. and Process.calendarize to identify what Todos to show in calendar. --- diff --git a/migrations/3_add_Todo_and_Process_calendarize.sql b/migrations/3_add_Todo_and_Process_calendarize.sql new file mode 100644 index 0000000..dcd65b2 --- /dev/null +++ b/migrations/3_add_Todo_and_Process_calendarize.sql @@ -0,0 +1,2 @@ +ALTER TABLE todos ADD COLUMN calendarize BOOLEAN NOT NULL DEFAULT FALSE; +ALTER TABLE processes ADD COLUMN calendarize BOOLEAN NOT NULL DEFAULT FALSE; diff --git a/migrations/init_2.sql b/migrations/init_2.sql deleted file mode 100644 index 17e2db5..0000000 --- a/migrations/init_2.sql +++ /dev/null @@ -1,114 +0,0 @@ -CREATE TABLE condition_descriptions ( - parent INTEGER NOT NULL, - timestamp TEXT NOT NULL, - description TEXT NOT NULL, - PRIMARY KEY (parent, timestamp), - FOREIGN KEY (parent) REFERENCES conditions(id) -); -CREATE TABLE condition_titles ( - parent INTEGER NOT NULL, - timestamp TEXT NOT NULL, - title TEXT NOT NULL, - PRIMARY KEY (parent, timestamp), - FOREIGN KEY (parent) REFERENCES conditions(id) -); -CREATE TABLE conditions ( - id INTEGER PRIMARY KEY, - is_active BOOLEAN NOT NULL -); -CREATE TABLE days ( - id TEXT PRIMARY KEY, - comment TEXT NOT NULL -); -CREATE TABLE process_conditions ( - process INTEGER NOT NULL, - condition INTEGER NOT NULL, - PRIMARY KEY (process, condition), - FOREIGN KEY (process) REFERENCES processes(id), - FOREIGN KEY (condition) REFERENCES conditions(id) -); -CREATE TABLE process_descriptions ( - parent INTEGER NOT NULL, - timestamp TEXT NOT NULL, - description TEXT NOT NULL, - PRIMARY KEY (parent, timestamp), - FOREIGN KEY (parent) REFERENCES processes(id) -); -CREATE TABLE process_disables ( - process INTEGER NOT NULL, - condition INTEGER NOT NULL, - PRIMARY KEY(process, condition), - FOREIGN KEY (process) REFERENCES processes(id), - FOREIGN KEY (condition) REFERENCES conditions(id) -); -CREATE TABLE process_efforts ( - parent INTEGER NOT NULL, - timestamp TEXT NOT NULL, - effort REAL NOT NULL, - PRIMARY KEY (parent, timestamp), - FOREIGN KEY (parent) REFERENCES processes(id) -); -CREATE TABLE process_enables ( - process INTEGER NOT NULL, - condition INTEGER NOT NULL, - PRIMARY KEY(process, condition), - FOREIGN KEY (process) REFERENCES processes(id), - FOREIGN KEY (condition) REFERENCES conditions(id) -); -CREATE TABLE process_steps ( - id INTEGER PRIMARY KEY, - owner INTEGER NOT NULL, - step_process INTEGER NOT NULL, - parent_step INTEGER, - FOREIGN KEY (owner) REFERENCES processes(id), - FOREIGN KEY (step_process) REFERENCES processes(id), - FOREIGN KEY (parent_step) REFERENCES process_steps(step_id) -); -CREATE TABLE process_titles ( - parent INTEGER NOT NULL, - timestamp TEXT NOT NULL, - title TEXT NOT NULL, - PRIMARY KEY (parent, timestamp), - FOREIGN KEY (parent) REFERENCES processes(id) -); -CREATE TABLE processes ( - id INTEGER PRIMARY KEY -); -CREATE TABLE todo_children ( - parent INTEGER NOT NULL, - child INTEGER NOT NULL, - PRIMARY KEY (parent, child), - FOREIGN KEY (parent) REFERENCES todos(id), - FOREIGN KEY (child) REFERENCES todos(id) -); -CREATE TABLE todo_conditions ( - todo INTEGER NOT NULL, - condition INTEGER NOT NULL, - PRIMARY KEY(todo, condition), - FOREIGN KEY (todo) REFERENCES todos(id), - FOREIGN KEY (condition) REFERENCES conditions(id) -); -CREATE TABLE todo_disables ( - todo INTEGER NOT NULL, - condition INTEGER NOT NULL, - PRIMARY KEY(todo, condition), - FOREIGN KEY (todo) REFERENCES todos(id), - FOREIGN KEY (condition) REFERENCES conditions(id) -); -CREATE TABLE todo_enables ( - todo INTEGER NOT NULL, - condition INTEGER NOT NULL, - PRIMARY KEY(todo, condition), - FOREIGN KEY (todo) REFERENCES todos(id), - FOREIGN KEY (condition) REFERENCES conditions(id) -); -CREATE TABLE todos ( - id INTEGER PRIMARY KEY, - process INTEGER NOT NULL, - is_done BOOLEAN NOT NULL, - day TEXT NOT NULL, - comment TEXT NOT NULL DEFAULT "", - effort REAL, - FOREIGN KEY (process) REFERENCES processes(id), - FOREIGN KEY (day) REFERENCES days(id) -); diff --git a/migrations/init_3.sql b/migrations/init_3.sql new file mode 100644 index 0000000..f261fd7 --- /dev/null +++ b/migrations/init_3.sql @@ -0,0 +1,116 @@ +CREATE TABLE condition_descriptions ( + parent INTEGER NOT NULL, + timestamp TEXT NOT NULL, + description TEXT NOT NULL, + PRIMARY KEY (parent, timestamp), + FOREIGN KEY (parent) REFERENCES conditions(id) +); +CREATE TABLE condition_titles ( + parent INTEGER NOT NULL, + timestamp TEXT NOT NULL, + title TEXT NOT NULL, + PRIMARY KEY (parent, timestamp), + FOREIGN KEY (parent) REFERENCES conditions(id) +); +CREATE TABLE conditions ( + id INTEGER PRIMARY KEY, + is_active BOOLEAN NOT NULL +); +CREATE TABLE days ( + id TEXT PRIMARY KEY, + comment TEXT NOT NULL +); +CREATE TABLE process_conditions ( + process INTEGER NOT NULL, + condition INTEGER NOT NULL, + PRIMARY KEY (process, condition), + FOREIGN KEY (process) REFERENCES processes(id), + FOREIGN KEY (condition) REFERENCES conditions(id) +); +CREATE TABLE process_descriptions ( + parent INTEGER NOT NULL, + timestamp TEXT NOT NULL, + description TEXT NOT NULL, + PRIMARY KEY (parent, timestamp), + FOREIGN KEY (parent) REFERENCES processes(id) +); +CREATE TABLE process_disables ( + process INTEGER NOT NULL, + condition INTEGER NOT NULL, + PRIMARY KEY(process, condition), + FOREIGN KEY (process) REFERENCES processes(id), + FOREIGN KEY (condition) REFERENCES conditions(id) +); +CREATE TABLE process_efforts ( + parent INTEGER NOT NULL, + timestamp TEXT NOT NULL, + effort REAL NOT NULL, + PRIMARY KEY (parent, timestamp), + FOREIGN KEY (parent) REFERENCES processes(id) +); +CREATE TABLE process_enables ( + process INTEGER NOT NULL, + condition INTEGER NOT NULL, + PRIMARY KEY(process, condition), + FOREIGN KEY (process) REFERENCES processes(id), + FOREIGN KEY (condition) REFERENCES conditions(id) +); +CREATE TABLE process_steps ( + id INTEGER PRIMARY KEY, + owner INTEGER NOT NULL, + step_process INTEGER NOT NULL, + parent_step INTEGER, + FOREIGN KEY (owner) REFERENCES processes(id), + FOREIGN KEY (step_process) REFERENCES processes(id), + FOREIGN KEY (parent_step) REFERENCES process_steps(step_id) +); +CREATE TABLE process_titles ( + parent INTEGER NOT NULL, + timestamp TEXT NOT NULL, + title TEXT NOT NULL, + PRIMARY KEY (parent, timestamp), + FOREIGN KEY (parent) REFERENCES processes(id) +); +CREATE TABLE processes ( + id INTEGER PRIMARY KEY, + calendarize BOOLEAN NOT NULL DEFAULT FALSE +); +CREATE TABLE todo_children ( + parent INTEGER NOT NULL, + child INTEGER NOT NULL, + PRIMARY KEY (parent, child), + FOREIGN KEY (parent) REFERENCES todos(id), + FOREIGN KEY (child) REFERENCES todos(id) +); +CREATE TABLE todo_conditions ( + todo INTEGER NOT NULL, + condition INTEGER NOT NULL, + PRIMARY KEY(todo, condition), + FOREIGN KEY (todo) REFERENCES todos(id), + FOREIGN KEY (condition) REFERENCES conditions(id) +); +CREATE TABLE todo_disables ( + todo INTEGER NOT NULL, + condition INTEGER NOT NULL, + PRIMARY KEY(todo, condition), + FOREIGN KEY (todo) REFERENCES todos(id), + FOREIGN KEY (condition) REFERENCES conditions(id) +); +CREATE TABLE todo_enables ( + todo INTEGER NOT NULL, + condition INTEGER NOT NULL, + PRIMARY KEY(todo, condition), + FOREIGN KEY (todo) REFERENCES todos(id), + FOREIGN KEY (condition) REFERENCES conditions(id) +); +CREATE TABLE todos ( + id INTEGER PRIMARY KEY, + process INTEGER NOT NULL, + is_done BOOLEAN NOT NULL, + day TEXT NOT NULL, + comment TEXT NOT NULL DEFAULT "", + effort REAL, + calendarize BOOLEAN NOT NULL DEFAULT FALSE, + FOREIGN KEY (process) REFERENCES processes(id), + FOREIGN KEY (day) REFERENCES days(id) +); diff --git a/plomtask/days.py b/plomtask/days.py index 5e97560..fe1ba44 100644 --- a/plomtask/days.py +++ b/plomtask/days.py @@ -3,6 +3,7 @@ from __future__ import annotations from datetime import datetime, timedelta from plomtask.exceptions import BadFormatException from plomtask.db import DatabaseConnection, BaseModel +from plomtask.todos import Todo DATE_FORMAT = '%Y-%m-%d' MIN_RANGE_DATE = '2024-01-01' @@ -36,6 +37,7 @@ class Day(BaseModel[str]): super().__init__(id_) self.datetime = datetime.strptime(self.date, DATE_FORMAT) self.comment = comment + self.calendarized_todos: list[Todo] = [] def __lt__(self, other: Day) -> bool: return self.date < other.date @@ -105,3 +107,8 @@ class Day(BaseModel[str]): """Return date succeeding date of this Day.""" 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] diff --git a/plomtask/db.py b/plomtask/db.py index 0e7df15..b4dc3e9 100644 --- a/plomtask/db.py +++ b/plomtask/db.py @@ -7,7 +7,7 @@ from sqlite3 import connect as sql_connect, Cursor, Row from typing import Any, Self, TypeVar, Generic from plomtask.exceptions import HandledException, NotFoundException -EXPECTED_DB_VERSION = 2 +EXPECTED_DB_VERSION = 3 MIGRATIONS_DIR = 'migrations' FILENAME_DB_SCHEMA = f'init_{EXPECTED_DB_VERSION}.sql' PATH_DB_SCHEMA = f'{MIGRATIONS_DIR}/{FILENAME_DB_SCHEMA}' @@ -131,6 +131,9 @@ class DatabaseFile: # pylint: disable=too-few-public-methods new_row += [f' {segment}'] new_row[0] = new_row[0].lstrip() new_row[-1] = new_row[-1].lstrip() + if new_row[-1] != ')' and new_row[-3][-1] != ',': + new_row[-3] = new_row[-3] + ',' + new_row[-2:] = [' ' + new_row[-1][:-1]] + [')'] new_rows += ['\n'.join(new_row)] return new_rows diff --git a/plomtask/http.py b/plomtask/http.py index d76ac05..080af8c 100644 --- a/plomtask/http.py +++ b/plomtask/http.py @@ -113,6 +113,8 @@ class TaskHandler(BaseHTTPRequestHandler): start = self.params.get_str('start') end = self.params.get_str('end') days = Day.all(self.conn, date_range=(start, end), fill_gaps=True) + for day in days: + day.collect_calendarized_todos(self.conn) return {'start': start, 'end': end, 'days': days} def do_GET_day(self) -> dict[str, object]: @@ -302,6 +304,7 @@ class TaskHandler(BaseHTTPRequestHandler): todo.set_enables(self.conn, self.form_data.get_all_int('enables')) todo.set_disables(self.conn, self.form_data.get_all_int('disables')) todo.is_done = len(self.form_data.get_all_str('done')) > 0 + todo.calendarize = len(self.form_data.get_all_str('calendarize')) > 0 todo.comment = self.form_data.get_str('comment', ignore_strict=True) todo.save(self.conn) for condition in todo.enables: @@ -325,6 +328,7 @@ class TaskHandler(BaseHTTPRequestHandler): self.form_data.get_all_int('condition')) process.set_enables(self.conn, self.form_data.get_all_int('enables')) process.set_disables(self.conn, self.form_data.get_all_int('disables')) + process.calendarize = self.form_data.get_all_str('calendarize') != [] process.save(self.conn) process.explicit_steps = [] steps: list[tuple[int | None, int, int | None]] = [] diff --git a/plomtask/processes.py b/plomtask/processes.py index 1778e4f..e136421 100644 --- a/plomtask/processes.py +++ b/plomtask/processes.py @@ -22,20 +22,21 @@ class ProcessStepsNode: class Process(BaseModel[int], ConditionsRelations): """Template for, and metadata for, Todos, and their arrangements.""" + # pylint: disable=too-many-instance-attributes table_name = 'processes' + to_save = ['calendarize'] to_save_versioned = ['title', 'description', 'effort'] to_save_relations = [('process_conditions', 'process', 'conditions'), ('process_enables', 'process', 'enables'), ('process_disables', 'process', 'disables')] - # pylint: disable=too-many-instance-attributes - - def __init__(self, id_: int | None) -> None: + def __init__(self, id_: int | None, calendarize: bool = False) -> None: super().__init__(id_) self.title = VersionedAttribute(self, 'process_titles', 'UNNAMED') self.description = VersionedAttribute(self, 'process_descriptions', '') self.effort = VersionedAttribute(self, 'process_efforts', 1.0) self.explicit_steps: list[ProcessStep] = [] + self.calendarize = calendarize self.conditions: list[Condition] = [] self.enables: list[Condition] = [] self.disables: list[Condition] = [] diff --git a/plomtask/todos.py b/plomtask/todos.py index 7cbe989..0fea234 100644 --- a/plomtask/todos.py +++ b/plomtask/todos.py @@ -23,7 +23,8 @@ class Todo(BaseModel[int], ConditionsRelations): """Individual actionable.""" # pylint: disable=too-many-instance-attributes table_name = 'todos' - to_save = ['process_id', 'is_done', 'date', 'comment', 'effort'] + to_save = ['process_id', 'is_done', 'date', 'comment', 'effort', + 'calendarize'] to_save_relations = [('todo_conditions', 'todo', 'conditions'), ('todo_enables', 'todo', 'enables'), ('todo_disables', 'todo', 'disables'), @@ -31,9 +32,12 @@ class Todo(BaseModel[int], ConditionsRelations): ('todo_children', 'child', 'parents')] # pylint: disable=too-many-arguments - def __init__(self, id_: int | None, process: Process, - is_done: bool, date: str, comment: str = '', - effort: None | float = None) -> None: + def __init__(self, id_: int | None, + process: Process, + is_done: bool, + date: str, comment: str = '', + effort: None | float = None, + calendarize: bool = False) -> None: super().__init__(id_) if process.id_ is None: raise NotFoundException('Process of Todo without ID (not saved?)') @@ -44,10 +48,12 @@ class Todo(BaseModel[int], ConditionsRelations): self.effort = effort self.children: list[Todo] = [] self.parents: list[Todo] = [] + self.calendarize = calendarize self.conditions: list[Condition] = [] self.enables: list[Condition] = [] self.disables: list[Condition] = [] if not self.id_: + self.calendarize = self.process.calendarize self.conditions = self.process.conditions[:] self.enables = self.process.enables[:] self.disables = self.process.disables[:] diff --git a/templates/calendar.html b/templates/calendar.html index 220e9bb..7724203 100644 --- a/templates/calendar.html +++ b/templates/calendar.html @@ -49,6 +49,14 @@ to {{day.comment|e}} +{% for todo in day.calendarized_todos %} + +[{% if todo.is_done %}X{% else %} {% endif %}] +{{todo.title.newest|e}} +{{todo.comment|e}} + +{% endfor %} + {% endfor %} {% endblock %} diff --git a/templates/process.html b/templates/process.html index d833c52..6dea493 100644 --- a/templates/process.html +++ b/templates/process.html @@ -55,6 +55,11 @@ add:
{% if process.id_ %} [
history]{% endif %} + +calendarize + + + conditions {{ macros.simple_checkbox_table("condition", process.conditions, "condition", "condition_candidates") }} diff --git a/templates/todo.html b/templates/todo.html index 6817cb9..efaabdd 100644 --- a/templates/todo.html +++ b/templates/todo.html @@ -33,6 +33,11 @@ + +calendarize + + + conditions {{ macros.simple_checkbox_table("condition", todo.conditions, "condition", "condition_candidates") }}