Index: 0.2.2/yagtd-0.2.2/src/yagtd.py =================================================================== --- 0.2.2.orig/yagtd-0.2.2/src/yagtd.py +++ 0.2.2/yagtd-0.2.2/src/yagtd.py @@ -298,6 +298,7 @@ class GTD(cmd.Cmd): def _disp(self, task): """Display the 'id' and a summary of the 'task'.""" + # NOTE: the return value of this function is used to save to disk! task_line = task['title'] if __debug__: @@ -844,7 +845,118 @@ class GTD(cmd.Cmd): print "%d%%%s" % (percent, self._colorize(next)) do_summary = do_status - + + def _get_deadlines_ordered(self): + # get tasks ordered by deadline, oldest first + tasks = {} # due -> task + for task in self.todo: + if not task['due'] or task['complete']: + continue + if not task['due'] in tasks: + tasks[task['due']] = [] + tasks[task['due']].append(task) + + dues = tasks.keys() + dues.sort() + + ordered = [] + + for due in dues: + ordered.extend(tasks[due]) + + return ordered + + def _get_deadline_string(self, task): + now = datetime.datetime.now() + daystart = datetime.datetime(year=now.year, month=now.month, + day=now.day) + dayend = daystart + datetime.timedelta(days=1) + + s = "" + due = task.get('due', None) + if due: + left = due - daystart + if due < daystart: + days = -left.days + if days == 1: + s = " [overdue one day]" + else: + s = " [overdue %s days]" % days + elif due < dayend: + s = " [due today]" + else: + if left.days == 1: + s = " [one day left]" + else: + s = " [%s days left]" % left.days + + return s + + s = "" + due = task.get('due', None) + if due: + left = due - now + if left < datetime.timedelta(days=1): + s = " [due today]" + elif left > datetime.timedelta(0): + s = " [%s days left]" % left.days + + def do_deadlines(self, line): + """Display upcoming tasks ordered by deadline. + GTD> deadlines #nb""" + + # Parse command line + nb = self._parse_args(line)[0] + + ordered = self._get_deadlines_ordered() + + # keep only upcoming tasks + now = datetime.datetime.now() + daystart = datetime.datetime(year=now.year, month=now.month, + day=now.day) + dayend = daystart + datetime.timedelta(days=1) + ordered = [t for t in ordered if t.get('due', None) >= daystart] + + if nb: ordered = ordered[:nb] # display only nb tasks + + for t in ordered: + # note about due + s = self._get_deadline_string(t) + + print self._disp(t) + s + + # Show number of tasks as result of search if more than 10 + if len(ordered) > 10: + print "%d due tasks found" % len(ordered) + + def do_overdue(self, line): + """Display overdue tasks ordered by deadline (including due today). + GTD> overdue #nb""" + + # Parse command line + nb = self._parse_args(line)[0] + + ordered = self._get_deadlines_ordered() + + # keep only overdue tasks + now = datetime.datetime.now() + daystart = datetime.datetime(year=now.year, month=now.month, + day=now.day) + dayend = daystart + datetime.timedelta(days=1) + ordered = [t for t in ordered if t.get('due', None) < dayend] + + if nb: ordered = ordered[:nb] # display only nb tasks + + for t in ordered: + # note about due + s = self._get_deadline_string(t) + + print self._disp(t) + s + + # Show number of tasks as result of search if more than 10 + if len(ordered) > 10: + print "%d overdue tasks found" % len(ordered) + # # Re-search. #