INSTALL pykolab/xml tests/unit

Thomas Brüderli bruederli at kolabsys.com
Tue Mar 4 14:51:16 CET 2014


 INSTALL                      |    2 +
 pykolab/xml/event.py         |   41 +++++++++++++++++++++++++++++++++++++
 pykolab/xml/utils.py         |    3 ++
 tests/unit/test-003-event.py |   47 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 93 insertions(+)

New commits:
commit 26adad180f8ada3a21038ddbc6fc1bfa43284ca3
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date:   Tue Mar 4 08:39:51 2014 -0500

    Use libkolab bindings to compute recurring event instances + add tests for this

diff --git a/INSTALL b/INSTALL
index 6000929..162869b 100644
--- a/INSTALL
+++ b/INSTALL
@@ -9,4 +9,6 @@
 
 * python-icalendar
 * python-kolabformat
+* python-kolab
 * python-nose
+* python-twisted-core
diff --git a/pykolab/xml/event.py b/pykolab/xml/event.py
index 70dfea2..a4e10f0 100644
--- a/pykolab/xml/event.py
+++ b/pykolab/xml/event.py
@@ -762,6 +762,47 @@ class Event(object):
 
         return msg
 
+    def to_event_cal(self):
+        from kolab.calendaring import EventCal
+        return EventCal(self.event)
+
+    def get_next_occurence(self, datetime):
+        if not hasattr(self, 'eventcal'):
+            self.eventcal = self.to_event_cal()
+
+        next_cdatetime = self.eventcal.getNextOccurence(xmlutils.to_cdatetime(datetime, True))
+        return xmlutils.from_cdatetime(next_cdatetime, True) if next_cdatetime is not None else None
+
+    def get_occurence_end_date(self, datetime):
+        if not hasattr(self, 'eventcal'):
+            return None
+
+        end_cdatetime = self.eventcal.getOccurenceEndDate(xmlutils.to_cdatetime(datetime, True))
+        return xmlutils.from_cdatetime(end_cdatetime, True) if end_cdatetime is not None else None
+
+    def get_last_occurrence(self):
+        if not hasattr(self, 'eventcal'):
+            self.eventcal = self.to_event_cal()
+
+        last = self.eventcal.getLastOccurrence()
+        return xmlutils.from_cdatetime(last, True) if last is not None else None
+
+    def get_next_instance(self, datetime):
+        next_start = self.get_next_occurence(datetime)
+        if next_start:
+            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)
+            next_end = self.get_occurence_end_date(next_start)
+            if next_end:
+                instance.set_end(next_end)
+
+            return instance
+
+        return None
+
+
 class EventIntegrityError(Exception):
     def __init__(self, message):
         Exception.__init__(self, message)
diff --git a/pykolab/xml/utils.py b/pykolab/xml/utils.py
index c09da54..c4d123c 100644
--- a/pykolab/xml/utils.py
+++ b/pykolab/xml/utils.py
@@ -21,6 +21,9 @@ def from_cdatetime(_cdatetime, with_timezone=True):
     """
         Convert from kolabformat.cDateTime to datetime.date(time)
     """
+    if not _cdatetime.isValid():
+        return None
+
     (
         year,
         month,
diff --git a/tests/unit/test-003-event.py b/tests/unit/test-003-event.py
index b90333a..5e77bc8 100644
--- a/tests/unit/test-003-event.py
+++ b/tests/unit/test-003-event.py
@@ -147,5 +147,52 @@ END:VCALENDAR
         self.assertEqual(event['summary'], "test")
         self.assertIsInstance(event['dtstamp'].dt, datetime.datetime)
 
+    def test_020_calendaring_recurrence(self):
+        rrule = kolabformat.RecurrenceRule()
+        rrule.setFrequency(kolabformat.RecurrenceRule.Monthly)
+        rrule.setCount(10)
+
+        self.event = Event()
+        self.event.set_recurrence(rrule);
+
+        _start = datetime.datetime(2014, 5, 1, 11, 30, 00, tzinfo=pytz.timezone("Europe/London"))
+        self.event.set_start(_start)
+        self.event.set_end(_start + datetime.timedelta(hours=2))
+
+        next_date = self.event.get_next_occurence(_start)
+        self.assertIsInstance(next_date, datetime.datetime)
+        self.assertEqual(next_date.month, 6)
+        self.assertEqual(next_date.day, 1)
+
+        end_date = self.event.get_occurence_end_date(next_date)
+        self.assertIsInstance(end_date, datetime.datetime)
+        self.assertEqual(end_date.month, 6)
+        self.assertEqual(end_date.hour, 13)
+
+        self.assertEqual(self.event.get_next_occurence(next_date).month, 7)
+
+        last_date = self.event.get_last_occurrence()
+        self.assertIsInstance(last_date, datetime.datetime)
+        self.assertEqual(last_date.year, 2015)
+        self.assertEqual(last_date.month, 2)
+
+        self.assertEqual(self.event.get_next_occurence(last_date), None)
+
+        # 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.assertEqual(self.event.get_summary(), next_instance.get_summary())
+        self.assertEqual(next_instance.get_start().month, 7)
+
+    def test_021_calendaring_no_recurrence(self):
+        _start = datetime.datetime(2014, 2, 1, 14, 30, 00, tzinfo=pytz.timezone("Europe/London"))
+        self.event = Event()
+        self.event.set_start(_start)
+        self.event.set_end(_start + datetime.timedelta(hours=2))
+
+        self.assertEqual(self.event.get_next_occurence(_start), None)
+        self.assertEqual(self.event.get_last_occurrence(), None)
+
+
 if __name__ == '__main__':
     unittest.main()




More information about the commits mailing list