e2xauthoring 0.2.0.dev1__py3-none-any.whl → 0.2.0.dev2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- e2xauthoring/__version__.py +1 -1
- e2xauthoring/app/handlers/apihandlers.py +76 -219
- e2xauthoring/app/handlers/base.py +83 -22
- e2xauthoring/app/templates/authoring/asset-manifest.json +3 -3
- e2xauthoring/app/templates/authoring/index.html +1 -1
- e2xauthoring/app/templates/authoring/static/js/main.1e6f65c1.js +3 -0
- e2xauthoring/app/templates/authoring/static/js/main.1e6f65c1.js.map +1 -0
- e2xauthoring/managers/__init__.py +17 -0
- e2xauthoring/{models/assignmentmodel.py → managers/assignmentmanager.py} +7 -7
- e2xauthoring/{models/managers/manager.py → managers/base.py} +19 -1
- e2xauthoring/managers/dataclasses/__init__.py +49 -0
- e2xauthoring/{models/presetmodel.py → managers/presetmanager.py} +11 -5
- e2xauthoring/managers/taskmanager.py +167 -0
- e2xauthoring/managers/taskpoolmanager.py +66 -0
- e2xauthoring/managers/templatemanager.py +69 -0
- e2xauthoring/managers/worksheetmanager.py +50 -0
- e2xauthoring/preprocessors/addtaskheader.py +1 -1
- e2xauthoring/preprocessors/copyfiles.py +5 -4
- e2xauthoring/preprocessors/copynotebooks.py +6 -5
- e2xauthoring/preprocessors/filltemplate.py +2 -0
- e2xauthoring/preprocessors/makeexercise.py +9 -2
- {e2xauthoring-0.2.0.dev1.dist-info → e2xauthoring-0.2.0.dev2.dist-info}/METADATA +1 -1
- e2xauthoring-0.2.0.dev2.dist-info/RECORD +52 -0
- e2xauthoring/app/templates/authoring/static/js/main.fe9bcd55.js +0 -3
- e2xauthoring/app/templates/authoring/static/js/main.fe9bcd55.js.map +0 -1
- e2xauthoring/models/__init__.py +0 -15
- e2xauthoring/models/basemodel.py +0 -20
- e2xauthoring/models/dataclasses/__init__.py +0 -28
- e2xauthoring/models/dataclasses/message.py +0 -13
- e2xauthoring/models/dataclasses/template.py +0 -6
- e2xauthoring/models/exercisemodel.py +0 -44
- e2xauthoring/models/lister/lister.py +0 -27
- e2xauthoring/models/lister/taskpoollister.py +0 -33
- e2xauthoring/models/lister/templatelister.py +0 -17
- e2xauthoring/models/managers/taskmanager.py +0 -123
- e2xauthoring/models/managers/taskpoolmanager.py +0 -63
- e2xauthoring/models/managers/templatemanager.py +0 -50
- e2xauthoring/models/taskmodel.py +0 -186
- e2xauthoring/models/taskpoolmodel.py +0 -125
- e2xauthoring/models/templatemodel.py +0 -67
- e2xauthoring-0.2.0.dev1.dist-info/RECORD +0 -61
- /e2xauthoring/app/templates/authoring/static/js/{main.fe9bcd55.js.LICENSE.txt → main.1e6f65c1.js.LICENSE.txt} +0 -0
- /e2xauthoring/{models → managers}/presets/questions/Code (Autograded).ipynb +0 -0
- /e2xauthoring/{models → managers}/presets/questions/Code (Manual).ipynb +0 -0
- /e2xauthoring/{models → managers}/presets/questions/Diagram.ipynb +0 -0
- /e2xauthoring/{models → managers}/presets/questions/Freetext.ipynb +0 -0
- /e2xauthoring/{models → managers}/presets/questions/Multiple Choice.ipynb +0 -0
- /e2xauthoring/{models → managers}/presets/questions/Single Choice.ipynb +0 -0
- /e2xauthoring/{models → managers}/presets/questions/Upload Files.ipynb +0 -0
- /e2xauthoring/{models → managers}/presets/template/Footer.ipynb +0 -0
- /e2xauthoring/{models → managers}/presets/template/Group Info.ipynb +0 -0
- /e2xauthoring/{models → managers}/presets/template/Header.ipynb +0 -0
- /e2xauthoring/{models → managers}/presets/template/Student Info.ipynb +0 -0
- {e2xauthoring-0.2.0.dev1.dist-info → e2xauthoring-0.2.0.dev2.dist-info}/WHEEL +0 -0
- {e2xauthoring-0.2.0.dev1.dist-info → e2xauthoring-0.2.0.dev2.dist-info}/licenses/LICENSE +0 -0
e2xauthoring/__version__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.2.0-
|
|
1
|
+
__version__ = "0.2.0-dev2"
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import json
|
|
2
|
-
import os
|
|
3
2
|
|
|
4
3
|
from e2xcore.handlers import E2xApiHandler
|
|
5
4
|
from e2xcore.utils import urljoin
|
|
@@ -7,58 +6,16 @@ from jupyter_client.kernelspec import KernelSpecManager
|
|
|
7
6
|
from nbgrader.server_extensions.formgrader.base import check_xsrf
|
|
8
7
|
from tornado import web
|
|
9
8
|
|
|
10
|
-
from ...
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
TemplateModel,
|
|
9
|
+
from ...managers import (
|
|
10
|
+
AssignmentManager,
|
|
11
|
+
PresetManager,
|
|
12
|
+
TaskManager,
|
|
13
|
+
TaskPoolManager,
|
|
14
|
+
TemplateManager,
|
|
15
|
+
WorksheetManager,
|
|
18
16
|
)
|
|
19
|
-
from ...utils import NotebookVariableExtractor
|
|
20
17
|
from ...utils.gitutils import get_author, set_author
|
|
21
|
-
from .base import
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
class PresetHandler(E2xApiHandler):
|
|
25
|
-
def initialize(self):
|
|
26
|
-
self.__model = PresetModel(self.coursedir)
|
|
27
|
-
|
|
28
|
-
def _list_template(self):
|
|
29
|
-
self.write(json.dumps(self.__model.list_template_presets()))
|
|
30
|
-
|
|
31
|
-
def _get_template(self):
|
|
32
|
-
name = self.get_argument("name")
|
|
33
|
-
self.write(json.dumps(self.__model.get_template_preset(name)))
|
|
34
|
-
|
|
35
|
-
def _list_question(self):
|
|
36
|
-
self.write(json.dumps(self.__model.list_question_presets()))
|
|
37
|
-
|
|
38
|
-
def _get_question(self):
|
|
39
|
-
name = self.get_argument("name")
|
|
40
|
-
self.write(json.dumps(self.__model.get_question_preset(name)))
|
|
41
|
-
|
|
42
|
-
@web.authenticated
|
|
43
|
-
@check_xsrf
|
|
44
|
-
def get(self):
|
|
45
|
-
action = self.get_argument("action")
|
|
46
|
-
preset_type = self.get_argument("type")
|
|
47
|
-
handler = getattr(self, "_{}_{}".format(action, preset_type))
|
|
48
|
-
handler()
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
class TemplateVariableHandler(E2xApiHandler):
|
|
52
|
-
@web.authenticated
|
|
53
|
-
@check_xsrf
|
|
54
|
-
def get(self):
|
|
55
|
-
template = self.get_argument("template")
|
|
56
|
-
variables = NotebookVariableExtractor().extract(
|
|
57
|
-
os.path.join(
|
|
58
|
-
self.url_prefix, "templates", template, "{}.ipynb".format(template)
|
|
59
|
-
)
|
|
60
|
-
)
|
|
61
|
-
self.write(json.dumps(variables))
|
|
18
|
+
from .base import ApiManageHandler
|
|
62
19
|
|
|
63
20
|
|
|
64
21
|
class KernelSpecHandler(E2xApiHandler):
|
|
@@ -68,152 +25,6 @@ class KernelSpecHandler(E2xApiHandler):
|
|
|
68
25
|
self.write(json.dumps(KernelSpecManager().get_all_specs()))
|
|
69
26
|
|
|
70
27
|
|
|
71
|
-
class ManagePoolsHandler(E2xApiHandler):
|
|
72
|
-
def initialize(self) -> None:
|
|
73
|
-
self.__poolmodel = TaskPoolModel(self.coursedir)
|
|
74
|
-
|
|
75
|
-
@web.authenticated
|
|
76
|
-
@check_xsrf
|
|
77
|
-
def get(self, action):
|
|
78
|
-
if action == "list":
|
|
79
|
-
self.write(json.dumps(self.__poolmodel.list()))
|
|
80
|
-
elif action == "get":
|
|
81
|
-
self.write(json.dumps(self.__poolmodel.get(pool=self.get_argument("pool"))))
|
|
82
|
-
else:
|
|
83
|
-
self.write(
|
|
84
|
-
json.dumps(
|
|
85
|
-
dict(status="error", message=f"{action} is not a valid action")
|
|
86
|
-
)
|
|
87
|
-
)
|
|
88
|
-
|
|
89
|
-
@web.authenticated
|
|
90
|
-
@check_xsrf
|
|
91
|
-
def post(self, action):
|
|
92
|
-
data = self.get_json_body()
|
|
93
|
-
name = data.get("name")
|
|
94
|
-
if action == "new":
|
|
95
|
-
create_repository = data.get("create_repository", False)
|
|
96
|
-
self.write(
|
|
97
|
-
json.dumps(
|
|
98
|
-
self.__poolmodel.new(name=name, create_repository=create_repository)
|
|
99
|
-
)
|
|
100
|
-
)
|
|
101
|
-
elif action == "remove":
|
|
102
|
-
self.write(json.dumps(self.__poolmodel.remove(name=name)))
|
|
103
|
-
elif action == "init_repo":
|
|
104
|
-
self.write(json.dumps(self.__poolmodel.turn_into_repository(name)))
|
|
105
|
-
else:
|
|
106
|
-
self.write(
|
|
107
|
-
json.dumps(
|
|
108
|
-
dict(status="error", message=f"{action} is not a valid action")
|
|
109
|
-
)
|
|
110
|
-
)
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
class ManageTasksHandler(E2xApiHandler):
|
|
114
|
-
def initialize(self) -> None:
|
|
115
|
-
self.__model = TaskModel(self.coursedir)
|
|
116
|
-
|
|
117
|
-
@web.authenticated
|
|
118
|
-
@check_xsrf
|
|
119
|
-
def get(self, action):
|
|
120
|
-
if action == "list":
|
|
121
|
-
self.write(json.dumps(self.__model.list(pool=self.get_argument("pool"))))
|
|
122
|
-
elif action == "list_all":
|
|
123
|
-
tasks = []
|
|
124
|
-
pool_model = TaskPoolModel(self.coursedir)
|
|
125
|
-
for pool in pool_model.list():
|
|
126
|
-
tasks.extend(self.__model.list(pool["name"]))
|
|
127
|
-
self.write(json.dumps(tasks))
|
|
128
|
-
elif action == "get":
|
|
129
|
-
self.write(
|
|
130
|
-
json.dumps(
|
|
131
|
-
self.__model.get(
|
|
132
|
-
pool=self.get_argument("pool"), name=self.get_argument("name")
|
|
133
|
-
)
|
|
134
|
-
)
|
|
135
|
-
)
|
|
136
|
-
elif action == "diff":
|
|
137
|
-
self.write(
|
|
138
|
-
json.dumps(
|
|
139
|
-
self.__model.git_diff(
|
|
140
|
-
pool=self.get_argument("pool"),
|
|
141
|
-
task=self.get_argument("task"),
|
|
142
|
-
file=self.get_argument("file"),
|
|
143
|
-
)
|
|
144
|
-
)
|
|
145
|
-
)
|
|
146
|
-
else:
|
|
147
|
-
self.write(
|
|
148
|
-
json.dumps(
|
|
149
|
-
dict(status="error", message=f"{action} is not a valid action")
|
|
150
|
-
)
|
|
151
|
-
)
|
|
152
|
-
|
|
153
|
-
@web.authenticated
|
|
154
|
-
@check_xsrf
|
|
155
|
-
def post(self, action):
|
|
156
|
-
data = self.get_json_body()
|
|
157
|
-
name = data.get("name")
|
|
158
|
-
pool = data.get("pool")
|
|
159
|
-
if action == "new":
|
|
160
|
-
self.write(json.dumps(self.__model.new(pool=pool, name=name)))
|
|
161
|
-
elif action == "remove":
|
|
162
|
-
self.write(json.dumps(self.__model.remove(pool=pool, name=name)))
|
|
163
|
-
elif action == "commit":
|
|
164
|
-
message = data.get("message", None)
|
|
165
|
-
self.write(
|
|
166
|
-
json.dumps(self.__model.commit(pool=pool, task=name, message=message))
|
|
167
|
-
)
|
|
168
|
-
else:
|
|
169
|
-
self.write(
|
|
170
|
-
json.dumps(
|
|
171
|
-
dict(status="error", message=f"{action} is not a valid action")
|
|
172
|
-
)
|
|
173
|
-
)
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
class ManageTemplatesHandler(E2xApiHandler):
|
|
177
|
-
def initialize(self) -> None:
|
|
178
|
-
self.__model = TemplateModel(self.coursedir)
|
|
179
|
-
|
|
180
|
-
@web.authenticated
|
|
181
|
-
@check_xsrf
|
|
182
|
-
def get(self, action):
|
|
183
|
-
if action == "list":
|
|
184
|
-
self.write(json.dumps(self.__model.list()))
|
|
185
|
-
else:
|
|
186
|
-
self.write(
|
|
187
|
-
json.dumps(
|
|
188
|
-
dict(status="error", message=f"{action} is not a valid action")
|
|
189
|
-
)
|
|
190
|
-
)
|
|
191
|
-
|
|
192
|
-
@web.authenticated
|
|
193
|
-
@check_xsrf
|
|
194
|
-
def post(self, action):
|
|
195
|
-
data = self.get_json_body()
|
|
196
|
-
name = data.get("name")
|
|
197
|
-
if action == "new":
|
|
198
|
-
self.write(json.dumps(self.__model.new(name=name)))
|
|
199
|
-
elif action == "remove":
|
|
200
|
-
self.write(json.dumps(self.__model.remove(name=name)))
|
|
201
|
-
else:
|
|
202
|
-
self.write(
|
|
203
|
-
json.dumps(
|
|
204
|
-
dict(status="error", message=f"{action} is not a valid action")
|
|
205
|
-
)
|
|
206
|
-
)
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
class GenerateExerciseHandler(E2xApiHandler):
|
|
210
|
-
@web.authenticated
|
|
211
|
-
@check_xsrf
|
|
212
|
-
def post(self):
|
|
213
|
-
GenerateExercise(coursedir=self.coursedir).convert(self.get_json_body())
|
|
214
|
-
self.write(dict(success=True))
|
|
215
|
-
|
|
216
|
-
|
|
217
28
|
class GitAuthorHandler(E2xApiHandler):
|
|
218
29
|
@web.authenticated
|
|
219
30
|
@check_xsrf
|
|
@@ -232,41 +43,87 @@ class GitAuthorHandler(E2xApiHandler):
|
|
|
232
43
|
api_url = urljoin("e2x", "authoring", "api")
|
|
233
44
|
name_regex = r"(?P<name>[^/]+)"
|
|
234
45
|
assignment_regex = r"(?P<assignment>[^/]+)"
|
|
235
|
-
pool_action_regex = r"(?P<action>new|list|remove|get|init_repo)"
|
|
236
|
-
task_action_regex = r"(?P<action>new|list|list_all|remove|commit|get|diff)"
|
|
237
|
-
template_action_regex = r"(?P<action>new|list|remove)"
|
|
238
46
|
default_handlers = [
|
|
239
|
-
(urljoin(api_url, "presets"), PresetHandler),
|
|
240
47
|
(
|
|
241
48
|
urljoin(api_url, "assignments", "?"),
|
|
242
|
-
|
|
243
|
-
dict(
|
|
49
|
+
ApiManageHandler,
|
|
50
|
+
dict(
|
|
51
|
+
manager_cls=AssignmentManager,
|
|
52
|
+
actions=dict(
|
|
53
|
+
get=dict(actions=["list"]),
|
|
54
|
+
),
|
|
55
|
+
),
|
|
244
56
|
),
|
|
245
57
|
(
|
|
246
|
-
urljoin(api_url, "
|
|
247
|
-
|
|
248
|
-
dict(
|
|
58
|
+
urljoin(api_url, "worksheets", "?"),
|
|
59
|
+
ApiManageHandler,
|
|
60
|
+
dict(
|
|
61
|
+
manager_cls=WorksheetManager,
|
|
62
|
+
actions=dict(
|
|
63
|
+
get=dict(actions=["get", "list"]),
|
|
64
|
+
delete=dict(default="remove", actions=["remove"]),
|
|
65
|
+
post=dict(default="create", actions=["create"]),
|
|
66
|
+
),
|
|
67
|
+
),
|
|
68
|
+
),
|
|
69
|
+
(
|
|
70
|
+
urljoin(api_url, "tasks", "?"),
|
|
71
|
+
ApiManageHandler,
|
|
72
|
+
dict(
|
|
73
|
+
manager_cls=TaskManager,
|
|
74
|
+
actions=dict(
|
|
75
|
+
delete=dict(default="remove", actions=["remove"]),
|
|
76
|
+
get=dict(
|
|
77
|
+
default="get", actions=["get", "list", "list_all", "git_diff"]
|
|
78
|
+
),
|
|
79
|
+
post=dict(default="create", actions=["create"]),
|
|
80
|
+
put=dict(actions=["copy", "rename", "commit"]),
|
|
81
|
+
),
|
|
82
|
+
),
|
|
249
83
|
),
|
|
250
84
|
(
|
|
251
85
|
urljoin(api_url, "templates", "?"),
|
|
252
|
-
|
|
253
|
-
dict(
|
|
86
|
+
ApiManageHandler,
|
|
87
|
+
dict(
|
|
88
|
+
manager_cls=TemplateManager,
|
|
89
|
+
actions=dict(
|
|
90
|
+
delete=dict(default="remove", actions=["remove"]),
|
|
91
|
+
get=dict(default="get", actions=["get", "list", "list_variables"]),
|
|
92
|
+
post=dict(default="create", actions=["create"]),
|
|
93
|
+
put=dict(actions=["copy", "rename"]),
|
|
94
|
+
),
|
|
95
|
+
),
|
|
254
96
|
),
|
|
255
97
|
(
|
|
256
|
-
urljoin(api_url, "
|
|
257
|
-
|
|
258
|
-
dict(
|
|
98
|
+
urljoin(api_url, "pools", "?"),
|
|
99
|
+
ApiManageHandler,
|
|
100
|
+
dict(
|
|
101
|
+
manager_cls=TaskPoolManager,
|
|
102
|
+
actions=dict(
|
|
103
|
+
delete=dict(default="remove", actions=["remove"]),
|
|
104
|
+
get=dict(default="get", actions=["get", "list"]),
|
|
105
|
+
post=dict(default="create", actions=["create"]),
|
|
106
|
+
put=dict(actions=["copy", "rename", "turn_into_repository"]),
|
|
107
|
+
),
|
|
108
|
+
),
|
|
259
109
|
),
|
|
260
110
|
(
|
|
261
|
-
urljoin(api_url, "
|
|
262
|
-
|
|
263
|
-
dict(
|
|
111
|
+
urljoin(api_url, "presets", "?"),
|
|
112
|
+
ApiManageHandler,
|
|
113
|
+
dict(
|
|
114
|
+
manager_cls=PresetManager,
|
|
115
|
+
actions=dict(
|
|
116
|
+
get=dict(
|
|
117
|
+
actions=[
|
|
118
|
+
"list_question_presets",
|
|
119
|
+
"list_template_presets",
|
|
120
|
+
"get_question_preset",
|
|
121
|
+
"get_template_preset",
|
|
122
|
+
]
|
|
123
|
+
)
|
|
124
|
+
),
|
|
125
|
+
),
|
|
264
126
|
),
|
|
265
|
-
(urljoin(api_url, "pools", pool_action_regex, "?"), ManagePoolsHandler),
|
|
266
|
-
(urljoin(api_url, "tasks", task_action_regex, "?"), ManageTasksHandler),
|
|
267
|
-
(urljoin(api_url, "templates", template_action_regex, "?"), ManageTemplatesHandler),
|
|
268
|
-
(urljoin(api_url, "templates", "variables"), TemplateVariableHandler),
|
|
269
127
|
(urljoin(api_url, "kernelspec"), KernelSpecHandler),
|
|
270
|
-
(urljoin(api_url, "generate_worksheet"), GenerateExerciseHandler),
|
|
271
128
|
(urljoin(api_url, "git", "author"), GitAuthorHandler),
|
|
272
129
|
]
|
|
@@ -1,41 +1,102 @@
|
|
|
1
|
-
import
|
|
1
|
+
import inspect
|
|
2
|
+
from typing import List
|
|
2
3
|
|
|
3
4
|
from e2xcore.handlers import E2xApiHandler
|
|
4
5
|
from nbgrader.server_extensions.formgrader.base import check_xsrf
|
|
5
6
|
from tornado import web
|
|
6
7
|
|
|
8
|
+
from e2xauthoring.managers.dataclasses import ErrorMessage, SuccessMessage
|
|
7
9
|
|
|
8
|
-
class BaseApiManageHandler(E2xApiHandler):
|
|
9
|
-
def initialize(self, model_cls):
|
|
10
|
-
self.__model = model_cls(self.coursedir)
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
def status_msg(method):
|
|
12
|
+
"""Decorates a method of a BaseApiManager
|
|
13
|
+
Wraps the response in a status message (ErrorMessage or SuccessMessage)
|
|
14
|
+
and catches exceptions.
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
method: The method to decorate
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
def wrapper(*args, **kwargs):
|
|
21
|
+
try:
|
|
22
|
+
res = method(*args, **kwargs)
|
|
23
|
+
return SuccessMessage(data=res)
|
|
24
|
+
except Exception as e:
|
|
25
|
+
return ErrorMessage(error=getattr(e, "message", str(e)))
|
|
26
|
+
|
|
27
|
+
return wrapper
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class ApiManageHandler(E2xApiHandler):
|
|
31
|
+
def initialize(self, manager_cls, actions) -> None:
|
|
32
|
+
self.__manager = manager_cls(self.coursedir)
|
|
33
|
+
self.__allowed_actions = {
|
|
34
|
+
request_type: dict(default=None, actions=[])
|
|
35
|
+
for request_type in ["delete", "get", "post", "put"]
|
|
36
|
+
}
|
|
37
|
+
self.set_allowed_actions(actions)
|
|
38
|
+
|
|
39
|
+
def set_allowed_actions(self, allowed_actions):
|
|
40
|
+
for request_type, action_dict in self.__allowed_actions.items():
|
|
41
|
+
if request_type in allowed_actions:
|
|
42
|
+
actions = allowed_actions[request_type].get("actions", [])
|
|
43
|
+
for action in actions:
|
|
44
|
+
assert hasattr(
|
|
45
|
+
self.__manager, action
|
|
46
|
+
), f"The manager class does not provide an action called {action}."
|
|
47
|
+
action_dict["default"] = allowed_actions[request_type].get(
|
|
48
|
+
"default", None
|
|
49
|
+
)
|
|
50
|
+
action_dict["actions"].extend(actions)
|
|
51
|
+
|
|
52
|
+
def extract_arguments(self, method: str):
|
|
53
|
+
params = dict()
|
|
54
|
+
json_body = self.get_json_body() or dict()
|
|
55
|
+
for arg in inspect.signature(method).parameters.keys():
|
|
56
|
+
argument = self.get_argument(name=arg, default=None)
|
|
57
|
+
if argument is None:
|
|
58
|
+
argument = json_body.get(arg, None)
|
|
59
|
+
params[arg] = argument
|
|
60
|
+
return params
|
|
61
|
+
|
|
62
|
+
def perform_action(self, action: str, allowed_actions: List[str]):
|
|
63
|
+
assert (
|
|
64
|
+
action is not None and action in allowed_actions
|
|
65
|
+
), f"Action {action} is not a valid action."
|
|
66
|
+
method = getattr(self.__manager, action)
|
|
67
|
+
arguments = self.extract_arguments(method)
|
|
68
|
+
return method(**arguments)
|
|
69
|
+
|
|
70
|
+
@status_msg
|
|
71
|
+
def handle_request(self, request_type: str):
|
|
72
|
+
action = self.get_argument(
|
|
73
|
+
"action", default=None # self.__allowed_actions[request_type]["default"]
|
|
74
|
+
)
|
|
75
|
+
if action is None:
|
|
76
|
+
action = (self.get_json_body() or dict()).get(
|
|
77
|
+
"action", self.__allowed_actions[request_type]["default"]
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
return self.perform_action(
|
|
81
|
+
action, self.__allowed_actions[request_type]["actions"]
|
|
82
|
+
)
|
|
16
83
|
|
|
17
84
|
@web.authenticated
|
|
18
85
|
@check_xsrf
|
|
19
|
-
def
|
|
20
|
-
self.
|
|
21
|
-
self.write({"status": True})
|
|
86
|
+
def get(self):
|
|
87
|
+
self.finish(self.handle_request("get").json())
|
|
22
88
|
|
|
23
89
|
@web.authenticated
|
|
24
90
|
@check_xsrf
|
|
25
|
-
def
|
|
26
|
-
self.
|
|
91
|
+
def delete(self):
|
|
92
|
+
self.finish(self.handle_request("delete").json())
|
|
27
93
|
|
|
28
94
|
@web.authenticated
|
|
29
95
|
@check_xsrf
|
|
30
|
-
def put(self
|
|
31
|
-
self.
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
class BaseApiListHandler(E2xApiHandler):
|
|
35
|
-
def initialize(self, model_cls):
|
|
36
|
-
self.__model = model_cls(self.coursedir)
|
|
96
|
+
def put(self):
|
|
97
|
+
self.finish(self.handle_request("put").json())
|
|
37
98
|
|
|
38
99
|
@web.authenticated
|
|
39
100
|
@check_xsrf
|
|
40
|
-
def
|
|
41
|
-
self.
|
|
101
|
+
def post(self):
|
|
102
|
+
self.finish(self.handle_request("post").json())
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"files": {
|
|
3
|
-
"main.js": "/e2x/authoring/static/js/main.
|
|
3
|
+
"main.js": "/e2x/authoring/static/js/main.1e6f65c1.js",
|
|
4
4
|
"index.html": "/e2x/authoring/index.html",
|
|
5
|
-
"main.
|
|
5
|
+
"main.1e6f65c1.js.map": "/e2x/authoring/static/js/main.1e6f65c1.js.map"
|
|
6
6
|
},
|
|
7
7
|
"entrypoints": [
|
|
8
|
-
"static/js/main.
|
|
8
|
+
"static/js/main.1e6f65c1.js"
|
|
9
9
|
]
|
|
10
10
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>e²xgrader - Authoring</title><script type="text/javascript">window.base_url="{{ base_url }}",window.url_prefix="{{ url_prefix }}",window.webpackstuff="/e2x/authoring/static/js/main.
|
|
1
|
+
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>e²xgrader - Authoring</title><script type="text/javascript">window.base_url="{{ base_url }}",window.url_prefix="{{ url_prefix }}",window.webpackstuff="/e2x/authoring/static/js/main.1e6f65c1.js"</script><script defer="defer" src="{{base_url}}/e2x/authoring/static/js/main.1e6f65c1.js"></script>{%- block head -%} {%- endblock -%}</head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|