home · contact · privacy
Improve accounting scripts.
[misc] / todo.py
diff --git a/todo.py b/todo.py
index 7b8b83e5ddfe34aa42cb9e6b6e3021b3ceadde71..29c1226e2d4938605bb0a2b48749ce051340c6f3 100644 (file)
--- a/todo.py
+++ b/todo.py
@@ -3,7 +3,6 @@ import json
 from uuid import uuid4
 from datetime import datetime, timedelta
 from urllib.parse import parse_qs
-from jinja2 import Template
 from jinja2 import Environment as JinjaEnv, FileSystemLoader as JinjaFSLoader 
 from urllib.parse import urlparse
 db_path = '/home/plom/org/todo_new.json'
@@ -160,6 +159,7 @@ class Day:
             if v == self:
                 return k
 
+
 class Todo:
 
     def __init__(self, day, done=False, day_effort=None, comment='', day_tags=None, importance=1.0):
@@ -202,8 +202,8 @@ class Todo:
     def tags(self):
         return self.day_tags | self.task.tags
 
-    def is_empty(self):
-        return self.done or (self.day_effort is not None) or len(self.comment) > 0 or len(self.day_tags) > 0
+    def internals_empty(self):
+        return len(self.comment) == 0 and len(self.day_tags) == 0
 
 
 class TodoDB(PlomDB):
@@ -309,29 +309,45 @@ class TodoDB(PlomDB):
             task_rows.sort(key=lambda r: False if not r['todo'] else True, reverse=True)
         elif task_sort == 'comment':
             task_rows.sort(key=lambda r: '' if not r['todo'] else r['todo'].comment, reverse=True)
-        return j2env.get_template('day.html').render(db=self, action=self.prefix+'/day', prev_date=prev_date_str, next_date=next_date_str, task_rows=task_rows, sort=task_sort)
+        done_tasks = []
+        for uuid, task in self.tasks.items():
+            if uuid in self.selected_day.todos.keys():
+                todo = self.selected_day.todos[uuid]
+                if todo.done:
+                    done_tasks += [todo]
+        done_tasks.sort(key=lambda t: t.effort, reverse=True)
+        return j2env.get_template('day.html').render(db=self, action=self.prefix+'/day', prev_date=prev_date_str, next_date=next_date_str, task_rows=task_rows, sort=task_sort, done_tasks=done_tasks)
 
     def show_calendar(self, start_date_str, end_date_str):
         self.t_filter_and = ['calendar']
         self.t_filter_not = ['deleted']
         self.set_visibilities()
         days_to_show = {}
-        todays_date = str(datetime.now())[:10]
-        target_start_str = start_date_str if start_date_str else sorted(self.days.keys())[0]
-        target_start = todays_date if target_start_str == 'today' else target_start_str
-        target_end_str = end_date_str if end_date_str else sorted(self.days.keys())[-1]
-        target_end = todays_date if target_end_str == 'today' else target_end_str
-        start_date = datetime.strptime(target_start, DATE_FORMAT)
-        end_date = datetime.strptime(target_end, DATE_FORMAT)
-        for n in range(int((end_date - start_date).days) + 1):
-            current_date_obj = start_date + timedelta(n)
-            current_date = current_date_obj.strftime(DATE_FORMAT)
-            if current_date not in self.days.keys():
-                days_to_show[current_date] = self.add_day()
+        todays_date_str = str(datetime.now())[:10]
+        todays_date_obj = datetime.strptime(todays_date_str, DATE_FORMAT) 
+        yesterdays_date_obj = todays_date_obj - timedelta(1)
+        yesterdays_date_str = yesterdays_date_obj.strftime(DATE_FORMAT) 
+        start_date_obj = datetime.strptime(sorted(self.days.keys())[0], DATE_FORMAT)
+        if start_date_str and len(start_date_str) > 0:
+            if start_date_str in {'today', 'yesterday'}:
+                start_date_obj = todays_date_obj if start_date_str == 'today' else yesterdays_date_obj
             else:
-                days_to_show[current_date] = self.days[current_date]
-            days_to_show[current_date].weekday = datetime.strptime(current_date, DATE_FORMAT).strftime('%A')[:2]
-        return j2env.get_template('calendar.html').render(db=self, days=days_to_show, action=self.prefix+'/calendar', today=str(datetime.now())[:10], start_date=start_date_str, end_date=end_date_str)
+                start_date_obj = datetime.strptime(start_date_str, DATE_FORMAT)
+        end_date_obj = datetime.strptime(sorted(self.days.keys())[-1], DATE_FORMAT)
+        if end_date_str and len(end_date_str) > 0:
+            if end_date_str in {'today', 'yesterday'}:
+                end_date_obj = todays_date_obj if end_date_str == 'today' else yesterdays_date_obj
+            else:
+                end_date_obj = datetime.strptime(start_date_str, DATE_FORMAT)
+        for n in range(int((end_date_obj - start_date_obj).days) + 1):
+            current_date_obj = start_date_obj + timedelta(n)
+            current_date_str = current_date_obj.strftime(DATE_FORMAT)
+            if current_date_str not in self.days.keys():
+                days_to_show[current_date_str] = self.add_day()
+            else:
+                days_to_show[current_date_str] = self.days[current_date_str]
+            days_to_show[current_date_str].weekday = datetime.strptime(current_date_str, DATE_FORMAT).strftime('%A')[:2]
+        return j2env.get_template('calendar.html').render(db=self, days=days_to_show, action=self.prefix+'/calendar', start_date=start_date_str, end_date=end_date_str)
 
     def show_todo(self, task_uuid, selected_date, referer):
         if selected_date not in self.days.keys():
