BaseMailTemplate.py 5.57 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
# Copyright (c) 2005-2006 Simplistix Ltd
#
# This Software is released under the MIT License:
# http://www.opensource.org/licenses/mit-license.html
# See license.txt for more details.

import os
import rfc822

from AccessControl import ClassSecurityInfo
from DateTime import DateTime
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText

from Globals import InitializeClass, package_home
from MTMultipart import MTMultipart
from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate, SUPPORTS_WEBDAV_LOCKS
from Products.PageTemplates.PageTemplateFile import PageTemplateFile

from ZPublisher import HTTPResponse

# Configured using zope.conf in Zope 2.7.8, Zope 2.8.2, and above
default_encoding = getattr(HTTPResponse,'default_encoding','iso-8859-15')

class BaseMailTemplate:

    security = ClassSecurityInfo()

    _properties = ()
    
    ZScriptHTML_tryForm = None

    content_type = 'text/plain'

    mailhost = None
    
    security.declarePrivate('_process')
    def _process(self,kw):
        # sort out what encoding we're going to use
        encoding = kw.get('encoding',
                          self.getProperty('encoding',
                                           default_encoding))
        text = self.__class__.__bases__[1].__call__(self,**kw)
        if not self.html():
            text = text.encode(encoding,'replace')
        # now turn the result into a MIMEText object
        msg = MIMEText(
            text.replace('\r',''),
            self.content_type.split('/')[1],
            encoding
            )
        # sort out what headers and addresses we're going to use
        headers = {}
        values = {}
        # headers from the headers property
        for header in getattr(self,'headers',()):
            name,value = header.split(':',1)
            headers[name]=value
        # headers from the headers parameter
        headers_param = kw.get('headers',{})
        headers.update(headers_param)
        # values and some specific headers
        for key,header in (('mfrom','From'),
                           ('mto','To'),
                           ('mcc','Cc'),
                           ('mbcc','Bcc'),
                           ('subject','Subject')):
            value = kw.get(key,
                           headers_param.get(header,
                                             getattr(self,
                                                     key,
                                                     headers.get(header))))
            if value is not None:
                values[key]=value
                # turn some sequences in coma-seperated strings
                if isinstance(value,tuple) or isinstance(value,list):
                    value = ', '.join(value)
                # make sure we have no unicode headers
                if isinstance(value,unicode):
                    value = value.encode(encoding)
                headers[header]=value
        # check required values have been supplied
        errors = []
        for param in ('mfrom','mto','subject'):
            if not values.get(param):
                errors.append(param)
        if errors:
            raise TypeError(
                'The following parameters were required by not specified: '+(
                ', '.join(errors)
                ))
        # add date header
        headers['Date']=DateTime().rfc822()
        # turn headers into an ordered list for predictable header order
        keys = headers.keys()
        keys.sort()
        return msg,values,[(key,headers[key]) for key in keys]
        
    security.declarePrivate('_send')
    def _send(self,mfrom,mto,msg):
            
        mailhost = self.restrictedTraverse(self.mailhost,None)
        if not getattr(mailhost,'meta_type',None) in (
            'Mail Host','Maildrop Host'
            ):
            raise RuntimeError(
                'Could not traverse to MailHost %r' % self.mailhost
                )
        
        mailhost._send(mfrom,mto,msg.as_string())

    security.declareProtected('View', 'send')
    def send(self,**kw):

        msg,values,headers = self._process(kw)

        for header,value in headers:
            msg[header]=value

        to_addrs = ()
        for key in ('mto', 'mcc', 'mbcc'):
            v = values.get(key)
            if v:
                if isinstance(v, basestring):
                    v = [rfc822.dump_address_pair(addr) for addr \
                            in rfc822.AddressList(v)]
                to_addrs += tuple(v)
        
        self._send(values['mfrom'], to_addrs, msg)

    security.declareProtected('View', '__call__')
    __call__ = send

    security.declareProtected('View', 'as_message')
    def as_message(self,**kw):
        msg,values,headers = self._process(kw)
        multipart_kw = {}
138 139 140 141 142 143
        #subtype = kw.get('subtype')
        #if subtype:
        #    multipart_kw['_subtype'] = subtype
        #boundary = kw.get('boundary')
        #if boundary:
        #    multipart_kw['boundary'] = boundary
144 145 146 147 148 149 150
            
        multipart = MTMultipart(self,
                                values['mfrom'],
                                values['mto'],
                                **multipart_kw)

        # set the encoding for the container
151
        #multipart.set_charset(msg.get_charset())
152 153 154 155 156 157 158 159 160 161 162
        
        for header,value in headers:
            multipart[header]=value
            
        multipart.attach(msg)

        return multipart
        
InitializeClass(BaseMailTemplate)