scrolling in xmlrpctracker
[sface.git] / sface / xmlrpcwindow.py
index 72b0f68..91f0c01 100644 (file)
@@ -1,4 +1,5 @@
 import re
 import re
+import xmlrpclib
 from lxml import etree
 from PyQt4.QtXml import QDomDocument
 from sface.xmlwidget import XmlWindow, DomModel, XmlView, XmlDelegate, ElemNodeDelegate, TextNodeDelegate, CommentNodeDelegate
 from lxml import etree
 from PyQt4.QtXml import QDomDocument
 from sface.xmlwidget import XmlWindow, DomModel, XmlView, XmlDelegate, ElemNodeDelegate, TextNodeDelegate, CommentNodeDelegate
@@ -15,39 +16,6 @@ class XmlrpcReader():
     def store(self, rawOutput):
         self.rawOutput = rawOutput
 
     def store(self, rawOutput):
         self.rawOutput = rawOutput
 
-    def paramString(self, item):
-        """
-           Convert an xmlrpc <PARAM> into a human-readable string
-           Is there an easier way?
-        """
-        if item.tag == "string":
-            return item.text
-        elif item.tag == "array":
-            arrayValues = item.xpath("data/value")
-            if arrayValues:
-                children = list(arrayValues[0])
-                if children:
-                    return self.paramString(children[0]) + ", ..."
-                else:
-                    return "[]"
-            else:
-                return "[]"
-        elif item.tag == "struct":
-            dict = {}
-            members = item.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]
-                        dict[name.text] = self.paramString(list(value)[0])
-            return str(dict)
-        else:
-            return "unknown"
-
     def parseMethodCall(self, mc):
         mc = str(mc)
 
     def parseMethodCall(self, mc):
         mc = str(mc)
 
@@ -61,20 +29,14 @@ class XmlrpcReader():
         if tree.tag != "methodCall" or (len(list(tree))==0):
             return request
 
         if tree.tag != "methodCall" or (len(list(tree))==0):
             return request
 
-        methodNames = tree.xpath("//methodCall/methodName")
-
-        if len(methodNames) == 0:
-            return request
-
-        request["args"] = []
-
-        params = tree.xpath("//methodCall/params/param/value")
-        for param in params:
-            children = list(param)
-            if children:
-                request["args"].append(self.paramString(children[0]))
+        try:
+            (pythonParams, methodName) = xmlrpclib.loads(etree.tostring(tree))
+        except:  # in case something went wrong when unmarashaling...
+            pythonParams = []
+            methodName = "<exception in parseMethodCall>"
 
 
-        request["methodName"] = methodNames[0].text
+        request["args"] = [str(x) for x in pythonParams]
+        request["methodName"] = methodName
 
         return request
 
 
         return request
 
@@ -196,6 +158,11 @@ class XmlrpcTracker(QWidget):
         self.delegate.insertNodeDelegate('comment', CommentNodeDelegate())
         self.xmlView.setItemDelegate(self.delegate)
 
         self.delegate.insertNodeDelegate('comment', CommentNodeDelegate())
         self.xmlView.setItemDelegate(self.delegate)
 
+        exportButton = QPushButton("&Export Call")
+        layoutButtons = QHBoxLayout()
+        layoutButtons.addWidget(exportButton)
+        layoutButtons.addStretch()
+
         self.layout = QVBoxLayout()
         self.layout.addWidget(labelCalls)
         self.layout.addWidget(self.callTable)
         self.layout = QVBoxLayout()
         self.layout.addWidget(labelCalls)
         self.layout.addWidget(self.callTable)
@@ -203,10 +170,12 @@ class XmlrpcTracker(QWidget):
         self.layout.addWidget(self.argsTable)
         self.layout.addWidget(labelXml)
         self.layout.addWidget(self.xmlView)
         self.layout.addWidget(self.argsTable)
         self.layout.addWidget(labelXml)
         self.layout.addWidget(self.xmlView)
