-
Notifications
You must be signed in to change notification settings - Fork 3.9k
/
Copy pathurls.py
349 lines (304 loc) · 17.2 KB
/
urls.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
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
"""
Urls of Studio.
"""
from django.conf import settings
from django.conf.urls.static import static
from django.contrib.admin import autodiscover as django_autodiscover
from django.urls import include
from django.urls import path, re_path
from django.utils.translation import gettext_lazy as _
from django.contrib import admin
from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView
from auth_backends.urls import oauth2_urlpatterns
from edx_api_doc_tools import make_docs_urls
import openedx.core.djangoapps.common_views.xblock
import openedx.core.djangoapps.debug.views
import openedx.core.djangoapps.lang_pref.views
from cms.djangoapps.contentstore import toggles
from cms.djangoapps.contentstore import views as contentstore_views
from cms.djangoapps.contentstore.views.organization import OrganizationListView
from openedx.core.apidocs import api_info
from openedx.core.djangoapps.password_policy import compliance as password_policy_compliance
from openedx.core.djangoapps.password_policy.forms import PasswordPolicyAwareAdminAuthForm
from openedx.core import toggles as core_toggles
django_autodiscover()
admin.site.site_header = _('Studio Administration')
admin.site.site_title = admin.site.site_header
if password_policy_compliance.should_enforce_compliance_on_login():
admin.site.login_form = PasswordPolicyAwareAdminAuthForm
# Custom error pages
# These are used by Django to render these error codes. Do not remove.
# pylint: disable=invalid-name
handler404 = contentstore_views.render_404
handler500 = contentstore_views.render_500
# Pattern to match a course key or a library key
COURSELIKE_KEY_PATTERN = r'(?P<course_key_string>({}|{}))'.format(
r'[^/]+/[^/]+/[^/]+', r'[^/:]+:[^/+]+\+[^/+]+(\+[^/]+)?'
)
# Pattern to match a library key only
LIBRARY_KEY_PATTERN = r'(?P<library_key_string>library-v1:[^/+]+\+[^/+]+)'
# oauth2_urlpatterns needs to be first to override any other login and
# logout related views.
urlpatterns = oauth2_urlpatterns + [
path('', include('openedx.core.djangoapps.user_authn.urls_common')),
path('', include('common.djangoapps.student.urls')),
path('transcripts/upload', contentstore_views.upload_transcripts, name='upload_transcripts'),
path('transcripts/download', contentstore_views.download_transcripts, name='download_transcripts'),
path('transcripts/check', contentstore_views.check_transcripts, name='check_transcripts'),
path('transcripts/choose', contentstore_views.choose_transcripts, name='choose_transcripts'),
path('transcripts/replace', contentstore_views.replace_transcripts, name='replace_transcripts'),
path('transcripts/rename', contentstore_views.rename_transcripts, name='rename_transcripts'),
re_path(r'^preview/xblock/(?P<usage_key_string>.*?)/handler/(?P<handler>[^/]*)(?:/(?P<suffix>.*))?$',
contentstore_views.preview_handler, name='preview_handler'),
re_path(r'^xblock/(?P<usage_key_string>.*?)/handler/(?P<handler>[^/]*)(?:/(?P<suffix>.*))?$',
contentstore_views.component_handler, name='component_handler'),
re_path(r'^xblock/resource/(?P<block_type>[^/]*)/(?P<uri>.*)$',
openedx.core.djangoapps.common_views.xblock.xblock_resource, name='xblock_resource_url'),
path('', include('openedx.core.djangoapps.xblock.rest_api.urls', namespace='xblock_api')),
path('not_found', contentstore_views.not_found, name='not_found'),
path('server_error', contentstore_views.server_error, name='server_error'),
path('organizations', OrganizationListView.as_view(), name='organizations'),
# noop to squelch ajax errors
path('event', contentstore_views.event, name='event'),
path('heartbeat', include('openedx.core.djangoapps.heartbeat.urls')),
path('i18n/', include('django.conf.urls.i18n')),
# User API endpoints
path('api/user/', include('openedx.core.djangoapps.user_api.urls')),
# Update session view
path('lang_pref/update_language', openedx.core.djangoapps.lang_pref.views.update_language,
name='update_language'
),
# Darklang View to change the preview language (or dark language)
path('update_lang/', include('openedx.core.djangoapps.dark_lang.urls', namespace='dark_lang')),
# For redirecting to help pages.
path('help_token/', include('help_tokens.urls')),
path('api/', include('cms.djangoapps.api.urls', namespace='api')),
# restful api
path('', contentstore_views.howitworks, name='homepage'),
path('howitworks', contentstore_views.howitworks, name='howitworks'),
path('signin_redirect_to_lms', contentstore_views.login_redirect_to_lms, name='login_redirect_to_lms'),
path('request_course_creator', contentstore_views.request_course_creator, name='request_course_creator'),
re_path(fr'^course_team/{COURSELIKE_KEY_PATTERN}(?:/(?P<email>.+))?$',
contentstore_views.course_team_handler, name='course_team_handler'),
re_path(fr'^course_info/{settings.COURSE_KEY_PATTERN}$', contentstore_views.course_info_handler,
name='course_info_handler'),
re_path(fr'^course_info_update/{settings.COURSE_KEY_PATTERN}/(?P<provided_id>\d+)?$',
contentstore_views.course_info_update_handler, name='course_info_update_handler'
),
re_path(r'^home/?$', contentstore_views.course_listing, name='home'),
re_path(r'^home_library/?$', contentstore_views.library_listing, name='home_library'),
re_path(fr'^course/{settings.COURSE_KEY_PATTERN}/search_reindex?$',
contentstore_views.course_search_index_handler,
name='course_search_index_handler'
),
re_path(fr'^course/{settings.COURSE_KEY_PATTERN}?$', contentstore_views.course_handler, name='course_handler'),
re_path(fr'^checklists/{settings.COURSE_KEY_PATTERN}?$',
contentstore_views.checklists_handler,
name='checklists_handler'),
re_path(fr'^course_notifications/{settings.COURSE_KEY_PATTERN}/(?P<action_state_id>\d+)?$',
contentstore_views.course_notifications_handler,
name='course_notifications_handler'),
re_path(fr'^course_rerun/{settings.COURSE_KEY_PATTERN}$', contentstore_views.course_rerun_handler,
name='course_rerun_handler'),
re_path(fr'^container/{settings.USAGE_KEY_PATTERN}$', contentstore_views.container_handler,
name='container_handler'),
re_path(fr'^orphan/{settings.COURSE_KEY_PATTERN}$', contentstore_views.orphan_handler,
name='orphan_handler'),
re_path(fr'^assets/{settings.COURSE_KEY_PATTERN}/{settings.ASSET_KEY_PATTERN}?$',
contentstore_views.assets_handler,
name='assets_handler'),
re_path(fr'^assets/{settings.COURSE_KEY_PATTERN}/{settings.ASSET_KEY_PATTERN}/usage',
contentstore_views.asset_usage_path_handler,
name='asset_usage_path_handler'),
re_path(fr'^import/{COURSELIKE_KEY_PATTERN}$', contentstore_views.import_handler,
name='import_handler'),
re_path(fr'^import_status/{COURSELIKE_KEY_PATTERN}/(?P<filename>.+)$',
contentstore_views.import_status_handler, name='import_status_handler'),
# rest api for course import/export
path('api/courses/', include('cms.djangoapps.contentstore.api.urls', namespace='courses_api')
),
re_path(fr'^export/{COURSELIKE_KEY_PATTERN}$', contentstore_views.export_handler,
name='export_handler'),
re_path(fr'^export_output/{COURSELIKE_KEY_PATTERN}$', contentstore_views.export_output_handler,
name='export_output_handler'),
re_path(fr'^export_status/{COURSELIKE_KEY_PATTERN}$', contentstore_views.export_status_handler,
name='export_status_handler'),
re_path(fr'^xblock/outline/{settings.USAGE_KEY_PATTERN}$', contentstore_views.xblock_outline_handler,
name='xblock_outline_handler'),
re_path(fr'^xblock/container/{settings.USAGE_KEY_PATTERN}$', contentstore_views.xblock_container_handler,
name='xblock_container_handler'),
re_path(fr'^xblock/{settings.USAGE_KEY_PATTERN}/(?P<view_name>[^/]+)$', contentstore_views.xblock_view_handler,
name='xblock_view_handler'),
re_path(fr'^xblock/{settings.USAGE_KEY_PATTERN}?$', contentstore_views.xblock_handler,
name='xblock_handler'),
re_path(fr'^tabs/{settings.COURSE_KEY_PATTERN}$', contentstore_views.tabs_handler,
name='tabs_handler'),
re_path(fr'^settings/details/{settings.COURSE_KEY_PATTERN}$', contentstore_views.settings_handler,
name='settings_handler'),
re_path(fr'^settings/grading/{settings.COURSE_KEY_PATTERN}(/)?(?P<grader_index>\d+)?$',
contentstore_views.grading_handler, name='grading_handler'),
re_path(fr'^settings/advanced/{settings.COURSE_KEY_PATTERN}$', contentstore_views.advanced_settings_handler,
name='advanced_settings_handler'),
re_path(fr'^textbooks/{settings.COURSE_KEY_PATTERN}$', contentstore_views.textbooks_list_handler,
name='textbooks_list_handler'),
re_path(fr'^textbooks/{settings.COURSE_KEY_PATTERN}/(?P<textbook_id>\d[^/]*)$',
contentstore_views.textbooks_detail_handler, name='textbooks_detail_handler'),
re_path(fr'^videos/{settings.COURSE_KEY_PATTERN}(?:/(?P<edx_video_id>[-\w]+))?$',
contentstore_views.videos_handler, name='videos_handler'),
re_path(fr'^generate_video_upload_link/{settings.COURSE_KEY_PATTERN}',
contentstore_views.generate_video_upload_link_handler, name='generate_video_upload_link'),
re_path(fr'^video_images/{settings.COURSE_KEY_PATTERN}(?:/(?P<edx_video_id>[-\w]+))?$',
contentstore_views.video_images_handler, name='video_images_handler'),
path('video_images_upload_enabled', contentstore_views.video_images_upload_enabled,
name='video_images_upload_enabled'),
path('video_features/', contentstore_views.get_video_features, name='video_features'),
re_path(fr'^transcript_preferences/{settings.COURSE_KEY_PATTERN}$',
contentstore_views.transcript_preferences_handler, name='transcript_preferences_handler'),
re_path(fr'^transcript_credentials/{settings.COURSE_KEY_PATTERN}$',
contentstore_views.transcript_credentials_handler, name='transcript_credentials_handler'),
path('transcript_download/', contentstore_views.transcript_download_handler, name='transcript_download_handler'),
path('transcript_upload/', contentstore_views.transcript_upload_handler, name='transcript_upload_handler'),
re_path(r'^transcript_delete/{}(?:/(?P<edx_video_id>[-\w]+))?(?:/(?P<language_code>[^/]*))?$'.format(
settings.COURSE_KEY_PATTERN
), contentstore_views.transcript_delete_handler, name='transcript_delete_handler'),
path('transcript_upload_api/', contentstore_views.transcript_upload_api, name='transcript_upload_api'),
re_path(fr'^video_encodings_download/{settings.COURSE_KEY_PATTERN}$',
contentstore_views.video_encodings_download, name='video_encodings_download'),
re_path(fr'^group_configurations/{settings.COURSE_KEY_PATTERN}$',
contentstore_views.group_configurations_list_handler,
name='group_configurations_list_handler'),
re_path(r'^group_configurations/{}/(?P<group_configuration_id>\d+)(/)?(?P<group_id>\d+)?$'.format(
settings.COURSE_KEY_PATTERN), contentstore_views.group_configurations_detail_handler,
name='group_configurations_detail_handler'),
path('api/val/v0/', include('edxval.urls')),
path('api/tasks/v0/', include('user_tasks.urls')),
path('accessibility', contentstore_views.accessibility, name='accessibility'),
]
if not settings.DISABLE_DEPRECATED_SIGNIN_URL:
# TODO: Remove deprecated signin url when traffic proves it is no longer in use
urlpatterns += [
path('signin', contentstore_views.login_redirect_to_lms),
]
if not settings.DISABLE_DEPRECATED_SIGNUP_URL:
# TODO: Remove deprecated signup url when traffic proves it is no longer in use
urlpatterns += [
path('signup', contentstore_views.register_redirect_to_lms, name='register_redirect_to_lms'),
]
JS_INFO_DICT = {
'domain': 'djangojs',
# We need to explicitly include external Django apps that are not in LOCALE_PATHS.
'packages': ('openassessment',),
}
urlpatterns += [
path('openassessment/fileupload/', include('openassessment.fileupload.urls')),
]
if settings.FEATURES.get('ENABLE_CONTENT_LIBRARIES'):
urlpatterns += [
re_path(fr'^library/{LIBRARY_KEY_PATTERN}?$',
contentstore_views.library_handler, name='library_handler'),
re_path(fr'^library/{LIBRARY_KEY_PATTERN}/team/$',
contentstore_views.manage_library_users, name='manage_library_users'),
]
if toggles.EXPORT_GIT.is_enabled():
urlpatterns += [
re_path(fr'^export_git/{settings.COURSE_KEY_PATTERN}$',
contentstore_views.export_git,
name='export_git')
]
if settings.FEATURES.get('ENABLE_SERVICE_STATUS'):
urlpatterns.append(path('status/', include('openedx.core.djangoapps.service_status.urls')))
# The password pages in the admin tool are disabled so that all password
# changes go through our user portal and follow complexity requirements.
if not settings.FEATURES.get('ENABLE_CHANGE_USER_PASSWORD_ADMIN'):
urlpatterns.append(re_path(r'^admin/auth/user/\d+/password/$', handler404))
urlpatterns.append(path('admin/password_change/', handler404))
urlpatterns.append(
path('admin/login/', contentstore_views.redirect_to_lms_login_for_admin, name='redirect_to_lms_login_for_admin')
)
urlpatterns.append(path('admin/', admin.site.urls))
# enable entrance exams
if core_toggles.ENTRANCE_EXAMS.is_enabled():
urlpatterns.append(re_path(fr'^course/{settings.COURSE_KEY_PATTERN}/entrance_exam/?$',
contentstore_views.entrance_exam))
# Enable Web/HTML Certificates
if settings.FEATURES.get('CERTIFICATES_HTML_VIEW'):
from cms.djangoapps.contentstore.views.certificates import (
certificate_activation_handler,
signatory_detail_handler,
certificates_detail_handler,
certificates_list_handler
)
urlpatterns += [
re_path(fr'^certificates/activation/{settings.COURSE_KEY_PATTERN}/',
certificate_activation_handler,
name='certificate_activation_handler'),
re_path(r'^certificates/{}/(?P<certificate_id>\d+)/signatories/(?P<signatory_id>\d+)?$'.format(
settings.COURSE_KEY_PATTERN), signatory_detail_handler, name='signatory_detail_handler'),
re_path(fr'^certificates/{settings.COURSE_KEY_PATTERN}/(?P<certificate_id>\d+)?$',
certificates_detail_handler, name='certificates_detail_handler'),
re_path(fr'^certificates/{settings.COURSE_KEY_PATTERN}$',
certificates_list_handler, name='certificates_list_handler')
]
# Maintenance Dashboard
urlpatterns.append(path('maintenance/', include('cms.djangoapps.maintenance.urls', namespace='maintenance')))
if settings.DEBUG:
try:
from .urls_dev import urlpatterns as dev_urlpatterns
urlpatterns += dev_urlpatterns
except ImportError:
pass
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += static(
settings.VIDEO_IMAGE_SETTINGS['BASE_URL'],
document_root=settings.VIDEO_IMAGE_SETTINGS['STORAGE_KWARGS']['location']
)
urlpatterns += static(
settings.VIDEO_TRANSCRIPTS_SETTINGS['BASE_URL'],
document_root=settings.VIDEO_TRANSCRIPTS_SETTINGS['STORAGE_KWARGS']['location']
)
if 'debug_toolbar' in settings.INSTALLED_APPS:
import debug_toolbar
urlpatterns.append(path('__debug__/', include(debug_toolbar.urls)))
# UX reference templates
urlpatterns.append(path('template/<path:template>', openedx.core.djangoapps.debug.views.show_reference_template,
name='openedx.core.djangoapps.debug.views.show_reference_template'))
urlpatterns.append(
path('api/learning_sequences/', include(
('openedx.core.djangoapps.content.learning_sequences.urls', 'learning_sequences'),
namespace='learning_sequences'
),
),
)
# display error page templates, for testing purposes
urlpatterns += [
path('404', handler404),
path('500', handler500),
]
# API docs.
urlpatterns += make_docs_urls(api_info)
# edx-drf-extensions csrf app
urlpatterns += [
path('', include('csrf.urls')),
]
if 'openedx.testing.coverage_context_listener' in settings.INSTALLED_APPS:
urlpatterns += [
path('coverage_context', include('openedx.testing.coverage_context_listener.urls'))
]
# pylint: disable=wrong-import-position, wrong-import-order
from edx_django_utils.plugins import get_plugin_url_patterns # isort:skip
# pylint: disable=wrong-import-position
from openedx.core.djangoapps.plugins.constants import ProjectType # isort:skip
urlpatterns.extend(get_plugin_url_patterns(ProjectType.CMS))
# Contentstore REST APIs
urlpatterns += [
path('api/contentstore/', include('cms.djangoapps.contentstore.rest_api.urls'))
]
# Content tagging
urlpatterns += [
path('api/content_tagging/', include(('openedx.core.djangoapps.content_tagging.urls'))),
]
# studio-content-api specific API docs (using drf-spectacular and openapi-v3)
urlpatterns += [
re_path('^cms-api/ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'),
re_path('^cms-api/schema/', SpectacularAPIView.as_view(), name='schema'),
]