diff options
-rw-r--r-- | pykolab/utils.py | 9 | ||||
-rw-r--r-- | pykolab/xml/event.py | 12 | ||||
-rw-r--r-- | tests/functional/resource_func.py | 3 | ||||
-rw-r--r-- | tests/functional/test_wallace/test_005_resource_invitation.py | 2 | ||||
-rw-r--r-- | tests/unit/test-011-itip.py | 12 | ||||
-rw-r--r-- | tests/unit/test-012-wallace_invitationpolicy.py | 12 | ||||
-rw-r--r-- | wallace/module_invitationpolicy.py | 20 | ||||
-rw-r--r-- | wallace/module_resources.py | 10 |
8 files changed, 62 insertions, 18 deletions
diff --git a/pykolab/utils.py b/pykolab/utils.py index d34daeb..f91ed8d 100644 --- a/pykolab/utils.py +++ b/pykolab/utils.py @@ -309,6 +309,15 @@ def stripped_message(message): return "\n%s\n" % ("\n".join(lines)) +def str2unicode(s, encoding='utf-8'): + if isinstance(s, unicode): + return s + try: + return unicode(s, encoding) + except: + pass + return s + def normalize(_object): if type(_object) == list: result = [] diff --git a/pykolab/xml/event.py b/pykolab/xml/event.py index 2eb1155..0e7c333 100644 --- a/pykolab/xml/event.py +++ b/pykolab/xml/event.py @@ -945,7 +945,6 @@ class Event(object): from email.MIMEBase import MIMEBase from email.MIMEText import MIMEText from email.Utils import COMMASPACE, formatdate - from email import Encoders msg = MIMEMultipart() organizer = self.get_organizer() @@ -1030,7 +1029,10 @@ class Event(object): from email.MIMEBase import MIMEBase from email.MIMEText import MIMEText from email.Utils import COMMASPACE, formatdate - from email import Encoders + + # encode unicode strings with quoted-printable + from email import charset + charset.add_charset('utf-8', charset.SHORTEST, charset.QP) msg = MIMEMultipart() @@ -1093,19 +1095,19 @@ class Event(object): else: msg_from = from_address - msg['From'] = msg_from + msg['From'] = utils.str2unicode(msg_from) msg['Date'] = formatdate(localtime=True) if subject is None: subject = _("Invitation for %s was %s") % (self.get_summary(), participant_status_label(participant_status)) - msg["Subject"] = subject + msg['Subject'] = utils.str2unicode(subject) if message_text is None: message_text = _("""This is an automated response to one of your event requests.""") - msg.attach(MIMEText(utils.stripped_message(message_text))) + msg.attach(MIMEText(utils.stripped_message(message_text), _charset='utf-8')) part = MIMEBase('text', 'calendar', charset='UTF-8', method=method) del part['MIME-Version'] # mime parts don't need this diff --git a/tests/functional/resource_func.py b/tests/functional/resource_func.py index ac80360..a7e4d90 100644 --- a/tests/functional/resource_func.py +++ b/tests/functional/resource_func.py @@ -15,7 +15,8 @@ def resource_add(type, cn, members=None, owner=None, **kw): 'cn': cn, 'kolabtargetfolder': "shared/Resources/" + cn + "@example.org", 'uniquemember': members, - 'owner': owner + 'owner': owner, + 'ou': 'ou=resources,dc=example,dc=org' } resource_details.update(kw) diff --git a/tests/functional/test_wallace/test_005_resource_invitation.py b/tests/functional/test_wallace/test_005_resource_invitation.py index 4e69f2f..885f4ba 100644 --- a/tests/functional/test_wallace/test_005_resource_invitation.py +++ b/tests/functional/test_wallace/test_005_resource_invitation.py @@ -574,7 +574,7 @@ class TestResourceInvitation(unittest.TestCase): def test_010_invalid_bookings(self): self.purge_mailbox(self.john['mailbox']) - itip_other = itip_invitation.replace("mailto:%s", "mailto:some-other-resource@example.org\nDESCRIPTION: Sent to %s") + itip_other = itip_invitation.replace("mailto:%s", "mailto:some-other-resource@example.org\nCOMMENT: Sent to %s") self.send_itip_invitation(self.audi['mail'], datetime.datetime(2014,3,22, 8,0,0), template=itip_other) time.sleep(1) diff --git a/tests/unit/test-011-itip.py b/tests/unit/test-011-itip.py index cb1b760..e5edee5 100644 --- a/tests/unit/test-011-itip.py +++ b/tests/unit/test-011-itip.py @@ -465,5 +465,13 @@ class TestITip(unittest.TestCase): self.assertEqual(message.get('Subject'), _("Invitation for %(summary)s was %(status)s") % { 'summary':'test', 'status':_accepted }) text = str(message.get_payload(0)); - self.assertIn('SUMMARY=test', text) - self.assertIn('STATUS=' + _accepted, text) + self.assertIn('SUMMARY=3Dtest', text) + self.assertIn('STATUS=3D' + _accepted, text) + + def test_004_send_reply_unicode(self): + itip_events = itip.events_from_message(message_from_string(itip_non_multipart.replace('SUMMARY:test', "SUMMARY:With äöü"))) + itip.send_reply("resource-collection-car@example.org", itip_events, "SUMMARY=%(summary)s; STATUS=%(status)s; NAME=%(name)s;") + + self.assertEqual(len(self.smtplog), 1) + self.assertIn("Subject: =?utf-8?q?Invitation_for_With_=C3=A4=C3=B6=C3=BC_was_Accepted?=", self.smtplog[0][2]) + self.assertIn('SUMMARY=3DWith =C3=A4=C3=B6=C3=BC', self.smtplog[0][2]) diff --git a/tests/unit/test-012-wallace_invitationpolicy.py b/tests/unit/test-012-wallace_invitationpolicy.py index 3366950..20e139d 100644 --- a/tests/unit/test-012-wallace_invitationpolicy.py +++ b/tests/unit/test-012-wallace_invitationpolicy.py @@ -1,3 +1,5 @@ +# -*- coding: utf-8 -*- + import os import pykolab import logging @@ -160,4 +162,12 @@ class TestWallaceInvitationpolicy(unittest.TestCase): self.assertFalse( MIP.is_auto_reply({ 'kolabinvitationpolicy':accept_some }, 'sam@example.org', 'event')) self.assertFalse( MIP.is_auto_reply({ 'kolabinvitationpolicy':accept_avail }, 'user@domain.com', 'event')) self.assertTrue( MIP.is_auto_reply({ 'kolabinvitationpolicy':accept_avail }, 'john@example.org', 'event')) -
\ No newline at end of file + + def test_006_send_update_notification(self): + itips = pykolab.itip.events_from_message(message_from_string(itip_multipart.replace('SUMMARY:test', 'SUMMARY:with äöü'))) + MIP.send_update_notification(itips[0]['xml'], { 'mail': 'sender@example.org' }, old=None, reply=True) + + self.assertEqual(len(self.smtplog), 1) + self.assertIn("Subject: =?utf-8?", self.smtplog[0][2]) + self.assertIn("The event 'with =C3=A4=C3=B6=C3=BC' at", self.smtplog[0][2]) + diff --git a/wallace/module_invitationpolicy.py b/wallace/module_invitationpolicy.py index 753547c..6adf82d 100644 --- a/wallace/module_invitationpolicy.py +++ b/wallace/module_invitationpolicy.py @@ -970,6 +970,10 @@ def send_update_notification(object, receiving_user, old=None, reply=True): from email.MIMEText import MIMEText from email.Utils import formatdate + # encode unicode strings with quoted-printable + from email import charset + charset.add_charset('utf-8', charset.SHORTEST, charset.QP) + organizer = object.get_organizer() orgemail = organizer.email() orgname = organizer.name() @@ -1053,12 +1057,12 @@ def send_update_notification(object, receiving_user, old=None, reply=True): message_text += "\n" + _("*** This is an automated message. Please do not reply. ***") # compose mime message - msg = MIMEText(utils.stripped_message(message_text)) + msg = MIMEText(utils.stripped_message(message_text), _charset='utf-8') msg['To'] = receiving_user['mail'] msg['Date'] = formatdate(localtime=True) - msg['Subject'] = _('"%s" has been updated') % (object.get_summary()) - msg['From'] = '"%s" <%s>' % (orgname, orgemail) if orgname else orgemail + msg['Subject'] = utils.str2unicode(_('"%s" has been updated') % (object.get_summary())) + msg['From'] = utils.str2unicode('"%s" <%s>' % (orgname, orgemail) if orgname else orgemail) smtp = smtplib.SMTP("localhost", 10027) @@ -1081,6 +1085,10 @@ def send_cancel_notification(object, receiving_user): from email.MIMEText import MIMEText from email.Utils import formatdate + # encode unicode strings with quoted-printable + from email import charset + charset.add_charset('utf-8', charset.SHORTEST, charset.QP) + log.debug(_("Send cancellation notification for %s %r to user %r") % ( object.type, object.uid, receiving_user['mail'] ), level=8) @@ -1111,12 +1119,12 @@ def send_cancel_notification(object, receiving_user): message_text += "\n" + _("*** This is an automated message. Please do not reply. ***") # compose mime message - msg = MIMEText(utils.stripped_message(message_text)) + msg = MIMEText(utils.stripped_message(message_text), _charset='utf-8') msg['To'] = receiving_user['mail'] msg['Date'] = formatdate(localtime=True) - msg['Subject'] = _('"%s" has been cancelled') % (object.get_summary()) - msg['From'] = '"%s" <%s>' % (orgname, orgemail) if orgname else orgemail + msg['Subject'] = utils.str2unicode(_('"%s" has been cancelled') % (object.get_summary())) + msg['From'] = utils.str2unicode('"%s" <%s>' % (orgname, orgemail) if orgname else orgemail) smtp = smtplib.SMTP("localhost", 10027) diff --git a/wallace/module_resources.py b/wallace/module_resources.py index 0b4d811..d1833eb 100644 --- a/wallace/module_resources.py +++ b/wallace/module_resources.py @@ -1197,6 +1197,10 @@ def send_owner_notification(resource, owner, itip_event, success=True): from email.MIMEText import MIMEText from email.Utils import formatdate + # encode unicode strings with quoted-printable + from email import charset + charset.add_charset('utf-8', charset.SHORTEST, charset.QP) + notify = False status = itip_event['xml'].get_attendee_by_email(resource['mail']).get_participant_status(True) @@ -1223,12 +1227,14 @@ def send_owner_notification(resource, owner, itip_event, success=True): message_text = owner_notification_text(resource, owner, itip_event['xml'], success) - msg = MIMEText(utils.stripped_message(message_text)) + msg = MIMEText(utils.stripped_message(message_text), _charset='utf-8') msg['To'] = owner['mail'] msg['From'] = resource['mail'] msg['Date'] = formatdate(localtime=True) - msg['Subject'] = _('Booking for %s has been %s') % (resource['cn'], participant_status_label(status) if success else _('failed')) + msg['Subject'] = utils.str2unicode(_('Booking for %s has been %s') % ( + resource['cn'], participant_status_label(status) if success else _('failed') + )) smtp = smtplib.SMTP("localhost", 10027) |