ya3

ya3 -- yet another appointment application
Log | Files | Refs

commit 427b1d341902830ce786c9e11b76c67ebc6ec469
parent d00ff2683b8ed0f2376981f1fc61ee2b57886382
Author: Matthias Balk <mbalk@mbalk.de>
Date:   Tue,  9 Feb 2021 19:10:50 +0100

support for vCal's `DURATION` value added

Diffstat:
Msrc/tests.py | 24+++++++++++++++++++++++-
Msrc/utils.py | 14+++++++++++++-
2 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/src/tests.py b/src/tests.py @@ -18,7 +18,7 @@ # along with ya3. If not, see <http://www.gnu.org/licenses/>. import unittest -from datetime import date, datetime +from datetime import date, datetime, timedelta import vobject @@ -51,5 +51,27 @@ class TestEvent2String(unittest.TestCase): utils.event2string(evt)) +class TestNormalize(unittest.TestCase): + + def setUp(self): + cal = vobject.iCalendar() + self.evt = cal.add('vevent') + self.evt.add('dtstart').value = datetime(2021, 2, 6, 13, 30, 0) + + def test_with_dtend(self): + self.evt.add('dtend').value = datetime(2021, 2, 6, 14, 30, 0) + norm = utils.normalize(self.evt) + self.assertEqual(datetime(2021, 2, 6, 14, 30, 0), norm.dtend.value) + + def test_with_duration(self): + self.evt.add('duration').value = timedelta(hours=7) + norm = utils.normalize(self.evt) + self.assertEqual(datetime(2021, 2, 6, 20, 30, 0), norm.dtend.value) + + def test_no_dtend_no_duration(self): + norm = utils.normalize(self.evt) + self.assertTrue(norm.dtstart.value < norm.dtend.value) + + if __name__ == '__main__': unittest.main() diff --git a/src/utils.py b/src/utils.py @@ -45,6 +45,17 @@ def parse2local(dt, force_datetime=False): return dt +def normalize(event): + if 'dtend' not in event.contents: + event.add('dtend') + if 'duration' in event.contents: + event.dtend.value = event.dtstart.value + event.duration.value + else: + event.dtend.value = event.dtstart.value + config.DEFAULT_DURATION + + return event + + def get_events(icsfilenames, ignore_configured_range=False): def _is_in_range(event): @@ -59,7 +70,8 @@ def get_events(icsfilenames, ignore_configured_range=False): for filename in icsfilenames: with open(filename) as f: for cal in vobject.readComponents(f): - events.extend(filter(_is_in_range, cal.vevent_list)) + events.extend(filter(_is_in_range, + map(normalize, cal.vevent_list))) return sorted(events, key=lambda ev: parse2local(ev.dtstart.value, force_datetime=True))