@@ -349,9 +365,9 @@ class TodoDB(PlomDB):
             todo = self.days[date].todos[task_uuid]
         else:
             todo = self.days[date].add_todo(task_uuid)
-        todo.day_effort = float(day_effort) if len(day_effort) > 0 else None
+        todo.day_effort = day_effort
         todo.done = done
-        todo.importance = float(importance)
+        todo.importance = importance
         return todo
 
     def collect_tags(self, tags_joined, tags_checked):
@@ -363,6 +379,8 @@ class TodoDB(PlomDB):
         return tags
 
     def update_todo(self, task_uuid, date, day_effort, done, comment, day_tags_joined, day_tags_checked, importance):
+        day_effort = float(day_effort) if len(day_effort) > 0 else None
+        importance = float(importance)
         todo = self.update_todo_mini(task_uuid, date, day_effort, done, importance)
         todo.comment = comment
         todo.day_tags = self.collect_tags(day_tags_joined, day_tags_checked) 
@@ -448,25 +466,35 @@ class TodoHandler(PlomHandler):
                 db.update_task(id_, postvars['title'][0], postvars['default_effort'][0], postvars['joined_tags'][0], collect_checked('tag_', postvars), collect_checked('link_', postvars))
 
         elif parsed_url.path == app_config['prefix'] + '/day':
+            # always store the two hide params in the URL if possible … TODO: find out if really necessary
             if 'expect_unchosen_done' in postvars.keys():
                 params_to_encode += [('hide_unchosen', int('hide_unchosen' in postvars.keys()))] + [('hide_done', int('hide_done' in postvars.keys()))]
+
             if 'selected_date' in postvars.keys():
-                 db.selected_date = postvars['selected_date'][0]
-                 if 't_uuid' in postvars.keys():
-                     for i, uuid in enumerate(postvars['t_uuid']):
-                         t = db.tasks[uuid]
-                         if uuid in db.selected_day.todos.keys() and ((not 'choose' in postvars) or uuid not in postvars['choose']) and not db.selected_day.todos[uuid].is_empty():
-                             del db.selected_day.todos[uuid]
-                     if 'choose' in postvars.keys():
-                         for i, uuid in enumerate(postvars['t_uuid']):
-                             uuids = postvars['choose']
-                             uuids += postvars['done'] if 'done' in postvars.keys() else []
-                             if uuid in uuids or postvars['day_effort'][i] != '' or (postvars['importance'][i] not in {'1.0', ''}):
-                                 done = 'done' in postvars and uuid in postvars['done']
-                                 db.update_todo_mini(uuid, db.selected_date, postvars['day_effort'][i], done, postvars['importance'][i])
-                 if 'day_comment' in postvars.keys():
-                     db.selected_day.comment = postvars['day_comment'][0]
-                 params_to_encode += [('selected_date', db.selected_date)]
+                db.selected_date = postvars['selected_date'][0]
+                if 'day_comment' in postvars.keys():
+                    db.selected_day.comment = postvars['day_comment'][0]
+                params_to_encode += [('selected_date', db.selected_date)]
+
+                # handle todo list updates via task UUIDs
+                if 't_uuid' in postvars.keys():
+                    for i, uuid in enumerate(postvars['t_uuid']):
+                        task = db.tasks[uuid]
+                        old_todo = None if not uuid in db.selected_day.todos.keys() else db.selected_day.todos[uuid]
+                        selects_as_todo = 'choose' in postvars and uuid in postvars['choose']
+                        too_much_keepworthy_data = ('done' in postvars and uuid in postvars['done']) or postvars['day_effort'][i] != '' or (old_todo and not old_todo.internals_empty())
+                        if old_todo and too_much_keepworthy_data and not selects_as_todo:
+                            raise PlomException('cannot deselect task as todo of preserve-worthy values')
+                        elif old_todo and not selects_as_todo:
+                            del db.selected_day.todos[uuid]
+                        else:
+                            done = ('done' in postvars) and (uuid in postvars['done'])
+                            day_effort_input = postvars['day_effort'][i]
+                            day_effort = float(day_effort_input) if len(day_effort_input) > 0 else None
+                            importance = float(postvars['importance'][i])
+                            if old_todo and old_todo.done == done and old_todo.day_effort == day_effort and old_todo.importance == importance:
+                                continue
+                            db.update_todo_mini(uuid, db.selected_date, day_effort, done, importance)
 
         if 'referer' in postvars.keys() and len(postvars['referer'][0]) > 0:
             homepage = postvars['referer'][0]
@@ -540,7 +568,6 @@ class TodoHandler(PlomHandler):
                 page = 'cookie unset!'
         else:
             start_date = get_param('start')
-            start_date = start_date if start_date else 'today'
             end_date = get_param('end')
             page = db.show_calendar(start_date, end_date)
         if parsed_url.path != app_config['prefix'] + '/unset_cookie':