[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