[Checkins] SVN: lovely.mail/trunk/ initial checkin
Manfred Schwendinger
manfred.schwendiger at lovelysystems.com
Mon Dec 10 10:12:03 EST 2007
Log message for revision 82236:
initial checkin
Changed:
A lovely.mail/trunk/
A lovely.mail/trunk/CHANGES.txt
A lovely.mail/trunk/LICENSE.txt
A lovely.mail/trunk/bootstrap.py
A lovely.mail/trunk/build/
A lovely.mail/trunk/build/bdist.macosx-10.3-i386/
A lovely.mail/trunk/build/lib/
A lovely.mail/trunk/build/lib/lovely/
A lovely.mail/trunk/build/lib/lovely/__init__.py
A lovely.mail/trunk/build/lib/lovely/mail/
A lovely.mail/trunk/build/lib/lovely/mail/LICENSE.txt
A lovely.mail/trunk/build/lib/lovely/mail/README.txt
A lovely.mail/trunk/build/lib/lovely/mail/SETUP.cfg
A lovely.mail/trunk/build/lib/lovely/mail/__init__.py
A lovely.mail/trunk/build/lib/lovely/mail/configure.zcml
A lovely.mail/trunk/build/lib/lovely/mail/lovely.mail-configure.zcml
A lovely.mail/trunk/build/lib/lovely/mail/remotemail.py
A lovely.mail/trunk/build/lib/lovely/mail/remotemail.txt
A lovely.mail/trunk/build/lib/lovely/mail/testing.py
A lovely.mail/trunk/build/lib/lovely/mail/tests.py
A lovely.mail/trunk/buildout.cfg
A lovely.mail/trunk/dist/
A lovely.mail/trunk/dist/lovely.mail-0.1.2-py2.4.egg
A lovely.mail/trunk/dist/lovely.mail-0.1.2.tar.gz
A lovely.mail/trunk/setup.py
A lovely.mail/trunk/src/
A lovely.mail/trunk/src/lovely/
A lovely.mail/trunk/src/lovely/__init__.py
A lovely.mail/trunk/src/lovely/mail/
A lovely.mail/trunk/src/lovely/mail/LICENSE.txt
A lovely.mail/trunk/src/lovely/mail/README.txt
A lovely.mail/trunk/src/lovely/mail/SETUP.cfg
A lovely.mail/trunk/src/lovely/mail/__init__.py
A lovely.mail/trunk/src/lovely/mail/configure.zcml
A lovely.mail/trunk/src/lovely/mail/lovely.mail-configure.zcml
A lovely.mail/trunk/src/lovely/mail/remotemail.py
A lovely.mail/trunk/src/lovely/mail/remotemail.txt
A lovely.mail/trunk/src/lovely/mail/testing.py
A lovely.mail/trunk/src/lovely/mail/tests.py
-=-
Added: lovely.mail/trunk/CHANGES.txt
===================================================================
--- lovely.mail/trunk/CHANGES.txt (rev 0)
+++ lovely.mail/trunk/CHANGES.txt 2007-12-10 15:12:02 UTC (rev 82236)
@@ -0,0 +1,28 @@
+=======================
+Changes for lovely.mail
+=======================
+
+After
+=====
+
+2007/12/10 0.1.2
+================
+
+- move stuff to zope.org and pypi
+
+2007/08/23 0.1.1
+================
+
+- added remotemail.py for remote sendmail tasks
+
+2007/06/20 0.1.0a1
+==================
+
+- added TestMailDelivery utility implementation
+
+- changed to current bootstrap.py
+
+- added this file
+
+- cleaned imports
+
Property changes on: lovely.mail/trunk/CHANGES.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Added: lovely.mail/trunk/LICENSE.txt
===================================================================
--- lovely.mail/trunk/LICENSE.txt (rev 0)
+++ lovely.mail/trunk/LICENSE.txt 2007-12-10 15:12:02 UTC (rev 82236)
@@ -0,0 +1,42 @@
+ZPL 2.1
+Zope Public License (ZPL) Version 2.1
+
+A copyright notice accompanies this license document that identifies
+the copyright holders.
+
+This license has been certified as open source. It has also been
+designated as GPL compatible by the Free Software Foundation (FSF).
+
+Redistribution and use in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+Redistributions in source code must retain the accompanying copyright
+notice, this list of conditions, and the following disclaimer.
+Redistributions in binary form must reproduce the accompanying
+copyright notice, this list of conditions, and the following
+disclaimer in the documentation and/or other materials provided
+with the distribution.
+Names of the copyright holders must not be used to endorse or
+promote products derived from this software without prior written
+permission from the copyright holders.
+The right to distribute this software or to use it for any purpose
+does not give you the right to use Servicemarks (sm) or Trademarks (tm)
+of the copyright holders. Use of them is covered by separate
+agreement with the copyright holders.
+If any files are modified, you must cause the modified files to
+carry prominent notices stating that you changed the files and
+the date of any change.
+
+Disclaimer
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Property changes on: lovely.mail/trunk/LICENSE.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Added: lovely.mail/trunk/bootstrap.py
===================================================================
--- lovely.mail/trunk/bootstrap.py (rev 0)
+++ lovely.mail/trunk/bootstrap.py 2007-12-10 15:12:02 UTC (rev 82236)
@@ -0,0 +1,50 @@
+##############################################################################
+#
+# Copyright (c) 2007 Lovely Systems and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id$
+"""
+
+import os, shutil, sys, tempfile, urllib2
+
+tmpeggs = tempfile.mkdtemp()
+
+try:
+ import pkg_resources
+except ImportError:
+ ez = {}
+ exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
+ ).read() in ez
+ ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
+
+ import pkg_resources
+
+cmd = 'from setuptools.command.easy_install import main; main()'
+if sys.platform == 'win32':
+ cmd = '"%s"' % cmd # work around spawn lamosity on windows
+
+ws = pkg_resources.working_set
+assert os.spawnle(
+ os.P_WAIT, sys.executable, sys.executable,
+ '-c', cmd, '-mqNxd', tmpeggs, 'zc.buildout',
+ dict(os.environ,
+ PYTHONPATH=
+ ws.find(pkg_resources.Requirement.parse('setuptools')).location
+ ),
+ ) == 0
+
+ws.add_entry(tmpeggs)
+ws.require('zc.buildout')
+import zc.buildout.buildout
+zc.buildout.buildout.main(sys.argv[1:] + ['bootstrap'])
+shutil.rmtree(tmpeggs)
Property changes on: lovely.mail/trunk/bootstrap.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: lovely.mail/trunk/build/lib/lovely/__init__.py
===================================================================
--- lovely.mail/trunk/build/lib/lovely/__init__.py (rev 0)
+++ lovely.mail/trunk/build/lib/lovely/__init__.py 2007-12-10 15:12:02 UTC (rev 82236)
@@ -0,0 +1,23 @@
+##############################################################################
+#
+# Copyright (c) 2007 Lovely Systems and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id$
+"""
+__docformat__ = "reStructuredText"
+
+
+try:
+ __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+ pass
Property changes on: lovely.mail/trunk/build/lib/lovely/__init__.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: lovely.mail/trunk/build/lib/lovely/mail/LICENSE.txt
===================================================================
--- lovely.mail/trunk/build/lib/lovely/mail/LICENSE.txt (rev 0)
+++ lovely.mail/trunk/build/lib/lovely/mail/LICENSE.txt 2007-12-10 15:12:02 UTC (rev 82236)
@@ -0,0 +1,42 @@
+ZPL 2.1
+Zope Public License (ZPL) Version 2.1
+
+A copyright notice accompanies this license document that identifies
+the copyright holders.
+
+This license has been certified as open source. It has also been
+designated as GPL compatible by the Free Software Foundation (FSF).
+
+Redistribution and use in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+Redistributions in source code must retain the accompanying copyright
+notice, this list of conditions, and the following disclaimer.
+Redistributions in binary form must reproduce the accompanying
+copyright notice, this list of conditions, and the following
+disclaimer in the documentation and/or other materials provided
+with the distribution.
+Names of the copyright holders must not be used to endorse or
+promote products derived from this software without prior written
+permission from the copyright holders.
+The right to distribute this software or to use it for any purpose
+does not give you the right to use Servicemarks (sm) or Trademarks (tm)
+of the copyright holders. Use of them is covered by separate
+agreement with the copyright holders.
+If any files are modified, you must cause the modified files to
+carry prominent notices stating that you changed the files and
+the date of any change.
+
+Disclaimer
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Property changes on: lovely.mail/trunk/build/lib/lovely/mail/LICENSE.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Added: lovely.mail/trunk/build/lib/lovely/mail/README.txt
===================================================================
--- lovely.mail/trunk/build/lib/lovely/mail/README.txt (rev 0)
+++ lovely.mail/trunk/build/lib/lovely/mail/README.txt 2007-12-10 15:12:02 UTC (rev 82236)
@@ -0,0 +1,93 @@
+Lovely.Mail and Mail Testing
+============================
+
+This package mainly provides a simple way to test the mail delivery using the
+current configuration. There is no need to change the mailing configuration
+for the functional tests.
+
+ >>> from lovely.mail import testing
+
+Before we can set up the mail testing we need to register the mailer
+utilities.
+
+ >>> from zope import component
+ >>> from zope.sendmail.mailer import SMTPMailer
+ >>> component.provideUtility(SMTPMailer(),
+ ... name='lovely-mailer')
+
+ >>> from zope.sendmail.delivery import QueuedMailDelivery
+ >>> component.provideUtility(QueuedMailDelivery('some_path'),
+ ... name='lovely-mail-delivery')
+
+Now we set up testing. This is the code which should go into you
+setUp-function for your tests.
+
+ >>> testing.setUpSMTPTesting('lovely-mailer', 'lovely-mail-delivery', unit_test=True)
+
+Testing simply replaces the smtp mailer of the utility to a test smtp mailer.
+
+ >>> from zope.sendmail.interfaces import IMailer, IMailDelivery
+ >>> mailer = component.getUtility(IMailer, 'lovely-mailer')
+ >>> mailer.smtp
+ <class 'lovely.mail.testing.TestMailerConnection'>
+
+And the mail delivery gets a temporary directory.
+
+ >>> delivery = component.getUtility(IMailDelivery, 'lovely-mail-delivery')
+ >>> delivery._queuePath != 'some_path'
+ True
+
+Testing provides a list with already sent mails.
+
+ >>> testing.sentMails
+ []
+
+Now we send a mail.
+
+ >>> messageId = delivery.send('README', ['MAILQUEUE',], 'I am a testing mail')
+ >>> testing.sentMails
+ []
+
+The mail is not sent yet because we need to trigger mail delivery.
+
+ >>> testing.triggerMail()
+ >>> from pprint import pprint
+ >>> pprint(testing.sentMails)
+ [('README',
+ ('MAILQUEUE',),
+ 'Message-Id: <...>\nI am a testing mail')]
+
+
+We also provide a simple function to send mails.
+
+ >>> from lovely.mail import sendmail
+ >>> sendmail('subject', 'me at gmail.org', ['you at gmail.org'], 'my mail body')
+ >>> testing.sentMails = []
+ >>> testing.triggerMail()
+ >>> pprint(testing.sentMails)
+ [('me at gmail.org',
+ ('you at gmail.org',),
+ 'Message-Id: ...\nFrom: me at gmail.org\nTo: you at gmail.org\n...\nmy mail body')]
+
+If we provide tuples for the addresses we get this :
+
+ >>> sendmail('subject', ('ich', 'me at gmail.org'), [('du','you at gmail.org',)], 'my mail body')
+ >>> testing.sentMails = []
+ >>> testing.triggerMail()
+ >>> pprint(testing.sentMails)
+ [('ich <me at gmail.org>',
+ ('du <you at gmail.org>',),
+ 'Message-Id: ...\nFrom: ich <me at gmail.org>\nTo: du <you at gmail.org>\n...\nmy mail body')]
+
+
+
+And clean up.
+
+ >>> testing.tearDownSMTPTesting()
+ >>> mailer.smtp
+ <class smtplib.SMTP at ...>
+ >>> delivery._queuePath == 'some_path'
+ True
+ >>> testing.sentMails
+ []
+
Property changes on: lovely.mail/trunk/build/lib/lovely/mail/README.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Added: lovely.mail/trunk/build/lib/lovely/mail/SETUP.cfg
===================================================================
--- lovely.mail/trunk/build/lib/lovely/mail/SETUP.cfg (rev 0)
+++ lovely.mail/trunk/build/lib/lovely/mail/SETUP.cfg 2007-12-10 15:12:02 UTC (rev 82236)
@@ -0,0 +1,3 @@
+<data-files zopeskel/etc/package-includes>
+ lovely.mail-*.zcml
+</data-files>
\ No newline at end of file
Added: lovely.mail/trunk/build/lib/lovely/mail/__init__.py
===================================================================
--- lovely.mail/trunk/build/lib/lovely/mail/__init__.py (rev 0)
+++ lovely.mail/trunk/build/lib/lovely/mail/__init__.py 2007-12-10 15:12:02 UTC (rev 82236)
@@ -0,0 +1,49 @@
+##############################################################################
+#
+# Copyright (c) 2007 Lovely Systems and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id$
+"""
+__docformat__ = "reStructuredText"
+
+from zope import component
+
+from zope.sendmail.interfaces import IMailDelivery
+
+from email.MIMEText import MIMEText
+import email.Charset
+email.Charset.add_charset('utf-8', email.Charset.SHORTEST, None, None)
+from datetime import datetime
+
+
+def sendmail(subject, fromaddr, toaddrs, body, replyTo=None, bodytype='plain'):
+
+ if isinstance(fromaddr, tuple):
+ fromaddr = '%s <%s>'% fromaddr
+
+ recipients = []
+ for toaddr in toaddrs:
+ if isinstance(toaddr, tuple):
+ toaddr = '%s <%s>'% toaddr
+ recipients.append(toaddr)
+
+ message = MIMEText(body.encode('utf-8'), bodytype, 'utf-8')
+ message['Subject'] = subject
+ message['From'] = fromaddr
+ if replyTo:
+ message['Reply-To'] = replyTo
+ message['To'] = ', '.join(recipients)
+ message['Date'] = datetime.now().strftime('%a, %d %b %Y %H:%M:%S +0000')
+ mailer = component.getUtility(IMailDelivery, name='lovely-mail-delivery')
+ mailer.send(fromaddr, recipients, message.as_string())
+
Property changes on: lovely.mail/trunk/build/lib/lovely/mail/__init__.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: lovely.mail/trunk/build/lib/lovely/mail/configure.zcml
===================================================================
--- lovely.mail/trunk/build/lib/lovely/mail/configure.zcml (rev 0)
+++ lovely.mail/trunk/build/lib/lovely/mail/configure.zcml 2007-12-10 15:12:02 UTC (rev 82236)
@@ -0,0 +1,9 @@
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:i18n="http://namespaces.zope.org/i18n"
+ i18n_domain="lovely.mail">
+
+
+ configuration is done in etc/mail.zcml!
+
+</configure>
\ No newline at end of file
Property changes on: lovely.mail/trunk/build/lib/lovely/mail/configure.zcml
___________________________________________________________________
Name: svn:eol-style
+ native
Added: lovely.mail/trunk/build/lib/lovely/mail/lovely.mail-configure.zcml
===================================================================
--- lovely.mail/trunk/build/lib/lovely/mail/lovely.mail-configure.zcml (rev 0)
+++ lovely.mail/trunk/build/lib/lovely/mail/lovely.mail-configure.zcml 2007-12-10 15:12:02 UTC (rev 82236)
@@ -0,0 +1,2 @@
+<include package="lovely.mail" />
+
Property changes on: lovely.mail/trunk/build/lib/lovely/mail/lovely.mail-configure.zcml
___________________________________________________________________
Name: svn:eol-style
+ native
Added: lovely.mail/trunk/build/lib/lovely/mail/remotemail.py
===================================================================
--- lovely.mail/trunk/build/lib/lovely/mail/remotemail.py (rev 0)
+++ lovely.mail/trunk/build/lib/lovely/mail/remotemail.py 2007-12-10 15:12:02 UTC (rev 82236)
@@ -0,0 +1,57 @@
+##############################################################################
+#
+# Copyright (c) 2007 Lovely Systems and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id$
+"""
+__docformat__ = "reStructuredText"
+
+import persistent
+
+from zope import component
+from zope import interface
+
+from zope.app.container.contained import Contained
+
+from lovely import remotetask
+
+from lovely.mail import sendmail as standardmail
+from lovely.remotetask.interfaces import ITask, ITaskService
+
+
+class RemoteMail(persistent.Persistent, Contained):
+ """ Task for remote mail """
+ interface.implements(ITask)
+
+ def __call__(self, service, jobid, input):
+ standardmail( **input )
+
+
+def sendmail(subject, fromaddr, toaddrs, body, replyTo=None, bodytype='plain', delay=None):
+ """overloaded lovely.mail.sendmail function"""
+
+ if delay is None:
+ standardmail(subject, fromaddr, toaddrs, body, replyTo, bodytype)
+ return
+
+ service = component.getUtility( ITaskService )
+ service.addCronJob( u'remotemail', {
+ 'subject':subject,
+ 'fromaddr':fromaddr,
+ 'toaddrs':toaddrs,
+ 'body':body,
+ 'replyTo':replyTo,
+ 'bodytype':bodytype },
+ delay=delay )
+
+
Property changes on: lovely.mail/trunk/build/lib/lovely/mail/remotemail.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: lovely.mail/trunk/build/lib/lovely/mail/remotemail.txt
===================================================================
--- lovely.mail/trunk/build/lib/lovely/mail/remotemail.txt (rev 0)
+++ lovely.mail/trunk/build/lib/lovely/mail/remotemail.txt 2007-12-10 15:12:02 UTC (rev 82236)
@@ -0,0 +1,108 @@
+Lovely Delayed Mail and Mail Testing
+====================================
+
+ >>> from lovely.mail import testing
+
+ >>> from zope import component
+ >>> from zope.sendmail.mailer import SMTPMailer
+ >>> component.provideUtility(SMTPMailer(),
+ ... name='lovely-mailer')
+
+ >>> from zope.sendmail.delivery import QueuedMailDelivery
+ >>> component.provideUtility(QueuedMailDelivery('some_path'),
+ ... name='lovely-mail-delivery')
+
+Now we set up testing. This is the code which should go into you
+setUp-function for your tests.
+
+ >>> testing.setUpSMTPTesting('lovely-mailer', 'lovely-mail-delivery', unit_test=True)
+
+Testing simply replaces the smtp mailer of the utility to a test smtp mailer.
+
+ >>> from zope.sendmail.interfaces import IMailer, IMailDelivery
+ >>> mailer = component.getUtility(IMailer, 'lovely-mailer')
+ >>> mailer.smtp
+ <class 'lovely.mail.testing.TestMailerConnection'>
+
+
+And the mail delivery gets a temporary directory.
+
+ >>> delivery = component.getUtility(IMailDelivery, 'lovely-mail-delivery')
+ >>> delivery._queuePath != 'some_path'
+ True
+
+Testing provides a list with already sent mails.
+
+ >>> testing.sentMails
+ []
+
+Testing the sendmail function
+
+ >>> from lovely.mail.remotemail import sendmail
+ >>> from pprint import pprint
+
+Test if non-delayed mails still work correctly
+
+ >>> sendmail('subject', 'me at gmail.org', ['you at gmail.org'], 'my mail body')
+ >>> testing.sentMails = []
+ >>> testing.triggerMail()
+ >>> pprint(testing.sentMails)
+ [('me at gmail.org',
+ ('you at gmail.org',),
+ 'Message-Id: ...\nFrom: me at gmail.org\nTo: you at gmail.org\n...\nmy mail body')]
+
+ If we provide tuples for the addresses we get this :
+
+ >>> sendmail('subject', ('ich', 'me at gmail.org'), [('du','you at gmail.org',)], 'my mail body')
+ >>> testing.sentMails = []
+ >>> testing.triggerMail()
+ >>> pprint(testing.sentMails)
+ [('ich <me at gmail.org>',
+ ('du <you at gmail.org>',),
+ 'Message-Id: ...\nFrom: ich <me at gmail.org>\nTo: du <you at gmail.org>\n...\nmy mail body')]
+
+Testing with delay
+
+Creating a remote task service, registered it under the name `TestTaskService`:
+
+ >>> from lovely import remotetask
+ >>> from lovely.remotetask import interfaces
+
+ >>> service = remotetask.TaskService()
+ >>> component.provideUtility(service, interfaces.ITaskService)
+ >>> service.getAvailableTasks()
+ {}
+
+ >>> from lovely.mail.remotemail import RemoteMail
+ >>> component.provideUtility( RemoteMail(), interfaces.ITask, name='remotemail')
+ >>> service.getAvailableTasks()
+ {u'remotemail': <lovely.mail.remotemail.RemoteMail object at ...>}
+
+ >>> sendmail('subject', 'me at gmail.org', ['you at gmail.org'], 'my mail body', delay=10)
+
+ >>> service.process(0)
+
+ >>> testing.sentMails = []
+ >>> testing.triggerMail()
+ >>> pprint(testing.sentMails)
+ []
+
+ >>> service.process(10)
+
+ >>> testing.sentMails = []
+ >>> testing.triggerMail()
+ >>> pprint(testing.sentMails)
+ [('me at gmail.org',
+ ('you at gmail.org',),
+ 'Message-Id: ...\nFrom: me at gmail.org\nTo: you at gmail.org\n...\nmy mail body')]
+
+And clean up.
+
+ >>> testing.tearDownSMTPTesting()
+ >>> mailer.smtp
+ <class smtplib.SMTP at ...>
+ >>> delivery._queuePath == 'some_path'
+ True
+ >>> testing.sentMails
+ []
+
Property changes on: lovely.mail/trunk/build/lib/lovely/mail/remotemail.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Added: lovely.mail/trunk/build/lib/lovely/mail/testing.py
===================================================================
--- lovely.mail/trunk/build/lib/lovely/mail/testing.py (rev 0)
+++ lovely.mail/trunk/build/lib/lovely/mail/testing.py 2007-12-10 15:12:02 UTC (rev 82236)
@@ -0,0 +1,125 @@
+##############################################################################
+#
+# Copyright (c) 2007 Lovely Systems and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id$
+"""
+__docformat__ = "reStructuredText"
+
+import os
+import tempfile
+
+import transaction
+
+from zope import component
+from zope import interface
+
+from zope.sendmail.interfaces import IMailer, IMailDelivery
+from zope.sendmail.delivery import QueueProcessorThread
+
+
+sentMails = []
+
+
+class TestMailDelivery(object):
+
+ """a mail delivery utility that stores its messages without
+ sending for testing
+
+ >>> md = TestMailDelivery()
+
+ It implements the maildelivery interface
+ >>> from zope.interface.verify import verifyObject
+ >>> verifyObject(IMailDelivery, md)
+ True
+
+ We can send messages ...
+ >>> md.send('from', ['to'], 'message')
+
+ They are stored in sent
+ >>> md.sent
+ [('from', ('to',), 'message')]
+
+ We can also clear the messages
+ >>> md.clear()
+ >>> md.sent
+ []
+ """
+ interface.implements(IMailDelivery)
+
+ def __init__(self):
+ self.clear()
+
+ def send(self, fromaddr, toaddrs, message):
+ self.sent.append((fromaddr, tuple(toaddrs), message))
+
+ def clear(self):
+ self.sent = []
+
+class TestMailerConnection(object):
+
+ def __init__(self, host=None, port=None):
+ self.host = host
+ self.port = port
+
+ def login(self, username, password):
+ pass
+
+ def sendmail(self, fromaddr, toaddr, message):
+ sentMails.append((fromaddr, toaddr, message))
+
+ def quit(self):
+ pass
+
+oldSMTP = None
+oldQueuePath = None
+mailer = None
+deliver = None
+thread = None
+
+def setUpSMTPTesting(mailerName, deliveryName, unit_test=False):
+ """Set up the mail testing for SMTP mailer.
+
+ We replace the smpt mail module by our test mailer.
+ """
+ global oldSMTP, oldQueuePath, mailer, delivery, thread
+ del sentMails[:]
+ mailer = component.getUtility(IMailer, mailerName)
+ oldSMTP = mailer.smtp
+ mailer.smtp = TestMailerConnection
+ delivery = component.getUtility(IMailDelivery, deliveryName)
+ oldQueuePath = delivery._queuePath
+ delivery._queuePath = os.path.join(tempfile.mkdtemp(), 'mail')
+ thread = QueueProcessorThread()
+ thread.setMailer(mailer)
+ thread.setQueuePath(delivery.queuePath)
+
+
+def tearDownSMTPTesting():
+ global oldSMTP, oldQueuePath, mailer, delivery, thread
+ mailer.smtp = oldSMTP
+ delivery._queuePath = oldQueuePath
+ thread = None
+ del sentMails[:]
+
+
+def triggerMail():
+ # send pending mails
+ global thread
+ transaction.commit()
+ if thread:
+ thread.run(False)
+
+def clearSentMails():
+ del sentMails[:]
+
Property changes on: lovely.mail/trunk/build/lib/lovely/mail/testing.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: lovely.mail/trunk/build/lib/lovely/mail/tests.py
===================================================================
--- lovely.mail/trunk/build/lib/lovely/mail/tests.py (rev 0)
+++ lovely.mail/trunk/build/lib/lovely/mail/tests.py 2007-12-10 15:12:02 UTC (rev 82236)
@@ -0,0 +1,53 @@
+##############################################################################
+#
+# Copyright (c) 2007 Lovely Systems and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id$
+"""
+__docformat__ = "reStructuredText"
+
+import unittest
+
+from zope.testing import doctest
+from zope.testing.doctestunit import DocFileSuite, DocTestSuite
+
+from zope.app.testing.setup import (placefulSetUp,
+ placefulTearDown)
+
+
+def setUp(test):
+ root = placefulSetUp(site=True)
+ test.globs['root'] = root
+
+def tearDown(test):
+ placefulTearDown()
+
+
+def test_suite():
+ return unittest.TestSuite((
+ DocFileSuite('README.txt',
+ setUp=setUp, tearDown=tearDown,
+ optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+ ),
+ DocFileSuite('remotemail.txt',
+ setUp=setUp, tearDown=tearDown,
+ optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+ ),
+ DocTestSuite('lovely.mail.testing',
+ optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+ ),
+ ))
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='test_suite')
+
Property changes on: lovely.mail/trunk/build/lib/lovely/mail/tests.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: lovely.mail/trunk/buildout.cfg
===================================================================
--- lovely.mail/trunk/buildout.cfg (rev 0)
+++ lovely.mail/trunk/buildout.cfg 2007-12-10 15:12:02 UTC (rev 82236)
@@ -0,0 +1,10 @@
+[buildout]
+develop = .
+parts = test
+find-links = http://download.lovelysystems.com/eggs/mirror/zope
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = lovely.mail [test]
+
+
Added: lovely.mail/trunk/dist/lovely.mail-0.1.2-py2.4.egg
===================================================================
(Binary files differ)
Property changes on: lovely.mail/trunk/dist/lovely.mail-0.1.2-py2.4.egg
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: lovely.mail/trunk/dist/lovely.mail-0.1.2.tar.gz
===================================================================
(Binary files differ)
Property changes on: lovely.mail/trunk/dist/lovely.mail-0.1.2.tar.gz
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: lovely.mail/trunk/setup.py
===================================================================
--- lovely.mail/trunk/setup.py (rev 0)
+++ lovely.mail/trunk/setup.py 2007-12-10 15:12:02 UTC (rev 82236)
@@ -0,0 +1,48 @@
+import os
+from setuptools import setup, find_packages
+
+def read(*rnames):
+ return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
+
+long_description=(
+ read('src', 'lovely', 'mail', 'README.txt')
+ + '\n' +
+ read('CHANGES.txt')
+ + '\n' +
+ 'Download\n'
+ '========\n'
+ )
+
+name = 'lovely.mail'
+setup(
+ name = name,
+ version = '0.1.2',
+ author = "Lovely Systems",
+ author_email = "office at lovelysystems.com",
+ license = "ZPL 2.1",
+ keywords = "mail zope zope3",
+ url = 'http://launchpad.net/lovely.mail',
+ long_description = long_description,
+ zip_safe = False,
+ packages = find_packages('src'),
+ include_package_data = True,
+ package_dir = {'':'src'},
+ namespace_packages = ['lovely',],
+ install_requires = ['setuptools',
+ 'zope.component',
+ 'zope.schema',
+ 'zope.sendmail',
+ 'lovely.remotetask',
+ ],
+ extras_require = dict(
+ test = ['zope.app.testing',
+ 'zope.testing',]),
+ classifiers = [
+ 'Development Status :: 4 - Beta',
+ 'Intended Audience :: Developers',
+ 'License :: OSI Approved :: Zope Public License',
+ 'Topic :: Software Development :: Libraries :: Python Modules',
+ ],
+
+ )
+
Property changes on: lovely.mail/trunk/setup.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: lovely.mail/trunk/src/lovely/__init__.py
===================================================================
--- lovely.mail/trunk/src/lovely/__init__.py (rev 0)
+++ lovely.mail/trunk/src/lovely/__init__.py 2007-12-10 15:12:02 UTC (rev 82236)
@@ -0,0 +1,23 @@
+##############################################################################
+#
+# Copyright (c) 2007 Lovely Systems and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id$
+"""
+__docformat__ = "reStructuredText"
+
+
+try:
+ __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+ pass
Property changes on: lovely.mail/trunk/src/lovely/__init__.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: lovely.mail/trunk/src/lovely/mail/LICENSE.txt
===================================================================
--- lovely.mail/trunk/src/lovely/mail/LICENSE.txt (rev 0)
+++ lovely.mail/trunk/src/lovely/mail/LICENSE.txt 2007-12-10 15:12:02 UTC (rev 82236)
@@ -0,0 +1,42 @@
+ZPL 2.1
+Zope Public License (ZPL) Version 2.1
+
+A copyright notice accompanies this license document that identifies
+the copyright holders.
+
+This license has been certified as open source. It has also been
+designated as GPL compatible by the Free Software Foundation (FSF).
+
+Redistribution and use in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+Redistributions in source code must retain the accompanying copyright
+notice, this list of conditions, and the following disclaimer.
+Redistributions in binary form must reproduce the accompanying
+copyright notice, this list of conditions, and the following
+disclaimer in the documentation and/or other materials provided
+with the distribution.
+Names of the copyright holders must not be used to endorse or
+promote products derived from this software without prior written
+permission from the copyright holders.
+The right to distribute this software or to use it for any purpose
+does not give you the right to use Servicemarks (sm) or Trademarks (tm)
+of the copyright holders. Use of them is covered by separate
+agreement with the copyright holders.
+If any files are modified, you must cause the modified files to
+carry prominent notices stating that you changed the files and
+the date of any change.
+
+Disclaimer
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Property changes on: lovely.mail/trunk/src/lovely/mail/LICENSE.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Added: lovely.mail/trunk/src/lovely/mail/README.txt
===================================================================
--- lovely.mail/trunk/src/lovely/mail/README.txt (rev 0)
+++ lovely.mail/trunk/src/lovely/mail/README.txt 2007-12-10 15:12:02 UTC (rev 82236)
@@ -0,0 +1,93 @@
+Lovely.Mail and Mail Testing
+============================
+
+This package mainly provides a simple way to test the mail delivery using the
+current configuration. There is no need to change the mailing configuration
+for the functional tests.
+
+ >>> from lovely.mail import testing
+
+Before we can set up the mail testing we need to register the mailer
+utilities.
+
+ >>> from zope import component
+ >>> from zope.sendmail.mailer import SMTPMailer
+ >>> component.provideUtility(SMTPMailer(),
+ ... name='lovely-mailer')
+
+ >>> from zope.sendmail.delivery import QueuedMailDelivery
+ >>> component.provideUtility(QueuedMailDelivery('some_path'),
+ ... name='lovely-mail-delivery')
+
+Now we set up testing. This is the code which should go into you
+setUp-function for your tests.
+
+ >>> testing.setUpSMTPTesting('lovely-mailer', 'lovely-mail-delivery', unit_test=True)
+
+Testing simply replaces the smtp mailer of the utility to a test smtp mailer.
+
+ >>> from zope.sendmail.interfaces import IMailer, IMailDelivery
+ >>> mailer = component.getUtility(IMailer, 'lovely-mailer')
+ >>> mailer.smtp
+ <class 'lovely.mail.testing.TestMailerConnection'>
+
+And the mail delivery gets a temporary directory.
+
+ >>> delivery = component.getUtility(IMailDelivery, 'lovely-mail-delivery')
+ >>> delivery._queuePath != 'some_path'
+ True
+
+Testing provides a list with already sent mails.
+
+ >>> testing.sentMails
+ []
+
+Now we send a mail.
+
+ >>> messageId = delivery.send('README', ['MAILQUEUE',], 'I am a testing mail')
+ >>> testing.sentMails
+ []
+
+The mail is not sent yet because we need to trigger mail delivery.
+
+ >>> testing.triggerMail()
+ >>> from pprint import pprint
+ >>> pprint(testing.sentMails)
+ [('README',
+ ('MAILQUEUE',),
+ 'Message-Id: <...>\nI am a testing mail')]
+
+
+We also provide a simple function to send mails.
+
+ >>> from lovely.mail import sendmail
+ >>> sendmail('subject', 'me at gmail.org', ['you at gmail.org'], 'my mail body')
+ >>> testing.sentMails = []
+ >>> testing.triggerMail()
+ >>> pprint(testing.sentMails)
+ [('me at gmail.org',
+ ('you at gmail.org',),
+ 'Message-Id: ...\nFrom: me at gmail.org\nTo: you at gmail.org\n...\nmy mail body')]
+
+If we provide tuples for the addresses we get this :
+
+ >>> sendmail('subject', ('ich', 'me at gmail.org'), [('du','you at gmail.org',)], 'my mail body')
+ >>> testing.sentMails = []
+ >>> testing.triggerMail()
+ >>> pprint(testing.sentMails)
+ [('ich <me at gmail.org>',
+ ('du <you at gmail.org>',),
+ 'Message-Id: ...\nFrom: ich <me at gmail.org>\nTo: du <you at gmail.org>\n...\nmy mail body')]
+
+
+
+And clean up.
+
+ >>> testing.tearDownSMTPTesting()
+ >>> mailer.smtp
+ <class smtplib.SMTP at ...>
+ >>> delivery._queuePath == 'some_path'
+ True
+ >>> testing.sentMails
+ []
+
Property changes on: lovely.mail/trunk/src/lovely/mail/README.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Added: lovely.mail/trunk/src/lovely/mail/SETUP.cfg
===================================================================
--- lovely.mail/trunk/src/lovely/mail/SETUP.cfg (rev 0)
+++ lovely.mail/trunk/src/lovely/mail/SETUP.cfg 2007-12-10 15:12:02 UTC (rev 82236)
@@ -0,0 +1,3 @@
+<data-files zopeskel/etc/package-includes>
+ lovely.mail-*.zcml
+</data-files>
\ No newline at end of file
Added: lovely.mail/trunk/src/lovely/mail/__init__.py
===================================================================
--- lovely.mail/trunk/src/lovely/mail/__init__.py (rev 0)
+++ lovely.mail/trunk/src/lovely/mail/__init__.py 2007-12-10 15:12:02 UTC (rev 82236)
@@ -0,0 +1,49 @@
+##############################################################################
+#
+# Copyright (c) 2007 Lovely Systems and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id$
+"""
+__docformat__ = "reStructuredText"
+
+from zope import component
+
+from zope.sendmail.interfaces import IMailDelivery
+
+from email.MIMEText import MIMEText
+import email.Charset
+email.Charset.add_charset('utf-8', email.Charset.SHORTEST, None, None)
+from datetime import datetime
+
+
+def sendmail(subject, fromaddr, toaddrs, body, replyTo=None, bodytype='plain'):
+
+ if isinstance(fromaddr, tuple):
+ fromaddr = '%s <%s>'% fromaddr
+
+ recipients = []
+ for toaddr in toaddrs:
+ if isinstance(toaddr, tuple):
+ toaddr = '%s <%s>'% toaddr
+ recipients.append(toaddr)
+
+ message = MIMEText(body.encode('utf-8'), bodytype, 'utf-8')
+ message['Subject'] = subject
+ message['From'] = fromaddr
+ if replyTo:
+ message['Reply-To'] = replyTo
+ message['To'] = ', '.join(recipients)
+ message['Date'] = datetime.now().strftime('%a, %d %b %Y %H:%M:%S +0000')
+ mailer = component.getUtility(IMailDelivery, name='lovely-mail-delivery')
+ mailer.send(fromaddr, recipients, message.as_string())
+
Property changes on: lovely.mail/trunk/src/lovely/mail/__init__.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: lovely.mail/trunk/src/lovely/mail/configure.zcml
===================================================================
--- lovely.mail/trunk/src/lovely/mail/configure.zcml (rev 0)
+++ lovely.mail/trunk/src/lovely/mail/configure.zcml 2007-12-10 15:12:02 UTC (rev 82236)
@@ -0,0 +1,9 @@
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:i18n="http://namespaces.zope.org/i18n"
+ i18n_domain="lovely.mail">
+
+
+ configuration is done in etc/mail.zcml!
+
+</configure>
\ No newline at end of file
Property changes on: lovely.mail/trunk/src/lovely/mail/configure.zcml
___________________________________________________________________
Name: svn:eol-style
+ native
Added: lovely.mail/trunk/src/lovely/mail/lovely.mail-configure.zcml
===================================================================
--- lovely.mail/trunk/src/lovely/mail/lovely.mail-configure.zcml (rev 0)
+++ lovely.mail/trunk/src/lovely/mail/lovely.mail-configure.zcml 2007-12-10 15:12:02 UTC (rev 82236)
@@ -0,0 +1,2 @@
+<include package="lovely.mail" />
+
Property changes on: lovely.mail/trunk/src/lovely/mail/lovely.mail-configure.zcml
___________________________________________________________________
Name: svn:eol-style
+ native
Added: lovely.mail/trunk/src/lovely/mail/remotemail.py
===================================================================
--- lovely.mail/trunk/src/lovely/mail/remotemail.py (rev 0)
+++ lovely.mail/trunk/src/lovely/mail/remotemail.py 2007-12-10 15:12:02 UTC (rev 82236)
@@ -0,0 +1,57 @@
+##############################################################################
+#
+# Copyright (c) 2007 Lovely Systems and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id$
+"""
+__docformat__ = "reStructuredText"
+
+import persistent
+
+from zope import component
+from zope import interface
+
+from zope.app.container.contained import Contained
+
+from lovely import remotetask
+
+from lovely.mail import sendmail as standardmail
+from lovely.remotetask.interfaces import ITask, ITaskService
+
+
+class RemoteMail(persistent.Persistent, Contained):
+ """ Task for remote mail """
+ interface.implements(ITask)
+
+ def __call__(self, service, jobid, input):
+ standardmail( **input )
+
+
+def sendmail(subject, fromaddr, toaddrs, body, replyTo=None, bodytype='plain', delay=None):
+ """overloaded lovely.mail.sendmail function"""
+
+ if delay is None:
+ standardmail(subject, fromaddr, toaddrs, body, replyTo, bodytype)
+ return
+
+ service = component.getUtility( ITaskService )
+ service.addCronJob( u'remotemail', {
+ 'subject':subject,
+ 'fromaddr':fromaddr,
+ 'toaddrs':toaddrs,
+ 'body':body,
+ 'replyTo':replyTo,
+ 'bodytype':bodytype },
+ delay=delay )
+
+
Property changes on: lovely.mail/trunk/src/lovely/mail/remotemail.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: lovely.mail/trunk/src/lovely/mail/remotemail.txt
===================================================================
--- lovely.mail/trunk/src/lovely/mail/remotemail.txt (rev 0)
+++ lovely.mail/trunk/src/lovely/mail/remotemail.txt 2007-12-10 15:12:02 UTC (rev 82236)
@@ -0,0 +1,108 @@
+Lovely Delayed Mail and Mail Testing
+====================================
+
+ >>> from lovely.mail import testing
+
+ >>> from zope import component
+ >>> from zope.sendmail.mailer import SMTPMailer
+ >>> component.provideUtility(SMTPMailer(),
+ ... name='lovely-mailer')
+
+ >>> from zope.sendmail.delivery import QueuedMailDelivery
+ >>> component.provideUtility(QueuedMailDelivery('some_path'),
+ ... name='lovely-mail-delivery')
+
+Now we set up testing. This is the code which should go into you
+setUp-function for your tests.
+
+ >>> testing.setUpSMTPTesting('lovely-mailer', 'lovely-mail-delivery', unit_test=True)
+
+Testing simply replaces the smtp mailer of the utility to a test smtp mailer.
+
+ >>> from zope.sendmail.interfaces import IMailer, IMailDelivery
+ >>> mailer = component.getUtility(IMailer, 'lovely-mailer')
+ >>> mailer.smtp
+ <class 'lovely.mail.testing.TestMailerConnection'>
+
+
+And the mail delivery gets a temporary directory.
+
+ >>> delivery = component.getUtility(IMailDelivery, 'lovely-mail-delivery')
+ >>> delivery._queuePath != 'some_path'
+ True
+
+Testing provides a list with already sent mails.
+
+ >>> testing.sentMails
+ []
+
+Testing the sendmail function
+
+ >>> from lovely.mail.remotemail import sendmail
+ >>> from pprint import pprint
+
+Test if non-delayed mails still work correctly
+
+ >>> sendmail('subject', 'me at gmail.org', ['you at gmail.org'], 'my mail body')
+ >>> testing.sentMails = []
+ >>> testing.triggerMail()
+ >>> pprint(testing.sentMails)
+ [('me at gmail.org',
+ ('you at gmail.org',),
+ 'Message-Id: ...\nFrom: me at gmail.org\nTo: you at gmail.org\n...\nmy mail body')]
+
+ If we provide tuples for the addresses we get this :
+
+ >>> sendmail('subject', ('ich', 'me at gmail.org'), [('du','you at gmail.org',)], 'my mail body')
+ >>> testing.sentMails = []
+ >>> testing.triggerMail()
+ >>> pprint(testing.sentMails)
+ [('ich <me at gmail.org>',
+ ('du <you at gmail.org>',),
+ 'Message-Id: ...\nFrom: ich <me at gmail.org>\nTo: du <you at gmail.org>\n...\nmy mail body')]
+
+Testing with delay
+
+Creating a remote task service, registered it under the name `TestTaskService`:
+
+ >>> from lovely import remotetask
+ >>> from lovely.remotetask import interfaces
+
+ >>> service = remotetask.TaskService()
+ >>> component.provideUtility(service, interfaces.ITaskService)
+ >>> service.getAvailableTasks()
+ {}
+
+ >>> from lovely.mail.remotemail import RemoteMail
+ >>> component.provideUtility( RemoteMail(), interfaces.ITask, name='remotemail')
+ >>> service.getAvailableTasks()
+ {u'remotemail': <lovely.mail.remotemail.RemoteMail object at ...>}
+
+ >>> sendmail('subject', 'me at gmail.org', ['you at gmail.org'], 'my mail body', delay=10)
+
+ >>> service.process(0)
+
+ >>> testing.sentMails = []
+ >>> testing.triggerMail()
+ >>> pprint(testing.sentMails)
+ []
+
+ >>> service.process(10)
+
+ >>> testing.sentMails = []
+ >>> testing.triggerMail()
+ >>> pprint(testing.sentMails)
+ [('me at gmail.org',
+ ('you at gmail.org',),
+ 'Message-Id: ...\nFrom: me at gmail.org\nTo: you at gmail.org\n...\nmy mail body')]
+
+And clean up.
+
+ >>> testing.tearDownSMTPTesting()
+ >>> mailer.smtp
+ <class smtplib.SMTP at ...>
+ >>> delivery._queuePath == 'some_path'
+ True
+ >>> testing.sentMails
+ []
+
Property changes on: lovely.mail/trunk/src/lovely/mail/remotemail.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Added: lovely.mail/trunk/src/lovely/mail/testing.py
===================================================================
--- lovely.mail/trunk/src/lovely/mail/testing.py (rev 0)
+++ lovely.mail/trunk/src/lovely/mail/testing.py 2007-12-10 15:12:02 UTC (rev 82236)
@@ -0,0 +1,125 @@
+##############################################################################
+#
+# Copyright (c) 2007 Lovely Systems and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id$
+"""
+__docformat__ = "reStructuredText"
+
+import os
+import tempfile
+
+import transaction
+
+from zope import component
+from zope import interface
+
+from zope.sendmail.interfaces import IMailer, IMailDelivery
+from zope.sendmail.delivery import QueueProcessorThread
+
+
+sentMails = []
+
+
+class TestMailDelivery(object):
+
+ """a mail delivery utility that stores its messages without
+ sending for testing
+
+ >>> md = TestMailDelivery()
+
+ It implements the maildelivery interface
+ >>> from zope.interface.verify import verifyObject
+ >>> verifyObject(IMailDelivery, md)
+ True
+
+ We can send messages ...
+ >>> md.send('from', ['to'], 'message')
+
+ They are stored in sent
+ >>> md.sent
+ [('from', ('to',), 'message')]
+
+ We can also clear the messages
+ >>> md.clear()
+ >>> md.sent
+ []
+ """
+ interface.implements(IMailDelivery)
+
+ def __init__(self):
+ self.clear()
+
+ def send(self, fromaddr, toaddrs, message):
+ self.sent.append((fromaddr, tuple(toaddrs), message))
+
+ def clear(self):
+ self.sent = []
+
+class TestMailerConnection(object):
+
+ def __init__(self, host=None, port=None):
+ self.host = host
+ self.port = port
+
+ def login(self, username, password):
+ pass
+
+ def sendmail(self, fromaddr, toaddr, message):
+ sentMails.append((fromaddr, toaddr, message))
+
+ def quit(self):
+ pass
+
+oldSMTP = None
+oldQueuePath = None
+mailer = None
+deliver = None
+thread = None
+
+def setUpSMTPTesting(mailerName, deliveryName, unit_test=False):
+ """Set up the mail testing for SMTP mailer.
+
+ We replace the smpt mail module by our test mailer.
+ """
+ global oldSMTP, oldQueuePath, mailer, delivery, thread
+ del sentMails[:]
+ mailer = component.getUtility(IMailer, mailerName)
+ oldSMTP = mailer.smtp
+ mailer.smtp = TestMailerConnection
+ delivery = component.getUtility(IMailDelivery, deliveryName)
+ oldQueuePath = delivery._queuePath
+ delivery._queuePath = os.path.join(tempfile.mkdtemp(), 'mail')
+ thread = QueueProcessorThread()
+ thread.setMailer(mailer)
+ thread.setQueuePath(delivery.queuePath)
+
+
+def tearDownSMTPTesting():
+ global oldSMTP, oldQueuePath, mailer, delivery, thread
+ mailer.smtp = oldSMTP
+ delivery._queuePath = oldQueuePath
+ thread = None
+ del sentMails[:]
+
+
+def triggerMail():
+ # send pending mails
+ global thread
+ transaction.commit()
+ if thread:
+ thread.run(False)
+
+def clearSentMails():
+ del sentMails[:]
+
Property changes on: lovely.mail/trunk/src/lovely/mail/testing.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: lovely.mail/trunk/src/lovely/mail/tests.py
===================================================================
--- lovely.mail/trunk/src/lovely/mail/tests.py (rev 0)
+++ lovely.mail/trunk/src/lovely/mail/tests.py 2007-12-10 15:12:02 UTC (rev 82236)
@@ -0,0 +1,53 @@
+##############################################################################
+#
+# Copyright (c) 2007 Lovely Systems and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id$
+"""
+__docformat__ = "reStructuredText"
+
+import unittest
+
+from zope.testing import doctest
+from zope.testing.doctestunit import DocFileSuite, DocTestSuite
+
+from zope.app.testing.setup import (placefulSetUp,
+ placefulTearDown)
+
+
+def setUp(test):
+ root = placefulSetUp(site=True)
+ test.globs['root'] = root
+
+def tearDown(test):
+ placefulTearDown()
+
+
+def test_suite():
+ return unittest.TestSuite((
+ DocFileSuite('README.txt',
+ setUp=setUp, tearDown=tearDown,
+ optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+ ),
+ DocFileSuite('remotemail.txt',
+ setUp=setUp, tearDown=tearDown,
+ optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+ ),
+ DocTestSuite('lovely.mail.testing',
+ optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+ ),
+ ))
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='test_suite')
+
Property changes on: lovely.mail/trunk/src/lovely/mail/tests.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
More information about the Checkins
mailing list