|
- # TODO add the license
- # I had to rewrite this class because the python MIME email.mime (version 2.5)
- # are buggy, they use \n instead \r\n for new line which is not compliant
- # to standard!
- # http://bugs.python.org/issue5525
-
- # TODO do not load all the message in memory stream it from the disk
-
- import re
- import random
- import sys
-
-
- # new line
- NL = '\r\n'
-
- _width = len(repr(sys.maxsize - 1))
- _fmt = '%%0%dd' % _width
-
-
- class MIMEMessage:
-
- def __init__(self):
- self._files = []
- self._xmlMessage = ""
- self._startCID = ""
- self._boundary = ""
-
- def makeBoundary(self):
- # create the boundary
- msgparts = []
- msgparts.append(self._xmlMessage)
- for i in self._files:
- msgparts.append(i.read())
- # this sucks, all in memory
- alltext = NL.join(msgparts)
- self._boundary = _make_boundary(alltext)
- # maybe I can save some memory
- del alltext
- del msgparts
- self._startCID = "<" + (_fmt % random.randrange(sys.maxsize)) \
- + (_fmt % random.randrange(sys.maxsize)) + ">"
-
- def toString(self):
- '''it return a string with the MIME message'''
- if len(self._boundary) == 0:
- # the makeBoundary hasn't been called yet
- self.makeBoundary()
- # ok we have everything let's start to spit the message out
- # first the XML
- returnstr = NL + "--" + self._boundary + NL
- returnstr += "Content-Type: text/xml; charset=\"us-ascii\"" + NL
- returnstr += "Content-Transfer-Encoding: 7bit" + NL
- returnstr += "Content-Id: " + self._startCID + NL + NL
- returnstr += self._xmlMessage + NL
- # then the files
- for file in self._files:
- returnstr += "--" + self._boundary + NL
- returnstr += "Content-Type: application/octet-stream" + NL
- returnstr += "Content-Transfer-Encoding: binary" + NL
- returnstr += "Content-Id: <" + str(id(file)) + ">" + NL + NL
- file.seek(0)
- returnstr += file.read() + NL
- # closing boundary
- returnstr += "--" + self._boundary + "--" + NL
- return returnstr
-
- def attachFile(self, file):
- '''
- it adds a file to this attachment
- '''
- self._files.append(file)
-
- def addXMLMessage(self, xmlMessage):
- '''
- it adds the XML message. we can have only one XML SOAP message
- '''
- self._xmlMessage = xmlMessage
-
- def getBoundary(self):
- '''
- this function returns the string used in the mime message as a
- boundary. First the write method as to be called
- '''
- return self._boundary
-
- def getStartCID(self):
- '''
- This function returns the CID of the XML message
- '''
- return self._startCID
-
-
- def _make_boundary(text=None):
- # some code taken from python stdlib
- # Craft a random boundary. If text is given, ensure that the chosen
- # boundary doesn't appear in the text.
- token = random.randrange(sys.maxsize)
- boundary = ('=' * 10) + (_fmt % token) + '=='
- if text is None:
- return boundary
- b = boundary
- counter = 0
- while True:
- cre = re.compile('^--' + re.escape(b) + '(--)?$', re.MULTILINE)
- if not cre.search(text):
- break
- b = boundary + '.' + str(counter)
- counter += 1
- return b
|