[Erp5-report] r18559 - /erp5/trunk/products/ERP5/Tool/NotificationTool.py
nobody at svn.erp5.org
nobody at svn.erp5.org
Mon Dec 31 10:57:49 CET 2007
Author: jp
Date: Mon Dec 31 10:57:49 2007
New Revision: 18559
URL: http://svn.erp5.org?rev=18559&view=rev
Log:
Support more cases for notification, including default notification when no recipient is provided. Added a function here to build Mail messages.
Modified:
erp5/trunk/products/ERP5/Tool/NotificationTool.py
Modified: erp5/trunk/products/ERP5/Tool/NotificationTool.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/Tool/NotificationTool.py?rev=18559&r1=18558&r2=18559&view=diff
==============================================================================
--- erp5/trunk/products/ERP5/Tool/NotificationTool.py (original)
+++ erp5/trunk/products/ERP5/Tool/NotificationTool.py Mon Dec 31 10:57:49 2007
@@ -38,7 +38,78 @@
from Products.ERP5Type import Permissions
from Products.ERP5 import _dtmldir
+from cStringIO import StringIO
+from mimetypes import guess_type
+from email.MIMEMultipart import MIMEMultipart
+from email.MIMEText import MIMEText
+from email.MIMEBase import MIMEBase
+from email.Header import make_header
+from email import Encoders
+
from zLOG import LOG, INFO
+
+def buildEmailMessage(from_url, to_url, msg=None,
+ subject=None, attachment_list=None,
+ extra_headers=None):
+ """
+ Builds a mail message which is ready to be
+ sent by Zope MailHost.
+
+ * attachment_list is a list of dictionnaries with those keys:
+ - name : name of the attachment,
+ - content: data of the attachment
+ - mime_type: mime-type corresponding to the attachment
+ * extra_headers is a dictionnary of custom headers to add to the email.
+ "X-" prefix is automatically added to those headers.
+ """
+
+ if attachment_list == None:
+ # Create non multi-part MIME message.
+ message = MIMEText(msg, _charset='utf-8')
+ attachment_list = []
+ else:
+ # Create multi-part MIME message.
+ message = MIMEMultipart()
+ message.preamble = "If you can read this, your mailreader\n" \
+ "can not handle multi-part messages!\n"
+ message.attach(MIMEText(msg, _charset='utf-8'))
+
+ if extra_headers:
+ for k, v in extra_headers.items():
+ message.add_header('X-%s' % k, v)
+
+ message.add_header('Subject',
+ make_header([(subject, 'utf-8')]).encode())
+ message.add_header('From', from_url)
+ message.add_header('To', to_url)
+
+ for attachment in attachment_list:
+ if attachment.has_key('name'):
+ attachment_name = attachment['name']
+ else:
+ attachment_name = ''
+ # try to guess the mime type
+ if not attachment.has_key('mime_type'):
+ type, encoding = guess_type( attachment_name )
+ if type != None:
+ attachment['mime_type'] = type
+ else:
+ attachment['mime_type'] = 'application/octet-stream'
+
+ # attach it
+ if attachment['mime_type'] == 'text/plain':
+ part = MIMEText(attachment['content'], _charset='utf-8')
+ else:
+ # encode non-plaintext attachment in base64
+ part = MIMEBase(*attachment['mime_type'].split('/', 1))
+ part.set_payload(attachment['content'])
+ Encoders.encode_base64(part)
+
+ part.add_header('Content-Disposition',
+ 'attachment; filename=%s' % attachment_name)
+ message.attach(part)
+
+ return message
class NotificationTool(BaseTool):
"""
@@ -86,8 +157,14 @@
message -- the text of the message (already translated)
attachment_list -- attached documents (optional)
+
+ TODO: support default notification email
"""
catalog_tool = getToolByName(self, 'portal_catalog')
+
+ # Default Values
+ portal = self.getPortalObject()
+ default_email = portal.email_from_address
# Change all strings to object values
if isinstance(sender, basestring):
@@ -100,32 +177,37 @@
email_from_address = email_value.asText()
if not email_from_address:
# If we can not find a from address then
- # we fallback to portal values
- portal = self.getPortalObject()
- email_from_address = portal.email_from_address
+ # we fallback to default values
+ email_from_address = default_email
# To is a list - let us find all members
if isinstance(recipient, basestring):
- recipient = [recipient]
- to_list = []
- for user in recipient:
- user_value = catalog_tool(portal_type='Person', reference=user)[0]
- if user_value is not None:
- to_list.append(user_value)
+ recipient = catalog_tool(portal_type='Person', reference=recipient)
+
+ # If no recipient is defined, just send an email to the
+ # default mail address defined at the CMF site root.
+ if recipient is None:
+ mailhost = getattr(self.getPortalObject(), 'MailHost', None)
+ if mailhost is None:
+ raise AttributeError, "Cannot find a MailHost object"
+ mail_message = buildEmailMessage(email_from_address, default_email,
+ msg=message, subject=subject,
+ attachment_list=attachment_list)
+ return mailhost.send(mail_message.as_string(), default_email, email_from_address)
# Default implementation is to send an active message to everyone
- for person in to_list:
+ for person in recipient:
email_value = person.getDefaultEmailValue()
if email_value is not None:
# Activity can not handle attachment
# Queuing messages has to be managed by the MTA
email_value.send(
- from_url=email_from_address,
- to_url=email_value.asText(),
- subject=subject,
- msg=message,
- attachment_list=attachment_list)
-
+ from_url=email_from_address,
+ to_url=email_value.asText(),
+ subject=subject,
+ msg=message,
+ attachment_list=attachment_list)
+
# Future implemetation could consist in implementing
# policies such as grouped notification (per hour, per day,
# per week, etc.) depending on user preferences. It
More information about the Erp5-report
mailing list