From 5cd43acb3c0391088f8f9fa52639c065fbc44f48 Mon Sep 17 00:00:00 2001 From: Unrud Date: Thu, 26 Apr 2018 00:07:42 +0200 Subject: [PATCH] vobject: apply PRs (Fixes #764, fixes #765) --- radicale_vobject/README.md | 6 ++++ radicale_vobject/icalendar.py | 60 ++++++++++++++++++++--------------- setup.py | 2 +- 3 files changed, 42 insertions(+), 26 deletions(-) diff --git a/radicale_vobject/README.md b/radicale_vobject/README.md index 33daf6f..10710a4 100644 --- a/radicale_vobject/README.md +++ b/radicale_vobject/README.md @@ -5,3 +5,9 @@ Fork of [VObject](https://github.com/eventable/vobject). Radicale VObject is licensed under the [Apache 2.0 license](http://www.apache.org/licenses/LICENSE-2.0). Upstream git commit: [c4ae08b767](https://github.com/eventable/vobject/commit/c4ae08b7678bfdeec3c6b2dcbf74d383fd27ed14) + +Applied PRs: + + * [RRULE: Fix VTODO without DTSTART (Fixes: #104)](https://github.com/eventable/vobject/pull/116) ([25379b7065](https://github.com/eventable/vobject/pull/116/commits/25379b7065c5503f44c2a019008a01fa0e9e6b7b)) + * [RRULE: Fix floating UNTIL with dateutil > 2.6.1](https://github.com/eventable/vobject/pull/115) ([0ec6ad3f9e](https://github.com/eventable/vobject/pull/115/commits/0ec6ad3f9ea51179abd7816fa137394feac2ea58)) + * [ignore escaped semi-colons in UNTIL value](https://github.com/eventable/vobject/pull/114) ([e07b94aa11](https://github.com/eventable/vobject/pull/114/commits/e07b94aa113cc709edde4e8e47053d6f778449ab)) \ No newline at end of file diff --git a/radicale_vobject/icalendar.py b/radicale_vobject/icalendar.py index bcc4fab..a44fffb 100644 --- a/radicale_vobject/icalendar.py +++ b/radicale_vobject/icalendar.py @@ -414,7 +414,21 @@ class RecurringComponent(Component): if addfunc is None: addfunc = getattr(rruleset, name) - dtstart = self.dtstart.value + try: + dtstart = self.dtstart.value + except (AttributeError, KeyError): + # Special for VTODO - try DUE property instead + try: + if self.name == "VTODO": + dtstart = self.due.value + else: + # if there's no dtstart, just return None + logging.error('failed to get dtstart with VTODO') + return None + except (AttributeError, KeyError): + # if there's no due, just return None + logging.error('failed to find DUE at all.') + return None if name in DATENAMES: if type(line.value[0]) == datetime.datetime: @@ -426,31 +440,22 @@ class RecurringComponent(Component): # ignore RDATEs with PERIOD values for now pass elif name in RULENAMES: - try: - dtstart = self.dtstart.value - except (AttributeError, KeyError): - # Special for VTODO - try DUE property instead - try: - if self.name == "VTODO": - dtstart = self.due.value - else: - # if there's no dtstart, just return None - logging.error('failed to get dtstart with VTODO') - return None - except (AttributeError, KeyError): - # if there's no due, just return None - logging.error('failed to find DUE at all.') - return None - # a Ruby iCalendar library escapes semi-colons in rrules, # so also remove any backslashes value = line.value.replace('\\', '') - rule = rrule.rrulestr( - value, dtstart=dtstart, - # If dtstart has no time zone, `until` - # shouldn't get one, either: - ignoretz=isinstance(dtstart, datetime.date)) - until = rule._until + # If dtstart has no time zone, `until` + # shouldn't get one, either: + ignoretz = (not isinstance(dtstart, datetime.datetime) or + dtstart.tzinfo is None) + try: + until = rrule.rrulestr(value, ignoretz=ignoretz)._until + except ValueError: + # WORKAROUND: dateutil<=2.7.2 doesn't set the time zone + # of dtstart + if ignoretz: + raise + utc_now = datetime.datetime.now(datetime.timezone.utc) + until = rrule.rrulestr(value, dtstart=utc_now)._until if until is not None and isinstance(dtstart, datetime.datetime) and \ @@ -458,7 +463,7 @@ class RecurringComponent(Component): # dateutil converts the UNTIL date to a datetime, # check to see if the UNTIL parameter value was a date vals = dict(pair.split('=') for pair in - line.value.upper().split(';')) + value.upper().split(';')) if len(vals.get('UNTIL', '')) == 8: until = datetime.datetime.combine(until.date(), dtstart.time()) @@ -488,7 +493,12 @@ class RecurringComponent(Component): if dtstart.tzinfo is None: until = until.replace(tzinfo=None) - rule._until = until + value_without_until = ';'.join( + pair for pair in value.split(';') + if pair.split('=')[0].upper() != 'UNTIL') + rule = rrule.rrulestr(value_without_until, + dtstart=dtstart, ignoretz=ignoretz) + rule._until = until # add the rrule or exrule to the rruleset addfunc(rule) diff --git a/setup.py b/setup.py index 1e97353..354735f 100755 --- a/setup.py +++ b/setup.py @@ -66,7 +66,7 @@ setup( packages=["radicale", "radicale_vobject"], package_data={"radicale": WEB_FILES}, entry_points={"console_scripts": ["radicale = radicale.__main__:run"]}, - install_requires=["python-dateutil==2.6.1"], + install_requires=["python-dateutil>=2.7.2"], setup_requires=pytest_runner, tests_require=tests_require, extras_require={