diff --git a/icalevents/icalparser.py b/icalevents/icalparser.py index 3f29427..c5c2814 100644 --- a/icalevents/icalparser.py +++ b/icalevents/icalparser.py @@ -219,9 +219,9 @@ def create_event(component, strict): else: event.attendee = str(None) - if component.get("uid"): + try: event.uid = component.get("uid").encode("utf-8").decode("ascii") - else: + except (AttributeError, UnicodeDecodeError): event.uid = str(uuid4()) # Be nice - treat every event as unique if component.get("organizer"): diff --git a/test/test_data/no_uid.ics b/test/test_data/no_uid.ics new file mode 100644 index 0000000..d1e1e61 --- /dev/null +++ b/test/test_data/no_uid.ics @@ -0,0 +1,40 @@ +BEGIN:VCALENDAR +METHOD:PUBLISH +PRODID:Microsoft Exchange Server 2010 +VERSION:2.0 +X-WR-CALNAME:Kalender +BEGIN:VTIMEZONE +TZID:Central European Standard Time +BEGIN:STANDARD +DTSTART:16010101T030000 +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=10 +END:STANDARD +BEGIN:DAYLIGHT +DTSTART:16010101T020000 +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=3 +END:DAYLIGHT +END:VTIMEZONE +BEGIN:VEVENT +SUMMARY:Free +DTSTART;VALUE=DATE:20210520 +DTEND;VALUE=DATE:20210521 +CLASS:PUBLIC +PRIORITY:5 +DTSTAMP:20210516T144840Z +TRANSP:TRANSPARENT +STATUS:CONFIRMED +SEQUENCE:0 +X-MICROSOFT-CDO-APPT-SEQUENCE:0 +X-MICROSOFT-CDO-BUSYSTATUS:FREE +X-MICROSOFT-CDO-INTENDEDSTATUS:BUSY +X-MICROSOFT-CDO-ALLDAYEVENT:TRUE +X-MICROSOFT-CDO-IMPORTANCE:1 +X-MICROSOFT-CDO-INSTTYPE:1 +X-MICROSOFT-DONOTFORWARDMEETING:FALSE +X-MICROSOFT-DISALLOW-COUNTER:FALSE +END:VEVENT +END:VCALENDAR diff --git a/test/test_data/non_ascii_uid.ics b/test/test_data/non_ascii_uid.ics new file mode 100644 index 0000000..e8d89e8 --- /dev/null +++ b/test/test_data/non_ascii_uid.ics @@ -0,0 +1,41 @@ +BEGIN:VCALENDAR +METHOD:PUBLISH +PRODID:Microsoft Exchange Server 2010 +VERSION:2.0 +X-WR-CALNAME:Kalender +BEGIN:VTIMEZONE +TZID:Central European Standard Time +BEGIN:STANDARD +DTSTART:16010101T030000 +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=10 +END:STANDARD +BEGIN:DAYLIGHT +DTSTART:16010101T020000 +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=3 +END:DAYLIGHT +END:VTIMEZONE +BEGIN:VEVENT +UID:🙉🙈👀 +SUMMARY:Free +DTSTART;VALUE=DATE:20210520 +DTEND;VALUE=DATE:20210521 +CLASS:PUBLIC +PRIORITY:5 +DTSTAMP:20210516T144840Z +TRANSP:TRANSPARENT +STATUS:CONFIRMED +SEQUENCE:0 +X-MICROSOFT-CDO-APPT-SEQUENCE:0 +X-MICROSOFT-CDO-BUSYSTATUS:FREE +X-MICROSOFT-CDO-INTENDEDSTATUS:BUSY +X-MICROSOFT-CDO-ALLDAYEVENT:TRUE +X-MICROSOFT-CDO-IMPORTANCE:1 +X-MICROSOFT-CDO-INSTTYPE:1 +X-MICROSOFT-DONOTFORWARDMEETING:FALSE +X-MICROSOFT-DISALLOW-COUNTER:FALSE +END:VEVENT +END:VCALENDAR diff --git a/test/test_icalevents.py b/test/test_icalevents.py index f1a1221..1abc629 100644 --- a/test/test_icalevents.py +++ b/test/test_icalevents.py @@ -954,3 +954,27 @@ class ICalEventsTests(unittest.TestCase): events = icalevents.events(file=ical, start=start, end=end, strict=True) self.assertEqual(len(events), 1) + + def test_no_uid(self): + ical = "test/test_data/no_uid.ics" + + # noinspection DuplicatedCode + start = date(2021, 1, 1) + end = date(2021, 12, 31) + + [event] = icalevents.events(file=ical, start=start, end=end) + + self.assertIsNot(event.uid, -1) + self.assertIsInstance(event.uid, str) + + def test_non_ascii_uid(self): + ical = "test/test_data/non_ascii_uid.ics" + + # noinspection DuplicatedCode + start = date(2021, 1, 1) + end = date(2021, 12, 31) + + [event] = icalevents.events(file=ical, start=start, end=end) + + self.assertIsNot(event.uid, -1) + self.assertIsInstance(event.uid, str)