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