changeset 219:36673d19c87e

server side: better async bridge calls handling
author Goffi <goffi@goffi.org>
date Sat, 21 Sep 2013 14:58:21 +0200
parents 4e6467efd6bf
children 09e4de9df5b7
files libervia.tac
diffstat 1 files changed, 45 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/libervia.tac	Sat Sep 07 19:54:41 2013 +0200
+++ b/libervia.tac	Sat Sep 21 14:58:21 2013 +0200
@@ -29,6 +29,7 @@
 from twisted.web.resource import Resource, NoResource
 from twisted.web.util import Redirect
 from twisted.python.components import registerAdapter
+from twisted.python.failure import Failure
 from twisted.words.protocols.jabber.jid import JID
 from txjsonrpc.web import jsonrpc
 from txjsonrpc import jsonrpclib
@@ -122,11 +123,41 @@
             del self.waiting_ids[action_tuple]
             callback(answer_type, action_id, data, *args, **kwargs)
 
-class MethodHandler(jsonrpc.JSONRPC):
+class JSONRPCMethodManager(jsonrpc.JSONRPC):
 
     def __init__(self, sat_host):
         jsonrpc.JSONRPC.__init__(self)
         self.sat_host=sat_host
+
+    def asyncBridgeCall(self, method_name, *args, **kwargs):
+        """Call an asynchrone bridge method and return a deferred
+        @param method_name: name of the method as a unicode
+        @return: a deferred which trigger the result
+
+        """
+        d = defer.Deferred()
+
+        def _callback(*args):
+            if not args:
+                d.callback(None)
+            else:
+                if len(args) != 1:
+                    Exception("Multiple return arguments not supported")
+                d.callback(args[0])
+
+        def _errback(result):
+            d.errback(Failure(unicode(result)))
+        
+        kwargs["callback"] = d.callback
+        kwargs["errback"] = _errback
+        getattr(self.sat_host.bridge, method_name)(*args, **kwargs)
+        return d
+
+
+class MethodHandler(JSONRPCMethodManager):
+
+    def __init__(self, sat_host):
+        JSONRPCMethodManager.__init__(self, sat_host)
         self.authorized_params = None
 
     def render(self, request):
@@ -232,8 +263,7 @@
         @param max_item: number of items to ask
         @return list of microblog data (dict)"""
         profile = ISATSession(self.session).profile
-        d = defer.Deferred()
-        self.sat_host.bridge.getLastGroupBlogs(publisher_jid, max_item, profile, callback=d.callback, errback=d.errback)
+        d = self.asyncBridgeCall("getLastGroupBlogs", publisher_jid, max_item, profile)
         return d
 
     def jsonrpc_getMassiveLastMblogs(self, publishers_type, publishers_list, max_item):
@@ -243,8 +273,7 @@
         @param max_item: number of items to ask
         @return: dictionary key=publisher's jid, value=list of microblog data (dict)"""
         profile = ISATSession(self.session).profile
-        d = defer.Deferred()
-        self.sat_host.bridge.getMassiveLastGroupBlogs(publishers_type, publishers_list, max_item, profile, callback=d.callback, errback=d.errback)
+        d = self.asyncBridgeCall("getMassiveLastGroupBlogs", publishers_type, publishers_list, max_item, profile)
         self.sat_host.bridge.massiveSubscribeGroupBlogs(publishers_type, publishers_list, profile)
         return d
 
