Commit f3fbd2cb authored by 's avatar

- added IMailHost interface

- some cleanup
parent db3603ff
...@@ -7,28 +7,38 @@ ...@@ -7,28 +7,38 @@
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE # FOR A PARTICULAR PURPOSE.
# #
############################################################################## ##############################################################################
"""SMTP mail objects """SMTP mail objects
$Id$"""
__version__ = "$Revision: 1.83 $"[11:-2]
from Globals import Persistent, DTMLFile, InitializeClass $Id$
from smtplib import SMTP """
from AccessControl.Role import RoleManager
from operator import truth import mimetools
import Acquisition, sys, types, mimetools import rfc822
import OFS.SimpleItem, re, quopri, rfc822
from cStringIO import StringIO from cStringIO import StringIO
from smtplib import SMTP
import Acquisition
import OFS.SimpleItem
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from AccessControl.Permissions import view_management_screens, \ from AccessControl.Permissions import change_configuration
use_mailhost_services from AccessControl.Permissions import use_mailhost_services
from AccessControl.Permissions import view_management_screens
from AccessControl.Role import RoleManager
from Globals import Persistent, DTMLFile, InitializeClass
from DateTime import DateTime from DateTime import DateTime
from zope.interface import implements
from interfaces import IMailHost
class MailHostError(Exception):
class MailHostError( Exception ):
pass pass
manage_addMailHostForm=DTMLFile('dtml/addMailHost_form', globals()) manage_addMailHostForm=DTMLFile('dtml/addMailHost_form', globals())
def manage_addMailHost( self, id, title='', smtp_host='localhost' def manage_addMailHost( self, id, title='', smtp_host='localhost'
, localhost='localhost', smtp_port=25 , localhost='localhost', smtp_port=25
...@@ -42,8 +52,13 @@ def manage_addMailHost( self, id, title='', smtp_host='localhost' ...@@ -42,8 +52,13 @@ def manage_addMailHost( self, id, title='', smtp_host='localhost'
add = manage_addMailHost add = manage_addMailHost
class MailBase(Acquisition.Implicit, OFS.SimpleItem.Item, RoleManager): class MailBase(Acquisition.Implicit, OFS.SimpleItem.Item, RoleManager):
'a mailhost...?' 'a mailhost...?'
implements(IMailHost)
meta_type='Mail Host' meta_type='Mail Host'
manage=manage_main=DTMLFile('dtml/manageMailHost', globals()) manage=manage_main=DTMLFile('dtml/manageMailHost', globals())
manage_main._setName('manage_main') manage_main._setName('manage_main')
...@@ -81,8 +96,7 @@ class MailBase(Acquisition.Implicit, OFS.SimpleItem.Item, RoleManager): ...@@ -81,8 +96,7 @@ class MailBase(Acquisition.Implicit, OFS.SimpleItem.Item, RoleManager):
self.smtp_host=smtp_host self.smtp_host=smtp_host
self.smtp_port=smtp_port self.smtp_port=smtp_port
security.declareProtected(change_configuration, 'manage_makeChanges')
security.declareProtected( 'Change configuration', 'manage_makeChanges' )
def manage_makeChanges(self,title,smtp_host,smtp_port,smtp_uid='',smtp_pwd='', REQUEST=None): def manage_makeChanges(self,title,smtp_host,smtp_port,smtp_uid='',smtp_pwd='', REQUEST=None):
'make the changes' 'make the changes'
...@@ -102,8 +116,7 @@ class MailBase(Acquisition.Implicit, OFS.SimpleItem.Item, RoleManager): ...@@ -102,8 +116,7 @@ class MailBase(Acquisition.Implicit, OFS.SimpleItem.Item, RoleManager):
, manage_tabs_message=msg , manage_tabs_message=msg
) )
security.declareProtected(use_mailhost_services, 'sendTemplate')
security.declareProtected( use_mailhost_services, 'sendTemplate' )
def sendTemplate(trueself, self, messageTemplate, def sendTemplate(trueself, self, messageTemplate,
statusTemplate=None, mto=None, mfrom=None, statusTemplate=None, mto=None, mfrom=None,
encode=None, REQUEST=None): encode=None, REQUEST=None):
...@@ -122,8 +135,7 @@ class MailBase(Acquisition.Implicit, OFS.SimpleItem.Item, RoleManager): ...@@ -122,8 +135,7 @@ class MailBase(Acquisition.Implicit, OFS.SimpleItem.Item, RoleManager):
except: except:
return "SEND OK" return "SEND OK"
security.declareProtected(use_mailhost_services, 'send')
security.declareProtected( use_mailhost_services, 'send' )
def send(self, messageText, mto=None, mfrom=None, subject=None, def send(self, messageText, mto=None, mfrom=None, subject=None,
encode=None): encode=None):
...@@ -131,21 +143,19 @@ class MailBase(Acquisition.Implicit, OFS.SimpleItem.Item, RoleManager): ...@@ -131,21 +143,19 @@ class MailBase(Acquisition.Implicit, OFS.SimpleItem.Item, RoleManager):
messageText = _encode(messageText, encode) messageText = _encode(messageText, encode)
self._send(mfrom, mto, messageText) self._send(mfrom, mto, messageText)
# This is here for backwards compatibility only. Possibly it could # This is here for backwards compatibility only. Possibly it could
# be used to send messages at a scheduled future time, or via a mail queue? # be used to send messages at a scheduled future time, or via a mail queue?
security.declareProtected( use_mailhost_services, 'scheduledSend' ) security.declareProtected(use_mailhost_services, 'scheduledSend')
scheduledSend = send scheduledSend = send
security.declareProtected( use_mailhost_services, 'simple_send' ) security.declareProtected(use_mailhost_services, 'simple_send')
def simple_send(self, mto, mfrom, subject, body): def simple_send(self, mto, mfrom, subject, body):
body="From: %s\nTo: %s\nSubject: %s\n\n%s" % ( body="From: %s\nTo: %s\nSubject: %s\n\n%s" % (
mfrom, mto, subject, body) mfrom, mto, subject, body)
self._send( mfrom, mto, body ) self._send( mfrom, mto, body )
security.declarePrivate('_send')
security.declarePrivate( '_send' )
def _send( self, mfrom, mto, messageText ): def _send( self, mfrom, mto, messageText ):
""" Send the message """ """ Send the message """
smtpserver = SMTP(self.smtp_host, int(self.smtp_port) ) smtpserver = SMTP(self.smtp_host, int(self.smtp_port) )
...@@ -154,12 +164,14 @@ class MailBase(Acquisition.Implicit, OFS.SimpleItem.Item, RoleManager): ...@@ -154,12 +164,14 @@ class MailBase(Acquisition.Implicit, OFS.SimpleItem.Item, RoleManager):
smtpserver.sendmail( mfrom, mto, messageText ) smtpserver.sendmail( mfrom, mto, messageText )
smtpserver.quit() smtpserver.quit()
InitializeClass(MailBase)
InitializeClass( MailBase )
class MailHost(Persistent, MailBase): class MailHost(Persistent, MailBase):
"persistent version" "persistent version"
def _encode(body, encode=None): def _encode(body, encode=None):
if encode is None: if encode is None:
return body return body
...@@ -191,7 +203,7 @@ def _mungeHeaders( messageText, mto=None, mfrom=None, subject=None): ...@@ -191,7 +203,7 @@ def _mungeHeaders( messageText, mto=None, mfrom=None, subject=None):
mo['Subject'] = '[No Subject]' mo['Subject'] = '[No Subject]'
if mto: if mto:
if isinstance(mto, types.StringType): if isinstance(mto, basestring):
mto = [rfc822.dump_address_pair(addr) for addr in rfc822.AddressList(mto) ] mto = [rfc822.dump_address_pair(addr) for addr in rfc822.AddressList(mto) ]
if not mo.getheader('To'): if not mo.getheader('To'):
mo['To'] = ','.join(mto) mo['To'] = ','.join(mto)
......
##############################################################################
#
# Copyright (c) 2005 Zope Corporation 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.
#
##############################################################################
"""MailHost z3 interfaces.
$Id$
"""
from zope.interface import Interface
class IMailHost(Interface):
def send(messageText, mto=None, mfrom=None, subject=None, encode=None):
"""Send mail.
"""
import os, sys, unittest ##############################################################################
#
# Copyright (c) 2002 Zope Corporation 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.
#
##############################################################################
"""MailHost unit tests.
$Id$
"""
import unittest
import string, cStringIO, re
import ZODB, Acquisition
from Products.MailHost.MailHost import MailHostError, _mungeHeaders from Products.MailHost.MailHost import MailHostError, _mungeHeaders
class TestMailHost( unittest.TestCase ):
class TestMailHost(unittest.TestCase):
def _getTargetClass(self):
from Products.MailHost.MailHost import MailHost
return MailHost
def test_z3interfaces(self):
from Products.MailHost.interfaces import IMailHost
from zope.interface.verify import verifyClass
verifyClass(IMailHost, self._getTargetClass())
def testAllHeaders( self ): def testAllHeaders( self ):
msg = """To: recipient@domain.com msg = """To: recipient@domain.com
...@@ -18,12 +45,14 @@ This is the message body.""" ...@@ -18,12 +45,14 @@ This is the message body."""
self.failUnless(resfrom == 'sender@domain.com' ) self.failUnless(resfrom == 'sender@domain.com' )
# Add duplicated info # Add duplicated info
resmsg, resto, resfrom = _mungeHeaders( msg, 'recipient@domain.com', 'sender@domain.com', 'This is the subject' ) resmsg, resto, resfrom = _mungeHeaders(msg, 'recipient@domain.com',
'sender@domain.com', 'This is the subject' )
self.failUnless(resto == ['recipient@domain.com']) self.failUnless(resto == ['recipient@domain.com'])
self.failUnless(resfrom == 'sender@domain.com' ) self.failUnless(resfrom == 'sender@domain.com' )
# Add extra info # Add extra info
resmsg, resto, resfrom = _mungeHeaders( msg, 'recipient2@domain.com', 'sender2@domain.com', 'This is the real subject' ) resmsg, resto, resfrom = _mungeHeaders(msg, 'recipient2@domain.com',
'sender2@domain.com', 'This is the real subject' )
self.failUnless(resto == ['recipient2@domain.com']) self.failUnless(resto == ['recipient2@domain.com'])
self.failUnless(resfrom == 'sender2@domain.com' ) self.failUnless(resfrom == 'sender2@domain.com' )
...@@ -32,18 +61,23 @@ This is the message body.""" ...@@ -32,18 +61,23 @@ This is the message body."""
This is the message body.""" This is the message body."""
# Doesn't specify to # Doesn't specify to
self.failUnlessRaises( MailHostError, _mungeHeaders, msg, mfrom='sender@domain.com' ) self.failUnlessRaises(MailHostError, _mungeHeaders, msg,
mfrom='sender@domain.com')
# Doesn't specify from # Doesn't specify from
self.failUnlessRaises( MailHostError, _mungeHeaders, msg, mto='recipient@domain.com' ) self.failUnlessRaises(MailHostError, _mungeHeaders, msg,
mto='recipient@domain.com')
def testNoHeaders( self ): def testNoHeaders( self ):
msg = """This is the message body.""" msg = """This is the message body."""
# Doesn't specify to # Doesn't specify to
self.failUnlessRaises( MailHostError, _mungeHeaders, msg, mfrom='sender@domain.com' ) self.failUnlessRaises(MailHostError, _mungeHeaders, msg,
mfrom='sender@domain.com')
# Doesn't specify from # Doesn't specify from
self.failUnlessRaises( MailHostError, _mungeHeaders, msg, mto='recipient@domain.com' ) self.failUnlessRaises(MailHostError, _mungeHeaders, msg,
mto='recipient@domain.com')
# Specify all # Specify all
resmsg, resto, resfrom = _mungeHeaders( msg, 'recipient2@domain.com', 'sender2@domain.com', 'This is the real subject' ) resmsg, resto, resfrom = _mungeHeaders(msg, 'recipient2@domain.com',
'sender2@domain.com', 'This is the real subject')
self.failUnless(resto == ['recipient2@domain.com']) self.failUnless(resto == ['recipient2@domain.com'])
self.failUnless(resfrom == 'sender2@domain.com' ) self.failUnless(resfrom == 'sender2@domain.com' )
...@@ -66,23 +100,24 @@ This is the message body.""" ...@@ -66,23 +100,24 @@ This is the message body."""
# Test Address-Parser for To & CC given in messageText # Test Address-Parser for To & CC given in messageText
resmsg, resto, resfrom = _mungeHeaders( msg ) resmsg, resto, resfrom = _mungeHeaders( msg )
self.failUnless(resto == ['"Name, Nick" <recipient@domain.com>','"Foo Bar" <foo@domain.com>','"Web, Jack" <jack@web.com>']) self.failUnless(resto == ['"Name, Nick" <recipient@domain.com>',
'"Foo Bar" <foo@domain.com>',
'"Web, Jack" <jack@web.com>'])
self.failUnless(resfrom == 'sender@domain.com' ) self.failUnless(resfrom == 'sender@domain.com' )
# Test Address-Parser for a given mto-string # Test Address-Parser for a given mto-string
resmsg, resto, resfrom = _mungeHeaders( msg, mto= '"Public, Joe" <pjoe@domain.com>, "Foo Bar" <foo@domain.com>') resmsg, resto, resfrom = _mungeHeaders(msg, mto= '"Public, Joe" <pjoe@domain.com>, "Foo Bar" <foo@domain.com>')
self.failUnless(resto == ['"Public, Joe" <pjoe@domain.com>','"Foo Bar" <foo@domain.com>']) self.failUnless(resto == ['"Public, Joe" <pjoe@domain.com>',
'"Foo Bar" <foo@domain.com>'])
self.failUnless(resfrom == 'sender@domain.com' ) self.failUnless(resfrom == 'sender@domain.com' )
def test_suite(): def test_suite():
suite = unittest.TestSuite() suite = unittest.TestSuite()
suite.addTest( unittest.makeSuite( TestMailHost ) ) suite.addTest( unittest.makeSuite( TestMailHost ) )
return suite return suite
def main():
unittest.TextTestRunner().run(test_suite())
if __name__ == '__main__': if __name__ == '__main__':
main() unittest.main(defaultTest='test_suite')
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment