[Checkins] SVN: zope.sendmail/trunk/src/zope/sendmail/README.txt
Add some documentation.
Marius Gedminas
marius at pov.lt
Thu Oct 25 11:13:47 EDT 2007
Log message for revision 81092:
Add some documentation.
Warning: the code examples haven't been actually tested. It might be a good
idea to convert them to doctests, if that can be done without decreasing
readability.
Changed:
A zope.sendmail/trunk/src/zope/sendmail/README.txt
-=-
Added: zope.sendmail/trunk/src/zope/sendmail/README.txt
===================================================================
--- zope.sendmail/trunk/src/zope/sendmail/README.txt (rev 0)
+++ zope.sendmail/trunk/src/zope/sendmail/README.txt 2007-10-25 15:13:46 UTC (rev 81092)
@@ -0,0 +1,135 @@
+Using zope.sendmail
+===================
+
+This package is useful when your Zope 3 application wants to send email. It
+integrates with the transaction mechanism and queues your emails to be sent on
+successful commits only.
+
+
+API
+---
+
+An application that wants to send an email can do so by getting the appropriate
+IMailDelivery utility. The standard library's email module is useful for
+formatting the message according to RFC-2822::
+
+ import email.MIMEText
+ import email.Header
+ from zope.sendmail.interfaces import IMailDelivery
+ from zope.component import getUtility
+
+ def send_email(sender, recipient, subject, body):
+ msg = email.MIMEText.MIMEText(body.encode('UTF-8'), 'plain', 'UTF-8')
+ msg["From"] = sender
+ msg["To"] = recipient
+ msg["Subject"] = email.Header.Header(subject, 'UTF-8')
+ mailer = getUtility(IMailDelivery, 'my-app.mailer')
+ mailer.send(sender, [recipient], msg.as_string())
+
+In real-world code you may need to do extra work to format the 'From' and 'To'
+headers correctly, if the addresses contain a real-name part with non-ASCII
+characters. You can find a recipe for that in this blog post:
+http://mg.pov.lt/blog/unicode-emails-in-python.html
+
+
+Configuration
+-------------
+
+The code above used a named IMailDelivery utility. It is your responsibility
+to define one, as Zope 3 doesn't provide one by default. You can define
+an IMailDelivery utility in your site.zcml with a configuration directive::
+
+ <configure xmlns="http://namespaces.zope.org/zope"
+ xmlns:mail="http://namespaces.zope.org/mail"
+
+ <mail:queuedDelivery
+ name="my-app.mailer"
+ permission="zope.Public"
+ mailer="smtp"
+ queuepath="var/mailqueue"
+ />
+
+ </configure>
+
+The ``mail:queuedDelivery`` directive stores every email in a queue (a standard
+Maildir folder on the file system in a given directory) and sends them only on
+successful transaction commits. I'll explain the ``mailer`` parameter later.
+
+There's an alternative directive, ``mail:directDelivery``, that ignores
+transactions and tries to send the emails directly. It is useful for (manual)
+testing, but don't use it in production if you don't want to send multiple
+copies of the same emails to your customers whenever ZODB retries a transaction
+after a ConflictError.
+
+
+Mailers
+-------
+
+The ``mailer`` argument of the ``mail:queuedDelivery`` utility chooses the
+appropriate IMailer utility that will be used to deliver email. There
+are alternative ways of doing that, for example, SMTP or piping the message to
+an external program. Currently ``zope.sendmail`` supports only plain SMTP.
+[#]_
+
+.. [#] There was once a mailer utility that invoked /usr/sbin/sendmail, but
+ it had security issues related to the difficulty of quoting command-line
+ arguments in a portable way.
+
+If the same system that runs your Zope 3 server also has an SMTP server on
+port 25, you can use the default ``smtp`` mailer. If you want to use a
+different SMTP server, define your own utility like this::
+
+ <configure xmlns="http://namespaces.zope.org/zope"
+ xmlns:mail="http://namespaces.zope.org/mail"
+
+ <mail:smtpMailer
+ name="my-app.smtp"
+ hostname="mail.my-app.com"
+ port="25"
+ />
+
+ <mail:queuedDelivery
+ name="my-app.mailer"
+ permission="zope.Public"
+ mailer="my-app.smtp"
+ queuepath="var/mailqueue"
+ />
+
+ </configure>
+
+
+Testing
+-------
+
+Obviously, you don't want your automated unit/functional test runs to send
+real emails. You'll have to define a fake email delivery utility in your
+test layer. Something like this will do the trick::
+
+ class FakeMailDelivery(object):
+ implements(IMailDelivery)
+
+ def send(self, source, dest, body):
+ print "*** Sending email from %s to %s:" % (source, dest)
+ print body
+ return 'fake-message-id at example.com'
+
+Register it with the standard ``utility`` directive::
+
+ <utility name="my-app.mailer" factory="my-app.testing.FakeMailDelivery" />
+
+
+Problems with zope.sendmail
+---------------------------
+
+* The API is a bit inconvenient to use (e.g. you have to do the message
+ formatting by yourself).
+
+* The configuration should be done in zope.conf, not in ZCML.
+
+* If the SMTP server rejects a message (for example, when the sender or
+ recipient address is malformed), that email stays in the queue forever
+ (TODO: file a bug at https://bugs.launchpad.net/zope3/+filebug)
+
+* The IMailSentEvent and IMailErrorEvent events aren't used and can't be used
+ (you don't want to send emails during the commit phase).
+
Property changes on: zope.sendmail/trunk/src/zope/sendmail/README.txt
___________________________________________________________________
Name: svn:eol-style
+ native
More information about the Checkins
mailing list