Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions test_files/thunderbird_duration_pt0s_workaround.ics
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
BEGIN:VCALENDAR
PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN
VERSION:2.0

BEGIN:VTIMEZONE
TZID:Europe/Berlin
BEGIN:DAYLIGHT
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
TZNAME:CEST
DTSTART:19700329T020000
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
TZNAME:CET
DTSTART:19701025T030000
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
END:STANDARD
END:VTIMEZONE

BEGIN:VEVENT
CREATED:20190812T160437Z
LAST-MODIFIED:20190813T140315Z
DTSTAMP:20190813T140315Z
UID:a13cca03-860a-4094-b162-e06f161a7681
SUMMARY:flummy
EXDATE:20190826T170000Z
RRULE:FREQ=WEEKLY;UNTIL=20190923T170000Z;INTERVAL=2
X-MOZ-LASTACK:20190812T164503Z
DTSTART;TZID=Europe/Berlin:20190812T190000
DTEND;TZID=Europe/Berlin:20190812T200000
DESCRIPTION:descr
LOCATION:location
SEQUENCE:2
TRANSP:OPAQUE
X-MOZ-GENERATION:5
BEGIN:VALARM
ACTION:DISPLAY
TRIGGER;VALUE=DURATION:-PT15M
DESCRIPTION:Default Mozilla Description
END:VALARM
END:VEVENT

BEGIN:VEVENT
CREATED:20190813T140257Z
LAST-MODIFIED:20190813T140315Z
DTSTAMP:20190813T140315Z
UID:a13cca03-860a-4094-b162-e06f161a7681
SUMMARY:flummy
RECURRENCE-ID;TZID=Europe/Berlin:20190909T190000
DTSTART;TZID=Europe/Berlin:20190909T130000
DTEND;TZID=Europe/Berlin:20190909T140000
DESCRIPTION:descr
LOCATION:location
SEQUENCE:3
TRANSP:OPAQUE
X-MOZ-GENERATION:5
DURATION:PT0S
CLASS:
BEGIN:VALARM
ACTION:DISPLAY
TRIGGER;VALUE=DURATION:-PT15M
DESCRIPTION:Default Mozilla Description
END:VALARM
END:VEVENT

END:VCALENDAR
8 changes: 8 additions & 0 deletions tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,14 @@ def test_parseParams(self):
['NEXT', 'Nope'], ['BAR']]
)

def test_thunderbird_duration_pt0s_workaround(self):
"""
Test parsing thundebird generated ics streams having both a duration of
0 seconds and a dtend attribute.
"""
cal = get_test_file("thunderbird_duration_pt0s_workaround.ics")
c = base.readOne(cal, validate=True)


class TestVcards(unittest.TestCase):
"""
Expand Down
24 changes: 17 additions & 7 deletions vobject/icalendar.py
Original file line number Diff line number Diff line change
Expand Up @@ -1161,13 +1161,23 @@ class VEvent(RecurringBehavior):
@classmethod
def validate(cls, obj, raiseException, *args):
if 'dtend' in obj.contents and 'duration' in obj.contents:
if raiseException:
m = "VEVENT components cannot contain both DTEND and DURATION\
components"
raise ValidateError(m)
return False
else:
return super(VEvent, cls).validate(obj, raiseException, *args)
# Hack: Thunderbird's lightning calendar sometimes generates
# VEvents with dtend and a zero duration. Clean up these errors.
ignore = True
for duration in obj.contents.get('duration', ()):
duration.transformToNative()
if duration.value != datetime.timedelta(0):
ignore = False
if ignore:
# Delete redundant zero duration
del obj.contents['duration']
else:
if raiseException:
m = "VEVENT components cannot contain both DTEND and DURATION\
components"
raise ValidateError(m)
return False
return super(VEvent, cls).validate(obj, raiseException, *args)

registerBehavior(VEvent)

Expand Down