import re
from lxml import etree
from PyQt4.QtXml import QDomDocument
from sface.xmlwidget import XmlWindow, DomModel
class XmlrpcReader():
def __init__(self):
self.rawOutput = None
self.responses = []
def getAndPrint(self, rawOutput):
self.store(rawOutput)
self.extractXml()
self.xmlrpcWindow.setData(self.xml)
if self.xml != "":
# only popup the window if we have something to show
self.showXmlrpc()
def store(self, rawOutput):
self.rawOutput = rawOutput
def parseMethodResponse(self, mr):
tree = etree.fromstring(str(mr))
response = {"kind": "unknown"}
if tree.tag != "methodResponse" or (len(list(tree))==0):
return response
# a fault should look like:
# kind: "fault"
# faultCode: "102"
# faultString: "Register: Missing authority..."
faults = tree.xpath("//methodResponse/fault")
for fault in faults:
response["kind"] = "fault"
structs = fault.xpath("value/struct")
for struct in structs:
members = struct.xpath("member")
for member in members:
names = member.xpath("name")
values = member.xpath("value")
if (names) and (values):
name = names[0]
value = values[0]
if len(list(value))>0:
data = list(value)[0]
response[name.text] = data.text
# once we have the first fault, return
return response
# whatever didn't fault must have succeeded?
response["kind"] = "success"
return response
def extractXml(self):
pttrnAsk = '.*?'
pttrnAns = '.*?'
answers = re.compile(pttrnAsk, re.DOTALL).findall(self.rawOutput)
replies = re.compile(pttrnAns, re.DOTALL).findall(self.rawOutput)
# cleaning
answers = [ x.replace('\\n','\n') for x in answers ]
replies = [ x.replace('\\n','\n').replace("'\nbody: '", '') for x in replies ]
replies.reverse() # so that I use pop() as popleft
# A well-formed XML document must have one, and only one, top-level element
self.responses = []
self.xml = ""
for ans in answers:
self.xml += ans
# we could have less responses than calls, so guard the pop
if replies:
replyXml = replies.pop()
self.xml += replyXml
self.responses.append(self.parseMethodResponse(replyXml))
# just in case somehow we ended up with more responses than calls
while replies:
replyXml = replies.pop()
self.xml += replyXml
self.responses.append(self.parseMethodResponse(replyXml))
return self.xml
def stats(self):
# statistics: round-trip time, size of the com
pass
class XmlrpcTracker(XmlrpcReader):
def __init__(self):
XmlrpcReader.__init__(self)
self.xmlrpcWindow = XmlrpcWindow()
def getAndPrint(self, rawOutput):
self.store(rawOutput)
self.extractXml()
self.xmlrpcWindow.setData(self.xml)
if self.xml != "":
# only popup the window if we have something to show
self.showXmlrpc()
def showXmlrpc(self):
self.xmlrpcWindow.show()
self.xmlrpcWindow.resize(500, 640)
self.xmlrpcWindow.raise_()
self.xmlrpcWindow.activateWindow()
def extractXml(self):
self.xml = "" + XmlrpcReader.extractXml(self) + ""
class XmlrpcWindow(XmlWindow):
def __init__(self, parent=None):
# super __init__() calls updateView,
# which assumes you have some data
self.data = ''
XmlWindow.__init__(self, parent, 'XMLRPC window')
def setData(self, XmlrpcCom):
self.data = XmlrpcCom
def updateView(self):
XmlWindow.updateView(self)
self.document.setContent(self.data)