mirror of
https://github.com/Kozea/Radicale.git
synced 2025-10-18 22:01:59 +00:00
parent
126a31c82a
commit
5cd43acb3c
3 changed files with 42 additions and 26 deletions
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue