From 51514478d48540e69cef16021a0b5a3520a0d0d4 Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Sat, 3 Feb 2024 11:39:21 -0800 Subject: [PATCH] Simplify handling of combining todo items with the same uid --- ical/list.py | 25 +++++-------------------- ical/todo.py | 2 +- 2 files changed, 6 insertions(+), 21 deletions(-) diff --git a/ical/list.py b/ical/list.py index 61c982f3..b064d65b 100644 --- a/ical/list.py +++ b/ical/list.py @@ -77,22 +77,6 @@ def _todos_by_uid(todos: list[Todo]) -> dict[str, list[Todo]]: return todos_by_uid -def _todo_iterable( - iterable: list[Todo], tzinfo: datetime.tzinfo -) -> Iterable[SortableItem[datetime.datetime | datetime.date | None, Todo]]: - """Create a sorted iterable from the list of events.""" - - def sortable_items() -> ( - Generator[SortableItem[datetime.datetime | datetime.date | None, Todo], None, None] - ): - for todo in iterable: - if todo.recurring: - continue - yield SortableItemValue(todo.due, todo) - - return SortedItemIterable(sortable_items, tzinfo) - - def _pick_todo(todos: list[Todo], tzinfo: datetime.tzinfo) -> Todo: """Pick a todo to return in a list from a list of recurring todos. @@ -101,14 +85,13 @@ def _pick_todo(todos: list[Todo], tzinfo: datetime.tzinfo) -> Todo: edited instance of a recurring todo has a recurrence-id that is different from the original todo. This function will return the next todo that is incomplete and has the latest due date. - - """ # For a recurring todo, the dtstart is after the last due date. Therefore - # we can stort items by dtstart and pick the last one that hasn't happened - iters = [_todo_iterable(todos, tzinfo=tzinfo)] + # we can stort items by dtstart and pick the last one that hasn't happened + iters = [] for todo in todos: if not (recur := todo.as_rrule()): + iters.append([SortableItemValue(todo.dtstart, todo)]) continue iters.append(RecurIterable(RecurAdapter(todo, tzinfo=tzinfo).get, recur)) @@ -120,6 +103,8 @@ def _pick_todo(todos: list[Todo], tzinfo: datetime.tzinfo) -> Todo: it = iter(root_iter) last = next(it, None) + if not last: + raise ValueError("Expected at least one item in the iterable") while cur := next(it, None): if cur.item.start_datetime is None or cur.item.start_datetime > now: break diff --git a/ical/todo.py b/ical/todo.py index a8baea28..a9b5a693 100644 --- a/ical/todo.py +++ b/ical/todo.py @@ -229,7 +229,7 @@ def as_rrule(self) -> Iterable[datetime.datetime | datetime.date] | None: This is only valid for events where `recurring` is True. """ - if not (self.rrule or self.rdate) or not self.start: + if not (self.rrule or self.rdate) or not self.computed_duration: return None return RulesetIterable( self.start,