Newer
Older
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
from django import urls
from pluggy import PluginManager, HookimplMarker, HookspecMarker
plugins_manager = PluginManager("funkwhale")
hook = HookimplMarker("funkwhale")
hookspec = HookspecMarker("funkwhale")
class PluginViewMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
from django.conf import settings
response = self.get_response(request)
if response.status_code == 404 and request.path.startswith("/plugins/"):
match = urls.resolve(request.path, urlconf=settings.PLUGINS_URLCONF)
response = match.func(request, *match.args, **match.kwargs)
return response
class ConfigError(ValueError):
pass
class Plugin:
conf = {}
def get_conf(self):
return {"enabled": self.plugin_settings.enabled}
def register_api_view(self, path, name=None):
def register(view):
return urls.path(
"plugins/{}/{}".format(self.name.replace("_", "-"), path),
view,
name="plugins-{}-{}".format(self.name, name),
)
return register
def plugin_settings(self):
"""
Return plugin specific settings from django.conf.settings
"""
import ipdb
ipdb.set_trace()
from django.conf import settings
d = {}
for key in dir(settings):
k = key.lower()
if not k.startswith("plugin_{}_".format(self.name.lower())):
continue
value = getattr(settings, key)
s_key = k.replace("plugin_{}_".format(self.name.lower()), "")
d[s_key] = value
return clean(d, self.conf, self.name)
def clean(d, conf, plugin_name):
cleaned = {}
for key, c in conf.items():
if key in d:
try:
cleaned[key] = c["validator"](d[key])
except (ValueError, TypeError, AttributeError):
raise ConfigError(
"Invalid value {} for setting {} in plugin {}".format(
d[key], key, plugin_name
)
)
else:
cleaned[key] = c["default"]
return cleaned
def reverse(name, **kwargs):
from django.conf import settings
return urls.reverse(name, settings.PLUGINS_URLCONF, **kwargs)
def resolve(name, **kwargs):
from django.conf import settings
return urls.resolve(name, settings.PLUGINS_URLCONF, **kwargs)
# def install_plugin(name_or_path):
# subprocess.check_call([sys.executable, "-m", "pip", "install", package])
# sub
class HookSpec:
@hookspec
def register_apps(self):
"""
Register additional apps in INSTALLED_APPS.
:rvalue: list"""
@hookspec
def middlewares_before(self):
"""
Register additional middlewares at the outer level.
:rvalue: list"""
@hookspec
def middlewares_after(self):
"""
Register additional middlewares at the inner level.
:rvalue: list"""
@hookspec
def urls(self):
"""
Register additional urls.
:rvalue: list"""
plugins_manager.add_hookspecs(HookSpec())