|
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.
|