From: <lcl...@us...> - 2009-03-31 18:27:11
|
Revision: 1482 http://pywebsvcs.svn.sourceforge.net/pywebsvcs/?rev=1482&view=rev Author: lclement Date: 2009-03-31 18:27:03 +0000 (Tue, 31 Mar 2009) Log Message: ----------- Added binary attachment support (only cliend side). Modified Paths: -------------- trunk/zsi/CHANGES trunk/zsi/ZSI/TCapache.py trunk/zsi/ZSI/client.py trunk/zsi/ZSI/typeinterpreter.py trunk/zsi/ZSI/writer.py trunk/zsi/test/test_t8.py Modified: trunk/zsi/CHANGES =================================================================== --- trunk/zsi/CHANGES 2009-02-10 20:05:51 UTC (rev 1481) +++ trunk/zsi/CHANGES 2009-03-31 18:27:03 UTC (rev 1482) @@ -5,6 +5,8 @@ - In SoapWriter, put nsdecls on body, not envelope - Record facets (restrictions) in XMLSchema.py <vc...@da...> - Remove Send()'s kwargs out of _args list <ef...@bo...> + - Added support for file attachment using AXIS apachesoap:DataHandler to + reference it in the WSDL (only client side) lcl...@sf... Change for 2.1.0_a1 released 31-Oct-2007: - No PyXML Dependency, use minidom by default (much faster) Modified: trunk/zsi/ZSI/TCapache.py =================================================================== --- trunk/zsi/ZSI/TCapache.py 2009-02-10 20:05:51 UTC (rev 1481) +++ trunk/zsi/ZSI/TCapache.py 2009-03-31 18:27:03 UTC (rev 1482) @@ -4,7 +4,9 @@ ''' from ZSI import _copyright, _child_elements, _get_idstr -from ZSI.TC import TypeCode, Struct as _Struct, Any as _Any +from ZSI.TC import SimpleType, TypeCode, Struct as _Struct, Any as _Any +from ZSI.wstools.logging import getLogger as _GetLogger +#import types class Apache: NS = "http://xml.apache.org/xml-soap" @@ -70,6 +72,54 @@ self.tc.serialize(el, sw, {'key': k, 'value': v}, name='item') +class AttachmentRef(SimpleType): + '''Type code for Attachment. This attachment will work only with axis... + ''' + + logger = _GetLogger('ZSI.TC.Attachment') + type = (Apache.NS, "DataHandler") + parselist = [(Apache.NS, "DataHandler")] + #seriallist = [ types.FileType ] + + def __init__(self, pname=None, format='%s', **kw): + TypeCode.__init__(self, pname, **kw) + self.format = format + + + def parse(self, elt, ps): + #never invoked ??? + #print "elt is: " + str(elt) + #print "while ps: " + str(ps) + return + + def get_formatted_content(self, pyobj): + return self.format %pyobj + + def serialize(self, elt, sw, pyobj, name=None, orig=None, **kw): + '''This function is in charge of serializing the attachment + fist it add the <attachment href=""/> tag + then it wraps up everything + + pyobj is the file descriptor pointing to the file we wanna attach + elt is the ElementProxy containing the <inputFile> tag with the attachment tag + sw SoapWriter + ''' + #print "serialize called with pyobj: " + str(pyobj) + #adding the attachment tag + if pyobj is None: + return + if not sw.Known(pyobj): + sw.addAttachment(pyobj) + idhref = id(pyobj) + attachmentElement = elt.createAppendElement(None, "attachment", prefix="") + attachmentElement.setAttributeNS(None, "href", "cid:" + str(idhref)) + else: + #print "the file " + pyobj + " was already attached" + #do nothing + #this should not happen + pass + + Apache.Map = _Map if __name__ == '__main__': print _copyright Modified: trunk/zsi/ZSI/client.py =================================================================== --- trunk/zsi/ZSI/client.py 2009-02-10 20:05:51 UTC (rev 1481) +++ trunk/zsi/ZSI/client.py 2009-03-31 18:27:03 UTC (rev 1482) @@ -289,6 +289,8 @@ soapdata = str(sw) self.h = transport(netloc, None, **self.transdict) self.h.connect() + self.boundary = sw.getMIMEBoundary() + self.startCID = sw.getStartCID() self.SendSOAPData(soapdata, url, soapaction, **kw) def SendSOAPData(self, soapdata, url, soapaction, headers={}, **kw): @@ -301,7 +303,13 @@ request_uri = _get_postvalue_from_absoluteURI(url) self.h.putrequest("POST", request_uri) self.h.putheader("Content-Length", "%d" % len(soapdata)) - self.h.putheader("Content-Type", 'text/xml; charset="%s"' %UNICODE_ENCODING) + if len(self.boundary) == 0: + #no attachment + self.h.putheader("Content-Type", 'text/xml; charset="%s"' %UNICODE_ENCODING) + else: + #we have attachment + contentType = "multipart/related; " + self.h.putheader("Content-Type" , "multipart/related; boundary=\"" + self.boundary + "\"; start=\"" + self.startCID + '\"; type="text/xml"') self.__addcookies() for header,value in headers.items(): Modified: trunk/zsi/ZSI/typeinterpreter.py =================================================================== --- trunk/zsi/ZSI/typeinterpreter.py 2009-02-10 20:05:51 UTC (rev 1481) +++ trunk/zsi/ZSI/typeinterpreter.py 2009-03-31 18:27:03 UTC (rev 1482) @@ -31,7 +31,7 @@ TC.gMonthDay, TC.InonPositiveInteger, \ TC.Ibyte, TC.FPdouble, TC.gTime, TC.gYear, \ TC.Ilong, TC.IunsignedLong, TC.Ishort, \ - TC.Token, TC.QName] + TC.Token, TC.QName, ZSI.TCapache.AttachmentRef] self._tc_to_int = [ ZSI.TCnumbers.IEnumeration, @@ -63,7 +63,8 @@ ZSI.TC.String, ZSI.TC.URI, ZSI.TC.XMLString, - ZSI.TC.Token] + ZSI.TC.Token, + ZSI.TCapache.AttachmentRef] self._tc_to_tuple = [ ZSI.TC.Duration, @@ -86,7 +87,7 @@ if untaged_xsd_types.has_key(msg_type): return untaged_xsd_types[msg_type] for tc in self._type_list: - if tc.type == (SCHEMA.XSD3,msg_type): + if tc.type == (SCHEMA.XSD3,msg_type) or tc.type == (SCHEMA.AXIS,msg_type): break else: tc = TC.AnyType Modified: trunk/zsi/ZSI/writer.py =================================================================== --- trunk/zsi/ZSI/writer.py 2009-02-10 20:05:51 UTC (rev 1481) +++ trunk/zsi/ZSI/writer.py 2009-03-31 18:27:03 UTC (rev 1482) @@ -8,6 +8,8 @@ from ZSI.wstools.Utility import MessageInterface, ElementProxy from ZSI.wstools.Namespaces import XMLNS, SOAP, SCHEMA from ZSI.wstools.c14n import Canonicalize +from ZSI.wstools.MIMEAttachment import MIMEMessage + import types _standard_ns = [ ('xml', XMLNS.XML), ('xmlns', XMLNS.BASE) ] @@ -46,11 +48,36 @@ self.body = None self.callbacks = [] self.closed = False + self._attachments = [] + self._MIMEBoundary = "" + self._startCID = "" def __str__(self): self.close() - return str(self.dom) + if len(self._attachments) == 0: + #we have no attachment let's return the SOAP message + return str(self.dom) + else: + #we have some files to attach let's create the MIME message + #first part the SOAP message + msg = MIMEMessage() + msg.addXMLMessage(str(self.dom)) + for file in self._attachments: + msg.attachFile(file) + msg.makeBoundary() + self._MIMEBoundary = msg.getBoundary() + self._startCID = msg.getStartCID() + return msg.toString() + def getMIMEBoundary(self): + #return the httpHeader if any + return self._MIMEBoundary + + def getStartCID(self): + #return the CID of the xml part + return self._startCID + + def getSOAPHeader(self): if self.header in (True, False): return None @@ -120,7 +147,7 @@ if root not in [ 0, 1 ]: raise ValueError, "SOAP-ENC root attribute not in [0,1]" elt.setAttributeNS(SOAP.ENC, 'root', root) - + return self def writeNSdict(self, nsdict): @@ -175,6 +202,12 @@ ''' return _backtrace(elt._getNode(), self.dom._getNode()) + + def addAttachment(self, fileDesc): + '''This function add an attachment to the SaopMessage + ''' + self._attachments.append(fileDesc) + def close(self): '''Invoke all the callbacks, and close off the SOAP message. ''' Modified: trunk/zsi/test/test_t8.py =================================================================== --- trunk/zsi/test/test_t8.py 2009-02-10 20:05:51 UTC (rev 1481) +++ trunk/zsi/test/test_t8.py 2009-03-31 18:27:03 UTC (rev 1482) @@ -1,6 +1,6 @@ #!/usr/bin/env python import unittest, sys, types, time -from ZSI import TC, SoapWriter, ParsedSoap, EvaluateException +from ZSI import TC, SoapWriter, ParsedSoap, EvaluateException, TCapache from ZSI.wstools.Namespaces import SCHEMA, SOAP NSDICT = {'tns':'xmlns:tns="urn:a"', @@ -31,7 +31,7 @@ def check_parse_empty_all(self): # None - skip = [TC.FPEnumeration, TC.Enumeration, TC.IEnumeration, TC.List, TC.Integer] + skip = [TC.FPEnumeration, TC.Enumeration, TC.IEnumeration, TC.List, TC.Integer, TCapache.AttachmentRef] for typeclass in filter(lambda c: type(c) in [types.ClassType,type] and not issubclass(c, TC.String) and issubclass(c, TC.SimpleType), TC.__dict__.values()): if typeclass in skip: continue tc = typeclass() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |