5 commits - pykolab/itip pykolab/xml tests/functional tests/unit wallace/__init__.py wallace/module_resources.py
Thomas Brüderli
bruederli at kolabsys.com
Thu Oct 23 14:14:30 CEST 2014
pykolab/itip/__init__.py | 4
pykolab/xml/event.py | 28 ++++--
tests/functional/test_wallace/test_007_invitationpolicy.py | 4
tests/unit/test-011-itip.py | 57 +++++++++++++
wallace/__init__.py | 3
wallace/module_resources.py | 2
6 files changed, 85 insertions(+), 13 deletions(-)
New commits:
commit b3e71834dfbdbe51c730580aa92dae3ea6797516
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Thu Oct 23 08:14:26 2014 -0400
Fix datetime objects for camparison
diff --git a/tests/functional/test_wallace/test_007_invitationpolicy.py b/tests/functional/test_wallace/test_007_invitationpolicy.py
index 4807313..d18e1f3 100644
--- a/tests/functional/test_wallace/test_007_invitationpolicy.py
+++ b/tests/functional/test_wallace/test_007_invitationpolicy.py
@@ -672,7 +672,7 @@ class TestWallaceInvitationpolicy(unittest.TestCase):
self.purge_mailbox(self.john['mailbox'])
# send update with new date and incremented sequence
- new_start = datetime.datetime(2014,8,15, 15,0,0, tzinfo=pytz.timezone("Europe/Berlin"))
+ new_start = pytz.timezone("Europe/Berlin").localize(datetime.datetime(2014,8,15, 15,0,0))
self.send_itip_update(self.jane['mail'], uid, new_start, summary="test", sequence=1)
response = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('ACCEPTED') }, self.jane['mail'])
@@ -696,7 +696,7 @@ class TestWallaceInvitationpolicy(unittest.TestCase):
# send update with new but conflicting date and incremented sequence
self.create_calendar_event(datetime.datetime(2014,8,10, 10,30,0, tzinfo=pytz.timezone("Europe/Berlin")), user=self.jack)
- new_start = datetime.datetime(2014,8,10, 9,30,0, tzinfo=pytz.timezone("Europe/Berlin"))
+ new_start = pytz.timezone("Europe/Berlin").localize(datetime.datetime(2014,8,10, 9,30,0))
self.send_itip_update(self.jack['mail'], uid, new_start, summary="test (updated)", sequence=1)
response = self.check_message_received(self.itip_reply_subject % { 'summary':'test', 'status':participant_status_label('DECLINED') }, self.jack['mail'])
commit 325441d8e67eee543a12390cc955718743455c9f
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Thu Oct 23 07:39:27 2014 -0400
Break module iteration if the message has been consumed by any of the modules
diff --git a/wallace/__init__.py b/wallace/__init__.py
index 6e41654..6698666 100644
--- a/wallace/__init__.py
+++ b/wallace/__init__.py
@@ -80,6 +80,9 @@ def pickup_message(filepath, *args, **kw):
else:
# A module has returned False or None
continue_with_accept = False
+ # The message very likely has been consumed by the module that returned False
+ if not os.path.isfile(filepath):
+ break
if continue_with_accept:
cb_action_ACCEPT('wallace', filepath)
commit 843b5663f60fa4dc3029f6b48f45a5fae0942d46
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Thu Oct 23 07:38:15 2014 -0400
Don't disconnect LDAP after lookup
diff --git a/wallace/module_resources.py b/wallace/module_resources.py
index c9b5eef..3d16844 100644
--- a/wallace/module_resources.py
+++ b/wallace/module_resources.py
@@ -778,8 +778,6 @@ def resource_record_from_email_address(email_address):
resource_records = [ resource_records ]
log.debug(_("Resource record: %r") % (resource_records), level=8)
- auth.disconnect()
-
return resource_records
commit bdf46e31d5713e2ee216f6a96ecdab2f6fa60ada
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Thu Oct 23 07:37:49 2014 -0400
Convert unicode strings to utf-8 encoded strings when parsing iCal messages + add unit test for this
diff --git a/pykolab/xml/event.py b/pykolab/xml/event.py
index 30b754f..2eb1155 100644
--- a/pykolab/xml/event.py
+++ b/pykolab/xml/event.py
@@ -21,6 +21,20 @@ from recurrence_rule import RecurrenceRule
log = pykolab.getLogger('pykolab.xml_event')
+def ustr(s):
+ if not isinstance(s, unicode):
+ for cs in ['utf-8','latin-1']:
+ try:
+ s = unicode(s, cs)
+ break
+ except:
+ pass
+
+ if isinstance(s, unicode):
+ return s.encode('utf-8')
+
+ return s
+
def event_from_ical(string):
return Event(from_ical=string)
@@ -130,7 +144,7 @@ class Event(object):
self.event.setAttendees(self._attendees)
def add_category(self, category):
- self._categories.append(str(category))
+ self._categories.append(ustr(category))
self.event.setCategories(self._categories)
def add_exception_date(self, _datetime):
@@ -628,11 +642,11 @@ class Event(object):
self.event.setCreated(xmlutils.to_cdatetime(_datetime, False, True))
def set_description(self, description):
- self.event.setDescription(str(description))
+ self.event.setDescription(ustr(description))
def set_comment(self, comment):
if hasattr(self.event, 'setComment'):
- self.event.setComment(str(comment))
+ self.event.setComment(ustr(comment))
def set_dtstamp(self, _datetime):
self.event.setLastModified(xmlutils.to_cdatetime(_datetime, False, True))
@@ -697,7 +711,7 @@ class Event(object):
params = {}
if params.has_key('CN'):
- name = str(params['CN'])
+ name = ustr(params['CN'])
else:
name = None
@@ -756,7 +770,7 @@ class Event(object):
params = {}
if params.has_key('CN'):
- cn = str(params['CN'])
+ cn = ustr(params['CN'])
self.set_organizer(str(address), name=cn)
@@ -767,7 +781,7 @@ class Event(object):
self.set_sequence(sequence)
def set_ical_summary(self, summary):
- self.set_summary(str(summary))
+ self.set_summary(ustr(summary))
def set_ical_uid(self, uid):
self.set_uid(str(uid))
@@ -790,7 +804,7 @@ class Event(object):
self.event.setLastModified(xmlutils.to_cdatetime(_datetime, False, True))
def set_location(self, location):
- self.event.setLocation(str(location))
+ self.event.setLocation(ustr(location))
def set_organizer(self, email, name=None):
contactreference = ContactReference(email)
diff --git a/tests/unit/test-011-itip.py b/tests/unit/test-011-itip.py
index a08d05f..cb1b760 100644
--- a/tests/unit/test-011-itip.py
+++ b/tests/unit/test-011-itip.py
@@ -1,3 +1,5 @@
+# -*- coding: utf-8 -*-
+
import pykolab
import datetime
import pytz
@@ -253,6 +255,54 @@ END:VEVENT
END:VCALENDAR
"""
+itip_unicode = """MIME-Version: 1.0
+Content-Type: multipart/mixed;
+ boundary="=_c8894dbdb8baeedacae836230e3436fd"
+From: "Doe, John" <john.doe at example.org>
+Date: Tue, 25 Feb 2014 13:54:14 +0100
+Message-ID: <240fe7ae7e139129e9eb95213c1016d7 at example.org>
+User-Agent: Roundcube Webmail/0.9-0.3.el6.kolab_3.0
+To: resource-car-audia4 at example.org
+Subject: "test"
+
+--=_c8894dbdb8baeedacae836230e3436fd
+Content-Type: text/plain; charset=UTF-8; format=flowed
+Content-Transfer-Encoding: quoted-printable
+
+*test*
+
+--=_c8894dbdb8baeedacae836230e3436fd
+Content-Type: text/calendar; charset=UTF-8; method=REQUEST; name=event.ics
+Content-Disposition: attachment; filename=event.ics
+Content-Transfer-Encoding: quoted-printable
+
+
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Roundcube=20Webmail=200.9-0.3.el6.kolab_3.0//NONSGML=20Calendar//=
+EN
+CALSCALE:GREGORIAN
+METHOD:REQUEST
+BEGIN:VEVENT
+UID:eea25142-fb1c-4831-a02d-ac9fb4c16b70
+DTSTAMP:20140213T125414Z
+DTSTART;TZID=3DEurope/London:20140713T100000
+DTEND;TZID=3DEurope/London:20140713T140000
+SUMMARY:Testing =C3=9Cmlauts
+DESCRIPTION:Testing =C3=9Cmlauts
+LOCATION:Rue the Gen=C3=A8ve
+ORGANIZER;CN=3D"D=C3=BE,=20John":mailto:john.doe at example.org
+ATTENDEE;ROLE=3DREQ-PARTICIPANT;CUTYPE=3DRESOURCE;PARTSTAT=3DNEEDS-ACTION;R=
+SVP=3DTRUE:mailto:resource-car-audia4 at example.org
+ATTENDEE;ROLE=3DREQ-PARTICIPANT;PARTSTAT=3DTENTATIVE;CN=3DSomebody=20Else:m=
+ailto:somebody at else.com
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
+
+--=_c8894dbdb8baeedacae836230e3436fd--
+"""
+
itip_empty = """MIME-Version: 1.0
Date: Fri, 17 Jan 2014 13:51:50 +0100
From: <john.doe at example.org>
@@ -318,6 +368,13 @@ class TestITip(unittest.TestCase):
itips7 = itip.events_from_message(message_from_string(itip_non_multipart.replace("METHOD:REQUEST", "METHOD:PUBLISH").replace("method=REQUEST", "method=PUBLISH")))
self.assertEqual(len(itips7), 0, "Invalid METHOD")
+ # iTips with unicode data
+ itips8 = itip.events_from_message(message_from_string(itip_unicode))
+ self.assertEqual(len(itips8), 1)
+ xml = itips8[0]['xml']
+ self.assertEqual(xml.get_summary(), "Testing Ãmlauts")
+ self.assertEqual(xml.get_location(), "Rue the Genève")
+
def test_002_check_date_conflict(self):
astart = datetime.datetime(2014,7,13, 10,0,0)
commit e5ed7a38f7683069795a0fcdc38818e0cc3a7bf8
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Thu Oct 23 07:24:21 2014 -0400
Fix type check; include charset in debug output
diff --git a/pykolab/itip/__init__.py b/pykolab/itip/__init__.py
index 1a361c1..93dc8bf 100644
--- a/pykolab/itip/__init__.py
+++ b/pykolab/itip/__init__.py
@@ -48,7 +48,7 @@ def objects_from_message(message, objnames, methods=None):
# Get the itip_payload
itip_payload = part.get_payload(decode=True)
- log.debug(_("Raw iTip payload: %s") % (itip_payload), level=9)
+ log.debug(_("Raw iTip payload (%r): %r") % (part.get_param('charset'), itip_payload), level=9)
# Python iCalendar prior to 3.0 uses "from_string".
if hasattr(icalendar.Calendar, 'from_ical'):
@@ -89,7 +89,7 @@ def objects_from_message(message, objnames, methods=None):
if c.has_key('dtstart'):
itip['start'] = c['dtstart'].dt
- elif itip['type'] == 'VEVENT':
+ elif itip['type'] == 'event':
log.error(_("iTip event without a start"))
continue
More information about the commits
mailing list