@@ -254,8 +283,7 @@
         @param node: comments node
         """
         profile = ISATSession(self.session).profile
-        d = defer.Deferred()
-        self.sat_host.bridge.getGroupBlogComments(service, node, profile, callback=d.callback, errback=d.errback)
+        d = self.asyncBridgeCall("getGroupBlogComments", service, node, profile)
         return d
 
 
@@ -275,8 +303,7 @@
         if JID(from_jid).userhost() != sat_jid.userhost() and JID(to_jid).userhost() != sat_jid.userhost():
             error("Trying to get history from a different jid, maybe a hack attempt ?")
             return {}
-        d = defer.Deferred()
-        self.sat_host.bridge.getHistory(from_jid, to_jid, size, between, profile, callback=d.callback, errback=d.errback)
+        d = self.asyncBridgeCall("getHistory", from_jid, to_jid, size, between, profile)
         def show(result_dbus):
             result = []
             for line in result_dbus:
@@ -362,7 +389,7 @@
     def jsonrpc_getParamsUI(self):
         """Return the parameters XML for profile"""
         profile = ISATSession(self.session).profile
-        d = defer.Deferred()
+        d = self.asyncBridgeCall("getParams", SECURITY_LIMIT, profile)
 
         def setAuthorizedParams(d):
             if self.authorized_params is None:
@@ -375,12 +402,12 @@
                 return d
             else:
                 return None
+        
         d.addCallback(setAuthorizedParams)
 
         from sat.tools.xml_tools import paramsXml2xmlUI
         d.addCallback(lambda d: paramsXml2xmlUI(d) if d else "")
 
-        self.sat_host.bridge.getParams(SECURITY_LIMIT, profile, callback=d.callback, errback=d.errback)
         return d
 
     def jsonrpc_setParam(self, name, value, category):
@@ -403,13 +430,12 @@
         self.sat_host.bridge.chatStateComposing(to_jid_s, profile)
 
 
-class Register(jsonrpc.JSONRPC):
+class Register(JSONRPCMethodManager):
     """This class manage the registration procedure with SàT
     It provide an api for the browser, check password and setup the web server"""
 
     def __init__(self, sat_host):
-        jsonrpc.JSONRPC.__init__(self)
-        self.sat_host=sat_host
+        JSONRPCMethodManager.__init__(self, sat_host)
         self.profiles_waiting={}
         self.request=None
 
@@ -488,8 +514,7 @@
                 return
 
             self.profiles_waiting[_login] = request
-            d = defer.Deferred()
-            self.sat_host.bridge.asyncConnect(_login, lambda: d.callback(None), d.errback)
+            d = self.asyncBridgeCall("asyncConnect", _login)
             return d
         
         def profile_pass_errback(ignore):
@@ -497,8 +522,7 @@
             request.write("AUTH ERROR")
             request.finish()
         
-        d = defer.Deferred()
-        self.sat_host.bridge.asyncGetParamA("Password", "Connection", profile_key=_login, callback=d.callback, errback=d.errback)
+        d = self.asyncBridgeCall("asyncGetParamA", "Password", "Connection", profile_key=_login)
         d.addCallbacks(profile_pass_cb, profile_pass_errback)
 
         return server.NOT_DONE_YET
@@ -507,12 +531,10 @@
         """Called when a account has just been created,
         setup stuff has microblog access"""
         def _connected(ignore):
-            mblog_d = defer.Deferred()
-            self.sat_host.bridge.setMicroblogAccess("open", profile, lambda: mblog_d.callback(None), mblog_d.errback)
+            mblog_d = self.asyncBridgeCall("setMicroblogAccess", "open", profile)
             mblog_d.addBoth(lambda ignore: self.sat_host.bridge.disconnect(profile))
        
-        d = defer.Deferred()
-        self.sat_host.bridge.asyncConnect(profile, lambda: d.callback(None), d.errback)
+        d = self.asyncBridgeCall("asyncConnect", profile)
         d.addCallback(_connected)
 
     def _registerNewAccount(self, request):
@@ -551,8 +573,7 @@
                 request.write('Unknown error (%s)' % reason)
             request.finish()
             
-        d = defer.Deferred()
-        self.sat_host.bridge.registerSatAccount(email, password, profile, lambda: d.callback(None), d.errback)
+        d = self.asyncBridgeCall("registerSatAccount", email, password, profile)
         d.addCallback(registered)
         d.addErrback(registeringError)
         return server.NOT_DONE_YET