"""quixote.util

Contains various useful functions:

  xmlrpc(request, func) : Processes the body of an XML-RPC request, and calls
                          'func' with the method name and parameters.
"""

__revision__ = "$Id: util.py,v 1.4 2002/11/20 19:43:22 gward Exp $"

import sys, xmlrpclib

def xmlrpc (request, func):
    """xmlrpc(request:Request, func:callable) : string

    Processes the body of an XML-RPC request, and calls 'func' with
    two arguments, a string containing the method name and a tuple of
    parameters.
    """

    # Get contents of POST body
    method = request.environ['REQUEST_METHOD']
    if method != 'POST':
        request.response.set_status(405, "Only the POST method is accepted")
        return "XML-RPC handlers only accept the POST method."

    length = int(request.environ['CONTENT_LENGTH'])
    data = request.stdin.read(length)

    # Parse arguments
    params, method = xmlrpclib.loads(data)

    try:
        result = func(method, params)
    except xmlrpclib.Fault, exc:
        result = exc
    except:
        # report exception back to client
        result = xmlrpclib.dumps(
            xmlrpclib.Fault(1, "%s:%s" % (sys.exc_type, sys.exc_value))
            )
    else:
        result = (result,)
        result = xmlrpclib.dumps(result, methodresponse=1)

    request.response.set_header('content-type', 'text/xml')
    return result
