Patchwork [v2,2/3] pwclient: Handle servers that barf on users with no name

login
register
mail settings
Submitter Doug Anderson
Date Dec. 4, 2012, 12:08 a.m.
Message ID <1354579699-26427-2-git-send-email-dianders@chromium.org>
Download mbox | patch
Permalink /patch/203508/
State Superseded
Headers show

Comments

Doug Anderson - Dec. 4, 2012, 12:08 a.m.
When working with pwclient I found that the xmlrpc server will barf
sometimes if a user has no real name.  The server code should be
fixed, but also fix the client to handle this more gracefully.

Signed-off-by: Doug Anderson <dianders@chromium.org>
---
Changes in v2:
- Added return value to handle the non-buggy case.

 apps/patchwork/bin/pwclient |   36 +++++++++++++++++++++++++++++++++++-
 1 files changed, 35 insertions(+), 1 deletions(-)

Patch

diff --git a/apps/patchwork/bin/pwclient b/apps/patchwork/bin/pwclient
index e642195..27bfdb3 100755
--- a/apps/patchwork/bin/pwclient
+++ b/apps/patchwork/bin/pwclient
@@ -36,6 +36,40 @@  import ConfigParser
 DEFAULT_URL = "http://patchwork/xmlrpc/"
 CONFIG_FILES = [os.path.expanduser('~/.pwclientrc')]
 
+class ServerWithFixes(xmlrpclib.Server):
+    """Wrapper for xmlrpclib.Server that handles some server issues.
+
+    This class adds workarounds for commands that might fail on some versions
+    of patchwork servers out there.  As servers are fixed then workaround
+    can be removed.
+    """
+    def person_get(self, person_id):
+        """Fix person_get() to handle people with no real name.
+
+        It appears that if you have a person with no real name then it makes
+        the server barf (it tries to marshall None but allow_none is False).
+        If we find this we'll try to grok some info about the user from patches
+        that he/she sent.
+
+        As an example, the submitter of:
+            https://patchwork.kernel.org/patch/1668321/
+        """
+        try:
+            return self.__getattr__("person_get")(person_id)
+        except xmlrpclib.Fault, e:
+            # If it's not the fault we're expecting, pass it on.
+            if e.faultString != ("<type 'exceptions.TypeError'>:cannot marshal "
+                                 "None unless allow_none is enabled"):
+                raise
+
+            # Create a fake person by grabbing the email from one of the patches
+            patch_list = self.patch_list({'submitter_id': person_id,
+                                          'max_count': 1})
+            return {
+                'name': '',
+                'email': patch_list[0]['submitter']
+            }
+
 class Filter:
     """Filter for selecting patches."""
     def __init__(self):
@@ -417,7 +451,7 @@  def main():
         filt.add("msgid", msgid_str)
 
     try:
-        rpc = xmlrpclib.Server(url, transport = transport)
+        rpc = ServerWithFixes(url, transport = transport)
     except:
         sys.stderr.write("Unable to connect to %s\n" % url)
         sys.exit(1)