From 1f01eef2738b6ba7496bc3d61f2f675d053531ad Mon Sep 17 00:00:00 2001 From: Tobias Brox Date: Tue, 5 Nov 2024 22:41:55 +0100 Subject: [PATCH] allow strings instead of tuples as input for sort_keys in search. Updates https://github.com/python-caldav/caldav/issues/448 --- CHANGELOG.md | 6 ++++++ caldav/objects.py | 3 +++ tests/test_caldav.py | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 96adc50..e9a8a3b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,12 @@ The format of this file should adhere to [Keep a Changelog](https://keepachangel This project should more or less adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Added + +* By now `calendar.search(..., sort_keys=("DTSTART")` will work. Sort keys expects a list or a tuple, but it's easy to send an attribute by mistake. + ## [1.4.0] - 2024-11-05 * Lots of work lifting the project up to more modern standards and improving code, thanks to Georges Toth (github @sim0nx), Matthias Urlichs (github @smurfix) and @ArtemIsmagilov. While this shouldn't matter for existing users, it will make the library more future-proof. diff --git a/caldav/objects.py b/caldav/objects.py index ce8b67f..13cc740 100644 --- a/caldav/objects.py +++ b/caldav/objects.py @@ -1311,6 +1311,7 @@ def sort_key_func(x): > datetime.now().strftime("%F%H%M%S") ), } + ## ref https://github.com/python-caldav/caldav/issues/448 - allow strings instead of a sequence here for sort_key in sort_keys: val = comp.get(sort_key, None) if val is None: @@ -1327,6 +1328,8 @@ def sort_key_func(x): return ret if sort_keys: + if isinstance(sort_keys, str): + sort_keys = (sort_keys,) objects.sort(key=sort_key_func, reverse=sort_reverse) ## partial workaround for https://github.com/python-caldav/caldav/issues/201 diff --git a/tests/test_caldav.py b/tests/test_caldav.py index 4f3b00a..b3c6254 100644 --- a/tests/test_caldav.py +++ b/tests/test_caldav.py @@ -1500,6 +1500,40 @@ def testSearchEvent(self): assert len(all_events) == 3 assert all_events[0].instance.vevent.summary.value == "Our Blissful Anniversary" + ## A more robust check for the sort key + all_events = c.search(sort_keys=("DTSTART",)) + assert len(all_events) == 3 + assert str(all_events[0].icalendar_component["DTSTART"].dt) < str( + all_events[1].icalendar_component["DTSTART"].dt + ) + assert str(all_events[1].icalendar_component["DTSTART"].dt) < str( + all_events[2].icalendar_component["DTSTART"].dt + ) + all_events = c.search(sort_keys=("DTSTART",), sort_reverse=True) + assert str(all_events[0].icalendar_component["DTSTART"].dt) > str( + all_events[1].icalendar_component["DTSTART"].dt + ) + assert str(all_events[1].icalendar_component["DTSTART"].dt) > str( + all_events[2].icalendar_component["DTSTART"].dt + ) + + ## Ref https://github.com/python-caldav/caldav/issues/448 + all_events = c.search(sort_keys=("DTSTART")) + assert len(all_events) == 3 + assert str(all_events[0].icalendar_component["DTSTART"].dt) < str( + all_events[1].icalendar_component["DTSTART"].dt + ) + assert str(all_events[1].icalendar_component["DTSTART"].dt) < str( + all_events[2].icalendar_component["DTSTART"].dt + ) + all_events = c.search(sort_keys=("DTSTART"), sort_reverse=True) + assert str(all_events[0].icalendar_component["DTSTART"].dt) > str( + all_events[1].icalendar_component["DTSTART"].dt + ) + assert str(all_events[1].icalendar_component["DTSTART"].dt) > str( + all_events[2].icalendar_component["DTSTART"].dt + ) + def testSearchSortTodo(self): self.skip_on_compatibility_flag("read_only") self.skip_on_compatibility_flag("no_todo")