diff options
-rw-r--r-- | pykolab/xml/event.py | 64 | ||||
-rw-r--r-- | tests/unit/test-003-event.py | 7 |
2 files changed, 66 insertions, 5 deletions
diff --git a/pykolab/xml/event.py b/pykolab/xml/event.py index 6242eaf..78a26dd 100644 --- a/pykolab/xml/event.py +++ b/pykolab/xml/event.py @@ -58,6 +58,7 @@ def event_from_message(message): class Event(object): type = 'event' + thisandfuture = False status_map = { None: kolabformat.StatusUndefined, @@ -191,8 +192,9 @@ class Event(object): # NOTE: Make sure to list(set()) or duplicates may arise for attr in list(set(event.singletons)): - ical_getter = 'get_ical_%s' % (attr.lower()) - default_getter = 'get_%s' % (attr.lower()) + _attr = attr.lower().replace('-', '') + ical_getter = 'get_ical_%s' % (_attr) + default_getter = 'get_%s' % (_attr) retval = None if hasattr(self, ical_getter): retval = getattr(self, ical_getter)() @@ -205,8 +207,9 @@ class Event(object): # NOTE: Make sure to list(set()) or duplicates may arise for attr in list(set(event.multiple)): - ical_getter = 'get_ical_%s' % (attr.lower()) - default_getter = 'get_%s' % (attr.lower()) + _attr = attr.lower().replace('-', '') + ical_getter = 'get_ical_%s' % (_attr) + default_getter = 'get_%s' % (_attr) retval = None if hasattr(self, ical_getter): retval = getattr(self, ical_getter)() @@ -575,6 +578,16 @@ class Event(object): return [ comment ] return None + def get_ical_recurrenceid(self): + rid = self.get_recurrence_id() + if isinstance(rid, datetime.datetime) or isinstance(rid, datetime.date): + prop = icalendar.vDatetime(rid) + if self.thisandfuture: + prop.params.update({'RANGE':'THISANDFUTURE'}) + return prop + + return None + def get_location(self): return self.event.location() @@ -616,6 +629,14 @@ class Event(object): self.set_uid(uuid.uuid4()) return self.get_uid() + def get_recurrence_id(self): + self.thisandfuture = self.event.thisAndFuture(); + return xmlutils.from_cdatetime(self.event.recurrenceID(), True) + + def get_thisandfuture(self): + self.thisandfuture = self.event.thisAndFuture(); + return self.thisandfuture + def get_sequence(self): return self.event.sequence() @@ -698,6 +719,7 @@ class Event(object): attr = attr.replace('-', '') ical_setter = 'set_ical_' + attr default_setter = 'set_' + attr + params = value.params if hasattr(value, 'params') else {} if isinstance(value, icalendar.vDDDTypes) and hasattr(value, 'dt'): value = value.dt @@ -706,6 +728,8 @@ class Event(object): self.add_category(value) elif attr == "class": self.set_classification(value) + elif attr == "recurrenceid": + self.set_ical_recurrenceid(value, params) elif hasattr(self, ical_setter): getattr(self, ical_setter)(value) elif hasattr(self, default_setter): @@ -800,6 +824,13 @@ class Event(object): def set_ical_uid(self, uid): self.set_uid(str(uid)) + def set_ical_recurrenceid(self, value, params): + try: + self.thisandfuture = params.get('RANGE', '') == 'THISANDFUTURE' + self.set_recurrence_id(value, self.thisandfuture) + except InvalidEventDateError, e: + pass + def set_lastmodified(self, _datetime=None): valid_datetime = False if isinstance(_datetime, datetime.date): @@ -875,6 +906,27 @@ class Event(object): self.uid = uid self.event.setUid(str(uid)) + def set_recurrence_id(self, _datetime, _thisandfuture=None): + valid_datetime = False + if isinstance(_datetime, datetime.date): + valid_datetime = True + + if isinstance(_datetime, datetime.datetime): + # If no timezone information is passed on, use the one from event start + if _datetime.tzinfo == None: + _start = self.get_start() + _datetime = _datetime.replace(tzinfo=_start.tzinfo) + + valid_datetime = True + + if not valid_datetime: + raise InvalidEventDateError, _("Event recurrence-id needs datetime.datetime instance") + + if _thisandfuture is None: + _thisandfuture = self.thisandfuture + + self.event.setRecurrenceID(xmlutils.to_cdatetime(_datetime), _thisandfuture) + def set_transparency(self, transp): return self.event.setTransparency(transp) @@ -1194,11 +1246,13 @@ class Event(object): instance = Event(from_string=str(self)) instance.set_start(next_start) instance.set_recurrence(kolabformat.RecurrenceRule()) # remove recurrence rules - instance.event.setRecurrenceID(instance.event.start(), False) + instance.event.setRecurrenceID(xmlutils.to_cdatetime(next_start), False) next_end = self.get_occurence_end_date(next_start) if next_end: instance.set_end(next_end) + # TODO: copy data from matching exception + return instance return None diff --git a/tests/unit/test-003-event.py b/tests/unit/test-003-event.py index 67481e3..876dd57 100644 --- a/tests/unit/test-003-event.py +++ b/tests/unit/test-003-event.py @@ -25,6 +25,7 @@ UID:7a35527d-f783-4b58-b404-b1389bd2fc57 DTSTAMP;VALUE=DATE-TIME:20140407T122311Z CREATED;VALUE=DATE-TIME:20140407T122245Z LAST-MODIFIED;VALUE=DATE-TIME:20140407T122311Z +RECURRENCE-ID;TZID=Europe/Zurich;RANGE=THISANDFUTURE:20140523T110000 DTSTART;TZID=Europe/Zurich;VALUE=DATE-TIME:20140523T110000 DURATION:PT1H30M0S RRULE:FREQ=WEEKLY;INTERVAL=1;COUNT=10 @@ -389,6 +390,8 @@ METHOD:REQUEST self.assertIsInstance(event.get_exception_dates()[0], datetime.datetime) self.assertEqual(len(event.get_alarms()), 1) self.assertEqual(len(event.get_attachments()), 2) + self.assertIsInstance(event.get_recurrence_id(), datetime.datetime) + self.assertEqual(event.thisandfuture, True) def test_018_ical_to_message(self): event = event_from_ical(ical_event) @@ -436,6 +439,7 @@ END:VEVENT self.event.set_sequence(3) self.event.set_classification('CONFIDENTIAL') self.event.add_custom_property('X-Custom', 'check') + self.event.set_recurrence_id(datetime.datetime(2014, 05, 23, 11, 0, 0), True) ical = icalendar.Calendar.from_ical(self.event.as_string_itip()) event = ical.walk('VEVENT')[0] @@ -446,6 +450,8 @@ END:VEVENT self.assertEqual(event['X-CUSTOM'], "check") self.assertIsInstance(event['dtstamp'].dt, datetime.datetime) self.assertEqual(event['class'], "CONFIDENTIAL") + self.assertIsInstance(event['recurrence-id'].dt, datetime.datetime) + self.assertEqual(event['recurrence-id'].params.get('RANGE'), 'THISANDFUTURE') def test_019_to_message_itip(self): self.event = Event() @@ -529,6 +535,7 @@ END:VEVENT # check get_next_instance() which returns a clone of the base event next_instance = self.event.get_next_instance(next_date) self.assertIsInstance(next_instance, Event) + self.assertIsInstance(next_instance.get_recurrence_id(), datetime.datetime) self.assertEqual(self.event.get_summary(), next_instance.get_summary()) self.assertEqual(next_instance.get_start().month, 7) self.assertFalse(next_instance.is_recurring()) |