BaseMailTemplate.py 5.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# 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

15 16
from App.class_init import default__class_init__ as InitializeClass
from App.Common import package_home
17
from MTMultipart import MTMultipart
18
from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate
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 138
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 = {}
139 140 141 142 143 144
        #subtype = kw.get('subtype')
        #if subtype:
        #    multipart_kw['_subtype'] = subtype
        #boundary = kw.get('boundary')
        #if boundary:
        #    multipart_kw['boundary'] = boundary
145 146 147 148 149 150 151
            
        multipart = MTMultipart(self,
                                values['mfrom'],
                                values['mto'],
                                **multipart_kw)

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

        return multipart
        
InitializeClass(BaseMailTemplate)