3 commits - pykolab/xml tests/functional tests/unit wallace/module_invitationpolicy.py
Thomas Brüderli
bruederli at kolabsys.com
Wed Aug 6 20:23:15 CEST 2014
pykolab/xml/attendee.py | 10 ++
pykolab/xml/event.py | 6 +
tests/functional/test_wallace/test_007_invitationpolicy.py | 51 +++++++++++++
tests/unit/test-003-event.py | 6 +
wallace/module_invitationpolicy.py | 36 ++++++++-
5 files changed, 102 insertions(+), 7 deletions(-)
New commits:
commit 389a93cb32fd319309aaf95979a7dcaf0070234f
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Wed Aug 6 14:23:08 2014 -0400
Fix Attendee.copy_from(); new method Event.find_attendee() which is similar to get_attendee() but doesn't raise an exception
diff --git a/pykolab/xml/attendee.py b/pykolab/xml/attendee.py
index c4ccb96..087e832 100644
--- a/pykolab/xml/attendee.py
+++ b/pykolab/xml/attendee.py
@@ -108,9 +108,17 @@ class Attendee(kolabformat.Attendee):
def copy_from(self, obj):
if isinstance(obj, kolabformat.Attendee):
- kolabformat.Attendee.__init__(self, obj)
self.contactreference = ContactReference(obj.contact())
self.email = self.contactreference.get_email()
+ kolabformat.Attendee.__init__(self, self.contactreference)
+
+ # manually copy all properities, copy constructor doesn't work :-(
+ self.setRSVP(obj.rsvp())
+ self.setRole(obj.role())
+ self.setCutype(obj.cutype())
+ self.setPartStat(obj.partStat())
+ self.setDelegatedTo(obj.delegatedTo())
+ self.setDelegatedFrom(obj.delegatedFrom())
def delegate_from(self, delegators):
crefs = []
diff --git a/pykolab/xml/event.py b/pykolab/xml/event.py
index eac764d..6655b8c 100644
--- a/pykolab/xml/event.py
+++ b/pykolab/xml/event.py
@@ -296,6 +296,12 @@ class Event(object):
else:
raise ValueError, _("Invalid argument value attendee %r, must be basestring or Attendee") % (attendee)
+ def find_attendee(self, attendee):
+ try:
+ return self.get_attendee(attendee)
+ except:
+ return None
+
def get_attendee_by_email(self, email):
if email in [x.get_email() for x in self.get_attendees()]:
return [x for x in self.get_attendees() if x.get_email() == email][0]
commit 419ece40024c5c91e659473b49aa988270a44b72
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Wed Aug 6 14:21:40 2014 -0400
Handle iTip REPLY messages with delegation
diff --git a/tests/functional/test_wallace/test_007_invitationpolicy.py b/tests/functional/test_wallace/test_007_invitationpolicy.py
index 9bc808f..568a0e8 100644
--- a/tests/functional/test_wallace/test_007_invitationpolicy.py
+++ b/tests/functional/test_wallace/test_007_invitationpolicy.py
@@ -105,6 +105,27 @@ END:VEVENT
END:VCALENDAR
"""
+itip_delegated = """
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//pykolab-0.6.9-1//kolab.org//
+CALSCALE:GREGORIAN
+METHOD:REPLY
+BEGIN:VEVENT
+SUMMARY:%(summary)s
+UID:%(uid)s
+DTSTART;TZID=Europe/Berlin;VALUE=DATE-TIME:%(start)s
+DTEND;TZID=Europe/Berlin;VALUE=DATE-TIME:%(end)s
+DTSTAMP;VALUE=DATE-TIME:20140706T171038Z
+ORGANIZER;CN="Doe, John":MAILTO:%(organizer)s
+ATTENDEE;PARTSTAT=DELEGATED;DELEGATED-TO=jack at ripper.com;ROLE=NON-PARTICIPANT:mailto:%(mailto)s
+ATTENDEE;PARTSTAT=%(partstat)s;DELEGATED-FROM=%(mailto)s;ROLE=REQ-PARTICIPANT:mailto:jack at ripper.com
+PRIORITY:0
+SEQUENCE:%(sequence)d
+END:VEVENT
+END:VCALENDAR
+"""
+
mime_message = """MIME-Version: 1.0
Content-Type: multipart/mixed;
boundary="=_c8894dbdb8baeedacae836230e3436fd"
@@ -584,6 +605,36 @@ class TestWallaceInvitationpolicy(unittest.TestCase):
self.assertEqual(event.get_attachment_data(0), 'This is a text attachment')
+ def test_006_invitation_reply_delegated(self):
+ self.purge_mailbox(self.john['mailbox'])
+
+ start = datetime.datetime(2014,8,28, 14,30,0, tzinfo=pytz.timezone("Europe/Berlin"))
+ uid = self.create_calendar_event(start, user=self.john)
+
+ event = self.check_user_calendar_event(self.john['kolabtargetfolder'], uid)
+ self.assertIsInstance(event, pykolab.xml.Event)
+
+ # send a reply from jane to john
+ self.send_itip_reply(uid, self.jane['mail'], self.john['mail'], start=start, template=itip_delegated, partstat='NEEDS-ACTION')
+
+ # check for the updated event in john's calendar
+ time.sleep(10)
+ event = self.check_user_calendar_event(self.john['kolabtargetfolder'], uid)
+ self.assertIsInstance(event, pykolab.xml.Event)
+
+ attendee = event.get_attendee(self.jane['mail'])
+ self.assertIsInstance(attendee, pykolab.xml.Attendee)
+ self.assertEqual(attendee.get_participant_status(), kolabformat.PartDelegated)
+ # FIXME: self.assertEqual(len(attendee.get_delegated_to()), 1)
+ # FIXME: self.assertEqual(attendee.get_delegated_to(True)[0], 'jack at ripper.com')
+
+ delegatee = event.get_attendee('jack at ripper.com')
+ self.assertIsInstance(delegatee, pykolab.xml.Attendee)
+ self.assertEqual(delegatee.get_participant_status(), kolabformat.PartNeedsAction)
+ # FIXME: self.assertEqual(len(delegatee.get_delegated_from()), 1)
+ # FIXME: self.assertEqual(delegatee.get_delegated_from(True)[0], self.jane['mail'])
+
+
def test_007_invitation_cancel(self):
self.purge_mailbox(self.john['mailbox'])
diff --git a/wallace/module_invitationpolicy.py b/wallace/module_invitationpolicy.py
index 92e1fea..6dfc111 100644
--- a/wallace/module_invitationpolicy.py
+++ b/wallace/module_invitationpolicy.py
@@ -424,7 +424,7 @@ def process_itip_reply(itip_event, policy, recipient_email, sender_email, receiv
return MESSAGE_FORWARD
# find existing event in user's calendar
- # TODO: set/check lock to avoid concurrent wallace processes trying to update the same event simultaneously
+ # sets/checks lock to avoid concurrent wallace processes trying to update the same event simultaneously
existing = find_existing_event(itip_event['uid'], receiving_user, True)
if existing:
@@ -438,13 +438,41 @@ def process_itip_reply(itip_event, policy, recipient_email, sender_email, receiv
log.debug(_("Auto-updating event %r on iTip REPLY") % (existing.uid), level=8)
try:
+ existing_attendee = existing.get_attendee(sender_email)
existing.set_attendee_participant_status(sender_email, sender_attendee.get_participant_status(), rsvp=False)
except Exception, e:
log.error("Could not find corresponding attende in organizer's event: %r" % (e))
- # TODO: accept new participant if ACT_ACCEPT ?
- remove_write_lock(existing._lock_key)
- return MESSAGE_FORWARD
+ # append delegated-from attendee ?
+ if len(sender_attendee.get_delegated_from()) > 0:
+ existing._attendees.append(sender_attendee)
+ existing.event.setAttendees(existing._attendees)
+ else:
+ # TODO: accept new participant if ACT_ACCEPT ?
+ remove_write_lock(existing._lock_key)
+ return MESSAGE_FORWARD
+
+ # append delegated-to attendee
+ if len(sender_attendee.get_delegated_to()) > 0:
+ try:
+ delegatee_email = sender_attendee.get_delegated_to(True)[0]
+ sender_delegatee = itip_event['xml'].get_attendee_by_email(delegatee_email)
+ existing_delegatee = existing.find_attendee(delegatee_email)
+
+ if not existing_delegatee:
+ existing._attendees.append(sender_delegatee)
+ log.debug(_("Add delegatee: %r") % (sender_delegatee.to_dict()), level=9)
+ else:
+ existing_delegatee.copy_from(sender_delegatee)
+ log.debug(_("Update existing delegatee: %r") % (existing_delegatee.to_dict()), level=9)
+
+ # copy all parameters from replying attendee (e.g. delegated-to, role, etc.)
+ existing_attendee.copy_from(sender_attendee)
+ existing.event.setAttendees(existing._attendees)
+ log.debug(_("Update delegator: %r") % (existing_attendee.to_dict()), level=9)
+
+ except Exception, e:
+ log.error("Could not find delegated-to attendee: %r" % (e))
# update the organizer's copy of the event
if update_event(existing, receiving_user):
commit 31077c43c6ece15a6e5d9488e1c211e38abb2651
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Wed Aug 6 12:58:10 2014 -0400
Test DELEGATED-* parameters
diff --git a/tests/unit/test-003-event.py b/tests/unit/test-003-event.py
index 4736b19..fa5d0fe 100644
--- a/tests/unit/test-003-event.py
+++ b/tests/unit/test-003-event.py
@@ -460,8 +460,10 @@ END:VEVENT
break
self.assertEqual(len(itip_event['attendee']), 2)
- self.assertEqual(itip_event['attendee'][0].lower(), 'mailto:jane at doe.org')
- self.assertEqual(itip_event['attendee'][1].lower(), 'mailto:jack at ripper.com')
+ self.assertEqual(str(itip_event['attendee'][0]).lower(), 'mailto:jane at doe.org')
+ self.assertEqual(str(itip_event['attendee'][1]).lower(), 'mailto:jack at ripper.com')
+ self.assertEqual(itip_event['attendee'][0].params['delegated-to'], 'jack at ripper.com')
+ self.assertEqual(itip_event['attendee'][1].params['delegated-from'], 'jane at doe.org')
def test_020_calendaring_recurrence(self):
More information about the commits
mailing list