view jabberbot/multicall.py @ 3233:5e120e903ad5

avoid browsers filling in the user's password into first pw field
author Thomas Waldmann <tw AT waldmann-edv DOT de>
date Sun, 09 Mar 2008 23:10:28 +0100
parents 01f05e74aa9c
children
line wrap: on
line source
""" XMLRPC MultiCall support for Python 2.3. Copied from xmlrpclib.py of Python 2.4.3. """

try:
    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]
            else:
                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)
        multicall.add(2,3)
        multicall.get_address("Guido")

        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))