mirror of
https://github.com/YunoHost/moulinette.git
synced 2024-09-03 20:06:31 +02:00
65 lines
2 KiB
Python
65 lines
2 KiB
Python
import re
|
|
from itertools import ifilter
|
|
from functools import wraps
|
|
from twisted.web.resource import Resource, NoResource
|
|
|
|
class _FakeResource(Resource):
|
|
_result = ''
|
|
isLeaf = True
|
|
def __init__(self, result):
|
|
Resource.__init__(self)
|
|
self._result = result
|
|
def render(self, request):
|
|
return self._result
|
|
|
|
|
|
def maybeResource(f):
|
|
@wraps(f)
|
|
def inner(*args, **kwargs):
|
|
result = f(*args, **kwargs)
|
|
if not isinstance(result, Resource):
|
|
result = _FakeResource(result)
|
|
return result
|
|
return inner
|
|
|
|
|
|
class APIResource(Resource):
|
|
|
|
_registry = None
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
Resource.__init__(self, *args, **kwargs)
|
|
self._registry = []
|
|
|
|
def _get_callback(self, request):
|
|
filterf = lambda t:t[0] in (request.method, 'ALL')
|
|
path_to_check = getattr(request, '_remaining_path', request.path)
|
|
for m, r, cb in ifilter(filterf, self._registry):
|
|
result = r.search(path_to_check)
|
|
if result:
|
|
request._remaining_path = path_to_check[result.span()[1]:]
|
|
return cb, result.groupdict()
|
|
return None, None
|
|
|
|
def register(self, method, regex, callback):
|
|
self._registry.append((method, re.compile(regex), callback))
|
|
|
|
def unregister(self, method=None, regex=None, callback=None):
|
|
if regex is not None: regex = re.compile(regex)
|
|
for m, r, cb in self._registry[:]:
|
|
if not method or (method and m==method):
|
|
if not regex or (regex and r==regex):
|
|
if not callback or (callback and cb==callback):
|
|
self._registry.remove((m, r, cb))
|
|
|
|
def getChild(self, name, request):
|
|
r = self.children.get(name, None)
|
|
if r is None:
|
|
# Go into the thing
|
|
callback, args = self._get_callback(request)
|
|
if callback is None:
|
|
return NoResource()
|
|
else:
|
|
return maybeResource(callback)(request, **args)
|
|
else:
|
|
return r
|