diff --git a/pyweb/extdirect.py b/pyweb/extdirect.py new file mode 100644 index 0000000..c312fa3 --- /dev/null +++ b/pyweb/extdirect.py @@ -0,0 +1,92 @@ +# -*- coding: utf-8 -*- +# kate: space-indent on; indent-width 4; replace-tabs on; + +""" + * Copyright (C) 2010, Michael "Svedrin" Ziegler + * + * Mumble-Django is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This package is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. +""" + +import simplejson +import inspect +import functools + +from django.http import HttpResponse + +def getname( cls_or_name ): + if type(cls_or_name) not in ( str, unicode ): + return cls_or_name.__name__ + return cls_or_name + +class Provider( object ): + def __init__( self, base_url ): + self.base_url = base_url + self.classes = {} + + def register_instance( self, cls_or_name, instance ): + name = getname(cls_or_name) + if name not in self.classes: + raise KeyError(name) + self.classes[ name ][0] = instance + return instance + + def register_method( self, cls_or_name ): + """ Return a function that takes a method as an argument and adds that to cls_or_name. """ + print "REGMETHOD", cls_or_name + clsname = getname(cls_or_name) + if clsname not in self.classes: + self.classes[clsname] = ( None, {} ) + return functools.partial( self._register_method, cls_or_name ) + + def _register_method( self, cls_or_name, method ): + print "REGREALMETHOD", cls_or_name, method + self.classes[ getname(cls_or_name) ][1][ method.__name__ ] = method + return method + + def get_api( self, name="Ext.app.REMOTING_API" ): + """ Introspect the methods and get a JSON description of this API. """ + actdict = {} + for clsname in self.classes: + actdict[clsname] = [] + for methodname in self.classes[clsname][1]: + actdict[clsname].append( { + "name": methodname, + "len": len( inspect.getargspec( self.classes[clsname][1][methodname] ).args ) + } ) + + return "%s = %s" % ( name, simplejson.dumps({ + "url": ("%s/router" % self.base_url), + "type": "remoting", + "actions": actdict + })) + + def request( self, request ): + cls = request.POST['extAction'] + methname = request.POST['extMethod'] + data = request.POST['extData'] + rtype = request.POST['extType'] + tid = request.POST['extTID'] + + if cls not in self.classes: + raise KeyError(cls) + if methname not in self.classes[cls][1]: + raise KeyError(methname) + + result = self.classes[cls][1][methname]( *data, request=request ) + + return HttpResponse( simplejson.dumps({ + "type": rtype, + "tid": tid, + "action": cls, + "method": methname, + "result": result + })) + diff --git a/pyweb/mumble/views.py b/pyweb/mumble/views.py index c6748de..fea567e 100644 --- a/pyweb/mumble/views.py +++ b/pyweb/mumble/views.py @@ -32,6 +32,13 @@ from models import Mumble, MumbleUser from forms import MumbleForm, MumbleUserForm, MumbleUserPasswordForm from forms import MumbleUserLinkForm, MumbleTextureForm, MumbleKickForm +from extdirect import Provider + +EXT_DIRECT_PROVIDER = Provider( "/mumble/ext" ) + +@EXT_DIRECT_PROVIDER.register_method( "omgfu" ) +def ohai( request ): + return "plzkthx" def redir( request ): """ Redirect to the servers list. """