From 0df18b3f65eab649cfdad2ec32c7631ce9131e3b Mon Sep 17 00:00:00 2001 From: Luca Clementi Date: Tue, 31 Mar 2009 18:27:55 +0000 Subject: [PATCH] Added binary attachment support (client only) --- MIMEAttachment.py | 110 ++++++++++++++++++++++++++++++++++++++++++++++ Namespaces.py | 4 +- Utility.py | 1 + 3 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 MIMEAttachment.py diff --git a/MIMEAttachment.py b/MIMEAttachment.py new file mode 100644 index 0000000..2376cc8 --- /dev/null +++ b/MIMEAttachment.py @@ -0,0 +1,110 @@ +#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.maxint-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.maxint)) + (_fmt % random.randrange(sys.maxint)) + ">" + + + 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.maxint) + 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 + diff --git a/Namespaces.py b/Namespaces.py index 699ce6d..85be392 100755 --- a/Namespaces.py +++ b/Namespaces.py @@ -24,7 +24,9 @@ except: XSD1 = "http://www.w3.org/1999/XMLSchema" XSD2 = "http://www.w3.org/2000/10/XMLSchema" XSD3 = "http://www.w3.org/2001/XMLSchema" - XSD_LIST = [ XSD1, XSD2, XSD3 ] + #AXIS attachment implementation details + AXIS = "http://xml.apache.org/xml-soap" + XSD_LIST = [ XSD1, XSD2, XSD3, AXIS] XSI1 = "http://www.w3.org/1999/XMLSchema-instance" XSI2 = "http://www.w3.org/2000/10/XMLSchema-instance" XSI3 = "http://www.w3.org/2001/XMLSchema-instance" diff --git a/Utility.py b/Utility.py index bb07159..df536b9 100755 --- a/Utility.py +++ b/Utility.py @@ -976,6 +976,7 @@ class ElementProxy(Base, MessageInterface): def createAttributeNS(self, namespace, name, value): document = self._getOwnerDocument() + ##this function doesn't exist!! it has only two arguments attrNode = document.createAttributeNS(namespace, name, value) def setAttributeNS(self, namespaceURI, localName, value):