+        self.layout.addLayout(layoutButtons)
 
         self.setLayout(self.layout)
 
         self.connect(self.callTable, SIGNAL("itemSelectionChanged ()"), self.onCallSelect)
 
         self.setLayout(self.layout)
 
         self.connect(self.callTable, SIGNAL("itemSelectionChanged ()"), self.onCallSelect)
+        self.connect(exportButton, SIGNAL("clicked()"), self.onExportClicked)
 
     def getAndPrint(self, rawOutput):
         self.reader.store(rawOutput)
 
     def getAndPrint(self, rawOutput):
         self.reader.store(rawOutput)
@@ -215,8 +184,9 @@ class XmlrpcTracker(QWidget):
 
     def updateCallTable(self):
         self.callTable.clear()
 
     def updateCallTable(self):
         self.callTable.clear()
-        self.callTable.setColumnCount(2)
-        self.callTable.setHorizontalHeaderLabels(["name", "status"])
+        self.callTable.setColumnCount(3)
+        self.callTable.setHorizontalHeaderLabels(["name", "status", "faultString"])
+        self.callTable.setHorizontalScrollMode(QAbstractItemView.ScrollPerPixel)
 
         calls = self.reader.calls
         self.callTable.setRowCount(len(calls))
 
         calls = self.reader.calls
         self.callTable.setRowCount(len(calls))
@@ -235,6 +205,11 @@ class XmlrpcTracker(QWidget):
             item.setData(Qt.UserRole, index)
             self.callTable.setItem(row, 1, item)
 
             item.setData(Qt.UserRole, index)
             self.callTable.setItem(row, 1, item)
 
+            item = QTableWidgetItem(call.get("faultString", ""))
+            item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
+            item.setData(Qt.UserRole, index)
+            self.callTable.setItem(row, 2, item)
+
             row = row + 1
 
         self.callTable.resizeColumnsToContents()
             row = row + 1
 
         self.callTable.resizeColumnsToContents()
@@ -261,19 +236,27 @@ class XmlrpcTracker(QWidget):
 
         self.argsTable.resizeColumnsToContents()
 
 
         self.argsTable.resizeColumnsToContents()
 
-    def onCallSelect(self):
+    def getSelectedCall(self):
         selItems = self.callTable.selectedItems()
         if (len(selItems) <= 0):
         selItems = self.callTable.selectedItems()
         if (len(selItems) <= 0):
-            return
+            return None
 
         row = selItems[0].data(Qt.UserRole).toInt()[0]
 
         calls = self.reader.calls
         if len(calls)<=row:
 
         row = selItems[0].data(Qt.UserRole).toInt()[0]
 
         calls = self.reader.calls
         if len(calls)<=row:
-            return
+            return None
 
         call = calls[row]
 
 
         call = calls[row]
 
+        return call
+
+    def onCallSelect(self):
+        call = self.getSelectedCall()
+
+        if not call:
+            return
+
         xml = "<debug>" + call.get("request","") + call.get("reply", "") + "</debug>"
         #xml = call.get("request","") + call.get("reply", "")
 
         xml = "<debug>" + call.get("request","") + call.get("reply", "") + "</debug>"
         #xml = call.get("request","") + call.get("reply", "")
 
@@ -281,6 +264,20 @@ class XmlrpcTracker(QWidget):
 
         self.updateArgsTable(call.get("args",[]))
 
 
         self.updateArgsTable(call.get("args",[]))
 
+    def onExportClicked(self):
+        call = self.getSelectedCall()
+
+        if not call:
+            return
+
+        filename = QFileDialog.getSaveFileName(self, 'Save File', '.')
+
+        f = open(filename, "w")
+        f.write(call.get("request","") + "\n")
+        f.write(call.get("reply","") + "\n")
+        f.close()
+
+
     def displayXml(self, xml):
         self.document = QDomDocument("XMLRPC Tracker")
         self.document.setContent(xml)
     def displayXml(self, xml):
         self.document = QDomDocument("XMLRPC Tracker")
         self.document.setContent(xml)