view jabberbot/multicall.py @ 5132:df8f5b4546ca

mailimport: fix endless looping while trying to import a forwarded mail This is just a fix to solve the endless looping / crash. It needs further improvement, currently the From/To/... header data of the forwarded mail is not processed at all and thus not visible later in the wiki. The body of it is visible, though, but just appears appended to the main mail body.
author Thomas Waldmann <tw AT waldmann-edv DOT de>
date Sun, 06 Sep 2009 22:35:50 +0200
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))