from xmlrpclib import loads, dumps, Fault, ResponseError from django.http import HttpResponse, HttpResponseNotAllowed from django.utils.functional import wraps from django.utils.html import strip_spaces_between_tags METHOD_NOT_SUPPORTED = Fault(0, "method not supported") class XMLRPC(object): def __init__(self): self.handlers = {} def register(self, xmlrpcname): "decorator to add an XML-RPC method" def inner(func): self.handlers[xmlrpcname] = func return func return wraps(func)(inner) def view(self, request): "view function for handling an XML-RPC request" if request.method != "POST": return HttpResponseNotAllowed("POST") try: args, method = loads(request.raw_post_data) except ResponseError: return HttpResponseNotAllowed("XML-RPC") if method is None: return HttpResponseNotAllowed("XML-RPC") if method not in self.handlers: result = METHOD_NOT_SUPPORTED else: try: result = self.handlers[method](*args) except Fault, fault: result = fault result = isinstance(result, tuple) and result or (result,) result = strip_spaces_between_tags(dumps(result, methodresponse=True)) response = HttpResponse(mimetype="text/xml") response.write(result) response["Content-Length"] = len(response.content) return response