/
resources.py
98 lines (72 loc) · 2.35 KB
/
resources.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import asyncio
import logging
from resolver_deco import resolver
from aiohttp_traversal.abc import AbstractResource
from aiohttp_traversal.traversal import Traverser
log = logging.getLogger(__name__)
class Resource(AbstractResource):
_parent = None
name = None
app = None
setup = None
def __init__(self, parent, name):
self._parent = parent
self.name = str(name)
if parent is not None:
self.app = parent.app
self.setup = self.app.router.resources.get(self.__class__)
@property
def __parent__(self):
return self._parent
def __getitem__(self, name):
return Traverser(self, (name,))
@asyncio.coroutine
def __getchild__(self, name):
return None
class InitCoroMixin:
""" Mixin for create initialization coroutine
"""
def __new__(cls, *args, **kwargs):
""" This is magic!
"""
instance = super().__new__(cls)
@asyncio.coroutine
def coro():
instance.__init__(*args, **kwargs)
yield from instance.__ainit__()
return instance
return coro()
@asyncio.coroutine
def __ainit__(self):
raise NotImplementedError
class DispatchMixin:
@asyncio.coroutine
def __getchild__(self, name):
if (self.setup is not None and
'children' in self.setup and
name in self.setup['children']):
res = self.setup['children'][name](self, name)
if asyncio.iscoroutine(res):
return (yield from res)
else:
return res
else:
return None
class DispatchResource(DispatchMixin, Resource):
pass
class Root(DispatchResource):
def __init__(self, app, *args, **kwargs):
super().__init__(parent=None, name=None)
self.app = app
self.args = args
self.kwargs = kwargs
self.setup = self.app.router.resources.get(self.__class__)
@resolver('parent', 'child')
def add_child(app, parent, name, child):
""" Add child resource for dispatch-resources
"""
if not issubclass(parent, DispatchMixin):
raise ValueError("{!r} is not a DispatchMixin subclass"
"".format(parent))
parent_setup = app.router.resources.setdefault(parent, {})
parent_setup.setdefault('children', {})[name] = child