MTMultipart.py 3.01 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
# 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.

from AccessControl import ClassSecurityInfo
from email import Encoders
from email.MIMEBase import MIMEBase
from email.MIMEMultipart import MIMEMultipart
from Globals import InitializeClass
12 13 14 15
try:
  from zope.app.content_types import guess_content_type
except ImportError:
  from OFS.content_types import guess_content_type # Zope 2.7
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
from OFS.Image import File
from ZPublisher.HTTPRequest import FileUpload

def cookId(filename):
    return filename[max(filename.rfind('/'),
                        filename.rfind('\\'),
                        filename.rfind(':'),
                        )+1:]
    
class MTMultipart(MIMEMultipart):

    security = ClassSecurityInfo()
    
    security.setDefaultAccess('allow')
    
    def __init__(self,mt,mfrom,mto,_subtype='mixed',boundary=None):
        MIMEMultipart.__init__(self,_subtype,boundary)
        self.mfrom = mfrom
        self.mto = mto
        self.mt = mt

    security.declarePublic('send')
    def send(self):
        "send ourselves using our MailTemplate's send method"
        return self.mt._send(self.mfrom,self.mto,self)

    security.declarePublic('add_file')
    def add_file(self,theFile=None,data=None,filename=None,content_type=None):
        "add a Zope file or Image to ourselves as an attachment"
        if theFile and data:
            raise TypeError(
                'A file-like object was passed as well as data to create a file'
                )
        if (data or filename) and not (data and filename):
            raise TypeError(
                'Both data and filename must be specified'
                )
        if data:
            if content_type is None:
                content_type, enc=guess_content_type(filename, data)
        elif isinstance(theFile,File):
            filename = theFile.getId()
            data = str(theFile.data)
            content_type = content_type or theFile.content_type
        elif isinstance(theFile,file):
            filename = cookId(theFile.name)
            data = theFile.read()
            if content_type is None:
                content_type,enc = guess_content_type(filename, data)
        elif isinstance(theFile,FileUpload):
            filename = cookId(theFile.filename)
            data=theFile.read()
            headers=theFile.headers
            if content_type is None:
                if headers.has_key('content-type'):
                    content_type=headers['content-type']
                else:
                    content_type, enc=guess_content_type(filename, data)
        else:
            raise TypeError('Unknown object type found: %r' % theFile)
        
        msg = MIMEBase(*content_type.split('/'))
        msg.set_payload(data)
        Encoders.encode_base64(msg)
        msg.add_header('Content-Disposition', 'attachment',
                       filename=filename)
        self.attach(msg)
        
InitializeClass(MTMultipart)