From d4556306f2965acfe24f8a946e1785132e046b8e Mon Sep 17 00:00:00 2001 From: Gaetan Delannay Date: Thu, 11 Jul 2013 16:41:45 +0200 Subject: [PATCH] [px] Added boolean param 'unicode' that defines if PX result must be unicode or an encoded str. [shared] dav: improved Resource.soap: better handling of HTTP header SOAPAction. --- px/__init__.py | 14 +++++++++++--- shared/dav.py | 15 ++++++++------- shared/xml_parser.py | 3 +++ 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/px/__init__.py b/px/__init__.py index cd278c2..0daf084 100644 --- a/px/__init__.py +++ b/px/__init__.py @@ -6,6 +6,7 @@ import xml.sax from px_parser import PxParser, PxEnvironment from appy.pod.buffers import MemoryBuffer +from appy.shared.xml_parser import xmlPrologue, xhtmlPrologue # Exception class -------------------------------------------------------------- class PxError(Exception): pass @@ -13,11 +14,11 @@ class PxError(Exception): pass # ------------------------------------------------------------------------------ class Px: '''Represents a (chunk of) PX code.''' - xhtmlPrologue = '\n' + xmlPrologue = xmlPrologue + xhtmlPrologue = xhtmlPrologue def __init__(self, content, isFileName=False, partial=True, - template=None, hook=None, prologue=None): + template=None, hook=None, prologue=None, unicode=True): '''p_content is the PX code, as a string, or a file name if p_isFileName is True. If this code represents a complete XML file, p_partial is False. Else, we must surround p_content with a root tag to be able @@ -29,6 +30,9 @@ class Px: If a p_prologue is specified, it will be rendered at the start of the PX result. + + By default, a PX's result will be a unicode. If you want to get an + encoded str instead, use p_unicode=False. ''' # Get the PX content if isFileName: @@ -56,6 +60,8 @@ class Px: self.hook = hook # Is there some (XML, XHTML...) prologue to dump? self.prologue = prologue + # Will the result be unicode or str? + self.unicode = unicode def completeErrorMessage(self, parsingError): '''A p_parsingError occurred. Complete the error message with the @@ -96,5 +102,7 @@ class Px: res = result.content if self.prologue: res = self.prologue + res + if not self.unicode: + res = res.encode('utf-8') return res # ------------------------------------------------------------------------------ diff --git a/shared/dav.py b/shared/dav.py index 693c5ce..26c0c10 100644 --- a/shared/dav.py +++ b/shared/dav.py @@ -58,7 +58,7 @@ class SoapDataEncoder: def encode(self): # Do nothing if we have a SOAP message already if isinstance(self.data, basestring): return self.data - # self.data is here a Python object. Wrap it a SOAP Body. + # self.data is here a Python object. Wrap it in a SOAP Body. soap = Object(Body=self.data) # Marshall it. marshaller = XmlMarshaller(rootTag='Envelope', namespaces=self.ns, @@ -69,7 +69,7 @@ class SoapDataEncoder: class HttpResponse: '''Stores information about a HTTP response.''' def __init__(self, code, text, headers, body, duration=None): - self.code = code # The return code, ie 404, 200, ... + self.code = code # The return code, ie 404, 200, 500... self.text = text # Textual description of the code self.headers = headers # A dict-like object containing the headers self.body = body # The body of the HTTP response @@ -260,17 +260,18 @@ class Resource: headers['Content-Length'] = str(len(body)) return self.send('POST', uri, headers=headers, body=body) - def soap(self, data, uri=None, headers={}, namespace=None): + def soap(self, data, uri=None, headers={}, namespace=None, soapAction=None): '''Sends a SOAP message to this resource. p_namespace is the URL of the - server-specific namespace.''' + server-specific namespace. If header value "SOAPAction" is different + from self.url, specify it in p_soapAction.''' if not uri: uri = self.uri # Prepare the data to send data = SoapDataEncoder(data, namespace).encode() - headers['SOAPAction'] = self.url + headers['SOAPAction'] = soapAction or self.url headers['Content-Type'] = 'text/xml' res = self.post(data, uri, headers=headers, encode=None) # Unwrap content from the SOAP envelope - res.data = res.data.Body + if hasattr(res.data, 'Body'): + res.data = res.data.Body return res # ------------------------------------------------------------------------------ - diff --git a/shared/xml_parser.py b/shared/xml_parser.py index d3cf491..6b749ac 100644 --- a/shared/xml_parser.py +++ b/shared/xml_parser.py @@ -31,6 +31,9 @@ from appy.shared.css import parseStyleAttribute # Constants -------------------------------------------------------------------- xmlPrologue = '\n' +xhtmlPrologue = '\n' + CONVERSION_ERROR = '"%s" value "%s" could not be converted by the XML ' \ 'unmarshaller.' CUSTOM_CONVERSION_ERROR = 'Custom converter for "%s" values produced an ' \