view jabberbot/ @ 3055:29d236eb2ab7

updated underlay
author Thomas Waldmann <tw AT waldmann-edv DOT de>
date Wed, 20 Feb 2008 11:07:18 +0100
parents 01f05e74aa9c
line wrap: on
line source

""" XMLRPC MultiCall support for Python 2.3. Copied from of Python 2.4.3. """

    from xmlrpclib import MultiCall
except ImportError:
    from xmlrpclib import Fault

    class _MultiCallMethod:
        # some lesser magic to store calls made to a MultiCall object
        # for batch execution
        def __init__(self, call_list, name):
            self.__call_list = call_list
            self.__name = name
        def __getattr__(self, name):
            return _MultiCallMethod(self.__call_list, "%s.%s" % (self.__name, name))
        def __call__(self, *args):
            self.__call_list.append((self.__name, args))

    class MultiCallIterator:
        """Iterates over the results of a multicall. Exceptions are
        thrown in response to xmlrpc faults."""

        def __init__(self, results):
            self.results = results

        def __getitem__(self, i):
            item = self.results[i]
            if type(item) == type({}):
                raise Fault(item['faultCode'], item['faultString'])
            elif type(item) == type([]):
                return item[0]
                raise ValueError,\
                      "unexpected type in multicall result"

    class MultiCall:
        """server -> a object used to boxcar method calls

        server should be a ServerProxy object.

        Methods can be added to the MultiCall using normal
        method call syntax e.g.:

        multicall = MultiCall(server_proxy)

        To execute the multicall, call the MultiCall object e.g.:

        add_result, address = multicall()

        def __init__(self, server):
            self.__server = server
            self.__call_list = []

        def __repr__(self):
            return "<MultiCall at %x>" % id(self)

        __str__ = __repr__

        def __getattr__(self, name):
            return _MultiCallMethod(self.__call_list, name)

        def __call__(self):
            marshalled_list = []
            for name, args in self.__call_list:
                marshalled_list.append({'methodName': name, 'params': args})

            return MultiCallIterator(self.__server.system.multicall(marshalled_list))