summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Bruederli <bruederli@kolabsys.com>2015-03-02 16:35:59 (GMT)
committerThomas Bruederli <bruederli@kolabsys.com>2015-03-02 16:36:39 (GMT)
commit403257f86465a53237bb88fd6c7f2d292ab9f041 (patch)
tree657fd660257180879d4fb83b704c8819a5b931f8
parentf955748696cae7f326187fbd32fdf400e672381e (diff)
downloadpykolab-403257f86465a53237bb88fd6c7f2d292ab9f041.tar.gz
Adapt itip.check_event_conflict() to new storage of single occurrences (#4726)
-rw-r--r--pykolab/itip/__init__.py20
-rw-r--r--tests/unit/test-011-itip.py42
2 files changed, 59 insertions, 3 deletions
diff --git a/pykolab/itip/__init__.py b/pykolab/itip/__init__.py
index 961c3dc..a81015b 100644
--- a/pykolab/itip/__init__.py
+++ b/pykolab/itip/__init__.py
@@ -159,6 +159,7 @@ def check_event_conflict(kolab_event, itip_event):
_es = to_dt(kolab_event.get_start())
_ee = to_dt(kolab_event.get_ical_dtend()) # use iCal style end date: next day for all-day events
_ev = kolab_event
+ _ei = 0
# naive loops to check for collisions in (recurring) events
# TODO: compare recurrence rules directly (e.g. matching time slot or weekday or monthday)
@@ -166,6 +167,7 @@ def check_event_conflict(kolab_event, itip_event):
_is = to_dt(itip_event['start'])
_ie = to_dt(itip_event['end'])
_iv = itip_event['xml']
+ _ii = 0
while not conflict and _is is not None:
# log.debug("* Comparing event dates at %s/%s with %s/%s" % (_es, _ee, _is, _ie), level=9)
@@ -174,24 +176,38 @@ def check_event_conflict(kolab_event, itip_event):
_ie = to_dt(itip_event['xml'].get_occurence_end_date(_is))
# get full occurrence to compare the dates from a possible exception
- if _is is not None and len(itip_event['xml'].get_exceptions()):
+ if _is is not None and itip_event['xml'].has_exceptions():
_ix = itip_event['xml'].get_instance(_is)
if _ix is not None:
_is = to_dt(_ix.get_start())
_ie = to_dt(_ix.get_end())
_iv = _ix
+ # iterate through all exceptions (non-recurring)
+ elif _is is None and not itip_event['xml'].is_recurring() and itip_event['xml'].has_exceptions() and len(itip_event['xml'].get_exceptions()) > _ii:
+ _ix = itip_event['xml'].get_exceptions()[_ii]
+ _is = to_dt(_ix.get_start())
+ _ie = to_dt(_ix.get_end())
+ _ii += 1
+
_es = to_dt(kolab_event.get_next_occurence(_es)) if kolab_event.is_recurring() else None
_ee = to_dt(kolab_event.get_occurence_end_date(_es))
# get full instance to compare the dates from a possible exception
- if _es is not None and len(kolab_event.get_exceptions()):
+ if _es is not None and kolab_event.has_exceptions():
_ex = kolab_event.get_instance(_es)
if _ex is not None:
_es = to_dt(_ex.get_start())
_ee = to_dt(_ex.get_end())
_ev = _ex
+ # iterate through all exceptions (non-recurring)
+ elif _es is None and not kolab_event.is_recurring() and kolab_event.has_exceptions() and len(kolab_event.get_exceptions()) > _ei:
+ _ex = kolab_event.get_exceptions()[_ei]
+ _es = to_dt(_ex.get_start())
+ _ee = to_dt(_ex.get_end())
+ _ei += 1
+
return conflict
diff --git a/tests/unit/test-011-itip.py b/tests/unit/test-011-itip.py
index 80b9df6..8179aa9 100644
--- a/tests/unit/test-011-itip.py
+++ b/tests/unit/test-011-itip.py
@@ -82,7 +82,7 @@ CALSCALE:GREGORIAN
METHOD:REQUEST
BEGIN:VEVENT
UID:626421779C777FBE9C9B85A80D04DDFA-A4BF5BBB9FEAA271
-DTSTAMP:20120713T1254140
+DTSTAMP:20120713T125414Z
DTSTART;TZID=3DEurope/London:20120713T100000
DTEND;TZID=3DEurope/London:20120713T110000
SUMMARY:test
@@ -477,6 +477,46 @@ class TestITip(unittest.TestCase):
event5.add_exception(exception)
self.assertFalse(itip.check_event_conflict(event5, itip_event), "No conflict with cancelled exception")
+ def test_002_check_event_conflict_single(self):
+ itip_event = itip.events_from_message(message_from_string(itip_non_multipart))[0]
+
+ event = Event()
+ event.set_start(datetime.datetime(2012,7,10, 9,30,0, tzinfo=itip_event['start'].tzinfo))
+ event.set_end(datetime.datetime(2012,7,10, 10,30,0, tzinfo=itip_event['start'].tzinfo))
+ event.set_recurrence_id(event.get_start())
+
+ dtstart = datetime.datetime(2012,7,13, 9,30,0, tzinfo=itip_event['start'].tzinfo)
+ second = Event(from_string=str(event))
+ second.set_start(dtstart)
+ second.set_end(dtstart + datetime.timedelta(hours=1))
+ second.set_recurrence_id(dtstart)
+ event.add_exception(second)
+
+ self.assertTrue(itip.check_event_conflict(event, itip_event), "Conflicting dates (exception)")
+
+ itip_event = itip.events_from_message(message_from_string(itip_non_multipart))[0]
+
+ dtstart = datetime.datetime(2012,7,15, 10,0,0, tzinfo=itip_event['start'].tzinfo)
+ second = Event(from_string=str(itip_event['xml']))
+ second.set_start(dtstart + datetime.timedelta(hours=1))
+ second.set_end(dtstart + datetime.timedelta(hours=2))
+ second.set_recurrence_id(dtstart)
+ itip_event['xml'].add_exception(second)
+ self.assertEqual(len(itip_event['xml'].get_exceptions()), 1)
+
+ event = Event()
+ event.set_start(datetime.datetime(2012,7,11, 9,30,0, tzinfo=itip_event['start'].tzinfo))
+ event.set_end(datetime.datetime(2012,7,11, 10,30,0, tzinfo=itip_event['start'].tzinfo))
+
+ self.assertFalse(itip.check_event_conflict(event, itip_event), "Conflicting dates (no)")
+
+ event = Event()
+ event.set_start(datetime.datetime(2012,7,15, 11,0,0, tzinfo=itip_event['start'].tzinfo))
+ event.set_end(datetime.datetime(2012,7,15, 11,30,0, tzinfo=itip_event['start'].tzinfo))
+
+ self.assertTrue(itip.check_event_conflict(event, itip_event), "Conflicting dates (exception)")
+
+
def test_003_send_reply(self):
itip_events = itip.events_from_message(message_from_string(itip_non_multipart))
itip.send_reply("resource-collection-car@example.org", itip_events, "SUMMARY=%(summary)s; STATUS=%(status)s; NAME=%(name)s;")