From 9d9c199d48c5845af320ee5167dca82dd9658487 Mon Sep 17 00:00:00 2001 From: bmedx Date: Fri, 3 Nov 2017 14:39:52 -0400 Subject: [PATCH] LMS urls cleanup for Django 1.11 - Remove usage of django.urls.patterns - Change urls tuples to lists - Make all string view names callables - This is the first of several urls updates for LMS; a work in progress --- lms/djangoapps/certificates/queue.py | 2 +- .../certificates/tests/test_views.py | 2 +- .../certificates/tests/test_webview_views.py | 4 +- lms/urls.py | 482 +++++++++--------- 4 files changed, 255 insertions(+), 235 deletions(-) diff --git a/lms/djangoapps/certificates/queue.py b/lms/djangoapps/certificates/queue.py index 5dbc394713..f40e8d13c4 100644 --- a/lms/djangoapps/certificates/queue.py +++ b/lms/djangoapps/certificates/queue.py @@ -510,7 +510,7 @@ class XQueueCertInterface(object): # for other certificates. Although both tasks use the same queue, # we can distinguish whether the certificate was an example cert based # on which end-point XQueue uses once the task completes. - callback_url_path = reverse('certificates.views.update_example_certificate') + callback_url_path = reverse('update_example_certificate') try: self._send_to_xqueue( diff --git a/lms/djangoapps/certificates/tests/test_views.py b/lms/djangoapps/certificates/tests/test_views.py index 7ccbf9f367..b99e3c8444 100644 --- a/lms/djangoapps/certificates/tests/test_views.py +++ b/lms/djangoapps/certificates/tests/test_views.py @@ -59,7 +59,7 @@ class UpdateExampleCertificateViewTest(CacheIsolationTestCase): description=self.DESCRIPTION, template=self.TEMPLATE, ) - self.url = reverse('certificates.views.update_example_certificate') + self.url = reverse('update_example_certificate') # Since rate limit counts are cached, we need to clear # this before each test. diff --git a/lms/djangoapps/certificates/tests/test_webview_views.py b/lms/djangoapps/certificates/tests/test_webview_views.py index 59fdd905ae..ba6795a283 100644 --- a/lms/djangoapps/certificates/tests/test_webview_views.py +++ b/lms/djangoapps/certificates/tests/test_webview_views.py @@ -935,7 +935,7 @@ class CertificatesViewsTests(CommonCertificatesTestCase): def test_request_certificate_without_passing(self): self.cert.status = CertificateStatuses.unavailable self.cert.save() - request_certificate_url = reverse('certificates.views.request_certificate') + request_certificate_url = reverse('request_certificate') response = self.client.post(request_certificate_url, {'course_id': unicode(self.course.id)}) self.assertEqual(response.status_code, 200) response_json = json.loads(response.content) @@ -946,7 +946,7 @@ class CertificatesViewsTests(CommonCertificatesTestCase): def test_request_certificate_after_passing(self): self.cert.status = CertificateStatuses.unavailable self.cert.save() - request_certificate_url = reverse('certificates.views.request_certificate') + request_certificate_url = reverse('request_certificate') with patch('capa.xqueue_interface.XQueueInterface.send_to_queue') as mock_queue: mock_queue.return_value = (0, "Successfully queued") with mock_passing_grade(): diff --git a/lms/urls.py b/lms/urls.py index c37d39bb18..1c44ecabfc 100644 --- a/lms/urls.py +++ b/lms/urls.py @@ -2,25 +2,52 @@ URLs for LMS """ -from config_models.views import ConfigurationModelCurrentAPIView from django.conf import settings -from django.conf.urls import include, patterns, url +from django.conf.urls import include, url from django.conf.urls.static import static from django.contrib.admin import autodiscover as django_autodiscover from django.utils.translation import ugettext_lazy as _ from django.views.generic.base import RedirectView -from ratelimitbackend import admin +from branding import views as branding_views +from certificates import views as certificates_views +from config_models.views import ConfigurationModelCurrentAPIView +from courseware.masquerade import handle_ajax as courseware_masquerade_handle_ajax +from courseware.module_render import handle_xblock_callback, handle_xblock_callback_noauth, xblock_view, xqueue_callback +from courseware.views import views as courseware_views from courseware.views.index import CoursewareIndex from courseware.views.views import CourseTabView, EnrollStaffView, StaticCourseTabView +from debug import views as debug_views +from django_cas import views as django_cas_views from django_comment_common.models import ForumsConfig +from django_openid_auth import views as django_openid_auth_views +from lms.djangoapps.discussion import views as discussion_views +from lms.djangoapps.instructor.views import coupons as instructor_coupons_views +from lms.djangoapps.instructor.views import instructor_dashboard as instructor_dashboard_views +from lms.djangoapps.instructor.views import registration_codes as instructor_registration_codes_views +from lms.djangoapps.instructor_task import views as instructor_task_views +from lms_migration import migrate as lms_migrate_views +from notes import views as notes_views +from notification_prefs import views as notification_prefs_views from openedx.core.djangoapps.auth_exchange.views import LoginWithAccessTokenView from openedx.core.djangoapps.catalog.models import CatalogIntegration +from openedx.core.djangoapps.cors_csrf import views as cors_csrf_views +from openedx.core.djangoapps.course_groups import views as course_groups_views +from openedx.core.djangoapps.debug import views as openedx_debug_views +from openedx.core.djangoapps.external_auth import views as external_auth_views +from openedx.core.djangoapps.lang_pref import views as lang_pref_views from openedx.core.djangoapps.programs.models import ProgramsApiConfig from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers +from openedx.core.djangoapps.verified_track_content import views as verified_track_content_views from openedx.features.enterprise_support.api import enterprise_enabled - +from ratelimitbackend import admin +from static_template_view import views as static_template_view_views +from staticbook import views as staticbook_views +from student import views as student_views +from student_account import views as student_account_views +from track import views as track_views +from util import views as util_views if settings.DEBUG or settings.FEATURES.get('ENABLE_DJANGO_ADMIN_SITE'): django_autodiscover() @@ -28,16 +55,13 @@ if settings.DEBUG or settings.FEATURES.get('ENABLE_DJANGO_ADMIN_SITE'): admin.site.site_title = admin.site.site_header -# Use urlpatterns formatted as within the Django docs with first parameter "stuck" to the open parenthesis -urlpatterns = ( - '', - - url(r'^$', 'branding.views.index', name="root"), # Main marketing page, or redirect to courseware +urlpatterns = [ + url(r'^$', branding_views.index, name='root'), # Main marketing page, or redirect to courseware url(r'', include('student.urls')), # TODO: Move lms specific student views out of common code - url(r'^dashboard$', 'student.views.dashboard', name="dashboard"), - url(r'^change_enrollment$', 'student.views.change_enrollment', name='change_enrollment'), + url(r'^dashboard$', student_views.dashboard, name='dashboard'), + url(r'^change_enrollment$', student_views.change_enrollment, name='change_enrollment'), # Event tracking endpoints url(r'', include('track.urls')), @@ -59,7 +83,7 @@ urlpatterns = ( url(r'^i18n/', include('django.conf.urls.i18n')), # Feedback Form endpoint - url(r'^submit_feedback$', 'util.views.submit_feedback'), + url(r'^submit_feedback$', util_views.submit_feedback), # Enrollment API RESTful endpoints url(r'^api/enrollment/v1/', include('enrollment.urls')), @@ -87,21 +111,16 @@ urlpatterns = ( url(r'^api/val/v0/', include('edxval.urls')), url(r'^api/commerce/', include('commerce.api.urls', namespace='commerce_api')), - url(r'^api/credit/', include('openedx.core.djangoapps.credit.urls', app_name="credit", namespace='credit')), + url(r'^api/credit/', include('openedx.core.djangoapps.credit.urls', app_name='credit', namespace='credit')), url(r'^rss_proxy/', include('rss_proxy.urls', namespace='rss_proxy')), url(r'^api/organizations/', include('organizations.urls', namespace='organizations')), url(r'^catalog/', include('openedx.core.djangoapps.catalog.urls', namespace='catalog')), # Update session view - url( - r'^lang_pref/session_language', - 'openedx.core.djangoapps.lang_pref.views.update_session_language', - name='session_language' - ), + url(r'^lang_pref/session_language', lang_pref_views.update_session_language, name='session_language'), # Multiple course modes and identity verification - # TODO Namespace these! url(r'^course_modes/', include('course_modes.urls')), url(r'^verify_student/', include('verify_student.urls')), @@ -119,34 +138,34 @@ urlpatterns = ( url(r'^dashboard/', include('learner_dashboard.urls')), url(r'^api/experiments/', include('experiments.urls', namespace='api_experiments')), -) +] # TODO: This needs to move to a separate urls.py once the student_account and # student views below find a home together -if settings.FEATURES["ENABLE_COMBINED_LOGIN_REGISTRATION"]: +if settings.FEATURES['ENABLE_COMBINED_LOGIN_REGISTRATION']: # Backwards compatibility with old URL structure, but serve the new views - urlpatterns += ( - url(r'^login$', 'student_account.views.login_and_registration_form', - {'initial_mode': 'login'}, name="signin_user"), - url(r'^register$', 'student_account.views.login_and_registration_form', - {'initial_mode': 'register'}, name="register_user"), - ) + urlpatterns += [ + url(r'^login$', student_account_views.login_and_registration_form, + {'initial_mode': 'login'}, name='signin_user'), + url(r'^register$', student_account_views.login_and_registration_form, + {'initial_mode': 'register'}, name='register_user'), + ] else: # Serve the old views - urlpatterns += ( - url(r'^login$', 'student.views.signin_user', name="signin_user"), - url(r'^register$', 'student.views.register_user', name="register_user"), - ) + urlpatterns += [ + url(r'^login$', student_views.signin_user, name='signin_user'), + url(r'^register$', student_views.register_user, name='register_user'), + ] -if settings.FEATURES["ENABLE_MOBILE_REST_API"]: - urlpatterns += ( +if settings.FEATURES['ENABLE_MOBILE_REST_API']: + urlpatterns += [ url(r'^api/mobile/v0.5/', include('mobile_api.urls')), - ) + ] -if settings.FEATURES["ENABLE_OPENBADGES"]: - urlpatterns += ( - url(r'^api/badges/v1/', include('badges.api.urls', app_name="badges", namespace="badges_api")), - ) +if settings.FEATURES['ENABLE_OPENBADGES']: + urlpatterns += [ + url(r'^api/badges/v1/', include('badges.api.urls', app_name='badges', namespace='badges_api')), + ] js_info_dict = { 'domain': 'djangojs', @@ -154,75 +173,74 @@ js_info_dict = { 'packages': ('openassessment',), } -urlpatterns += ( +urlpatterns += [ url(r'^openassessment/fileupload/', include('openassessment.fileupload.urls')), -) +] # sysadmin dashboard, to see what courses are loaded, to delete & load courses -if settings.FEATURES["ENABLE_SYSADMIN_DASHBOARD"]: - urlpatterns += ( +if settings.FEATURES['ENABLE_SYSADMIN_DASHBOARD']: + urlpatterns += [ url(r'^sysadmin/', include('dashboard.sysadmin_urls')), - ) + ] -urlpatterns += ( - url(r'^support/', include('support.urls', app_name="support", namespace='support')), -) +urlpatterns += [ + url(r'^support/', include('support.urls', app_name='support', namespace='support')), +] # Favicon favicon_path = configuration_helpers.get_value('favicon_path', settings.FAVICON_PATH) # pylint: disable=invalid-name -urlpatterns += (url( - r'^favicon\.ico$', - RedirectView.as_view(url=settings.STATIC_URL + favicon_path, permanent=True) -),) +urlpatterns += [ + url(r'^favicon\.ico$', RedirectView.as_view(url=settings.STATIC_URL + favicon_path, permanent=True)), +] # Multicourse wiki (Note: wiki urls must be above the courseware ones because of # the custom tab catch-all) if settings.WIKI_ENABLED: from wiki.urls import get_pattern as wiki_pattern + from course_wiki import views as course_wiki_views from django_notify.urls import get_pattern as notify_pattern - urlpatterns += ( + urlpatterns += [ # First we include views from course_wiki that we use to override the default views. # They come first in the urlpatterns so they get resolved first - url('^wiki/create-root/$', 'course_wiki.views.root_create', name='root_create'), + url('^wiki/create-root/$', course_wiki_views.root_create, name='root_create'), url(r'^wiki/', include(wiki_pattern())), url(r'^notify/', include(notify_pattern())), # These urls are for viewing the wiki in the context of a course. They should # never be returned by a reverse() so they come after the other url patterns url(r'^courses/{}/course_wiki/?$'.format(settings.COURSE_ID_PATTERN), - 'course_wiki.views.course_wiki_redirect', name="course_wiki"), + course_wiki_views.course_wiki_redirect, name='course_wiki'), url(r'^courses/{}/wiki/'.format(settings.COURSE_KEY_REGEX), include(wiki_pattern())), - ) + ] -COURSE_URLS = patterns( - '', +COURSE_URLS = [ url( r'^look_up_registration_code$', - 'lms.djangoapps.instructor.views.registration_codes.look_up_registration_code', + instructor_registration_codes_views.look_up_registration_code, name='look_up_registration_code', ), url( r'^registration_code_details$', - 'lms.djangoapps.instructor.views.registration_codes.registration_code_details', + instructor_registration_codes_views.registration_code_details, name='registration_code_details', ), -) -urlpatterns += ( +] +urlpatterns += [ # jump_to URLs for direct access to a location in the course url( r'^courses/{}/jump_to/(?P.*)$'.format( settings.COURSE_ID_PATTERN, ), - 'courseware.views.views.jump_to', + courseware_views.jump_to, name='jump_to', ), url( r'^courses/{}/jump_to_id/(?P.*)$'.format( settings.COURSE_ID_PATTERN, ), - 'courseware.views.views.jump_to_id', + courseware_views.jump_to_id, name='jump_to_id', ), @@ -232,7 +250,7 @@ urlpatterns += ( course_key=settings.COURSE_ID_PATTERN, usage_key=settings.USAGE_ID_PATTERN, ), - 'courseware.module_render.handle_xblock_callback', + handle_xblock_callback, name='xblock_handler', ), url( @@ -240,7 +258,7 @@ urlpatterns += ( course_key=settings.COURSE_ID_PATTERN, usage_key=settings.USAGE_ID_PATTERN, ), - 'courseware.module_render.handle_xblock_callback_noauth', + handle_xblock_callback_noauth, name='xblock_handler_noauth', ), @@ -252,17 +270,17 @@ urlpatterns += ( course_key=settings.COURSE_ID_PATTERN, usage_key=settings.USAGE_ID_PATTERN, ), - 'courseware.module_render.xblock_view', + xblock_view, name='xblock_view', ), # xblock Rendering View URL # URL to provide an HTML view of an xBlock. The view type (e.g., student_view) is - # passed as a "view" parameter to the URL. + # passed as a 'view' parameter to the URL. # Note: This is not an API. Compare this with the xblock_view API above. url( r'^xblock/{usage_key_string}$'.format(usage_key_string=settings.USAGE_KEY_PATTERN), - 'courseware.views.views.render_xblock', + courseware_views.render_xblock, name='render_xblock', ), @@ -277,21 +295,21 @@ urlpatterns += ( r'^courses/{}/xqueue/(?P[^/]*)/(?P.*?)/(?P[^/]*)$'.format( settings.COURSE_ID_PATTERN, ), - 'courseware.module_render.xqueue_callback', + xqueue_callback, name='xqueue_callback', ), # TODO: These views need to be updated before they work - url(r'^calculate$', 'util.views.calculate'), + url(r'^calculate$', util_views.calculate), - url(r'^courses/?$', 'branding.views.courses', name="courses"), + url(r'^courses/?$', branding_views.courses, name='courses'), #About the course url( r'^courses/{}/about$'.format( settings.COURSE_ID_PATTERN, ), - 'courseware.views.views.course_about', + courseware_views.course_about, name='about_course', ), @@ -308,14 +326,14 @@ urlpatterns += ( r'^courses/{}/$'.format( settings.COURSE_ID_PATTERN, ), - 'courseware.views.views.course_info', + courseware_views.course_info, name='course_root', ), url( r'^courses/{}/info$'.format( settings.COURSE_ID_PATTERN, ), - 'courseware.views.views.course_info', + courseware_views.course_info, name='info', ), # TODO arjun remove when custom tabs in place, see courseware/courses.py @@ -323,7 +341,7 @@ urlpatterns += ( r'^courses/{}/syllabus$'.format( settings.COURSE_ID_PATTERN, ), - 'courseware.views.views.syllabus', + courseware_views.syllabus, name='syllabus', ), @@ -332,7 +350,7 @@ urlpatterns += ( r'^courses/{}/survey$'.format( settings.COURSE_ID_PATTERN, ), - 'courseware.views.views.course_survey', + courseware_views.course_survey, name='course_survey', ), @@ -340,14 +358,14 @@ urlpatterns += ( r'^courses/{}/book/(?P\d+)/$'.format( settings.COURSE_ID_PATTERN, ), - 'staticbook.views.index', + staticbook_views.index, name='book', ), url( r'^courses/{}/book/(?P\d+)/(?P\d+)$'.format( settings.COURSE_ID_PATTERN, ), - 'staticbook.views.index', + staticbook_views.index, name='book', ), @@ -355,14 +373,14 @@ urlpatterns += ( r'^courses/{}/pdfbook/(?P\d+)/$'.format( settings.COURSE_ID_PATTERN, ), - 'staticbook.views.pdf_index', + staticbook_views.pdf_index, name='pdf_book', ), url( r'^courses/{}/pdfbook/(?P\d+)/(?P\d+)$'.format( settings.COURSE_ID_PATTERN, ), - 'staticbook.views.pdf_index', + staticbook_views.pdf_index, name='pdf_book', ), @@ -370,14 +388,14 @@ urlpatterns += ( r'^courses/{}/pdfbook/(?P\d+)/chapter/(?P\d+)/$'.format( settings.COURSE_ID_PATTERN, ), - 'staticbook.views.pdf_index', + staticbook_views.pdf_index, name='pdf_book', ), url( r'^courses/{}/pdfbook/(?P\d+)/chapter/(?P\d+)/(?P\d+)$'.format( settings.COURSE_ID_PATTERN, ), - 'staticbook.views.pdf_index', + staticbook_views.pdf_index, name='pdf_book', ), @@ -385,14 +403,14 @@ urlpatterns += ( r'^courses/{}/htmlbook/(?P\d+)/$'.format( settings.COURSE_ID_PATTERN, ), - 'staticbook.views.html_index', + staticbook_views.html_index, name='html_book', ), url( r'^courses/{}/htmlbook/(?P\d+)/chapter/(?P\d+)/$'.format( settings.COURSE_ID_PATTERN, ), - 'staticbook.views.html_index', + staticbook_views.html_index, name='html_book', ), @@ -430,7 +448,7 @@ urlpatterns += ( r'^courses/{}/progress$'.format( settings.COURSE_ID_PATTERN, ), - 'courseware.views.views.progress', + courseware_views.progress, name='progress', ), @@ -439,7 +457,7 @@ urlpatterns += ( r'^courses/{}/progress/(?P[^/]*)/$'.format( settings.COURSE_ID_PATTERN, ), - 'courseware.views.views.progress', + courseware_views.progress, name='student_progress', ), @@ -447,7 +465,7 @@ urlpatterns += ( r'^programs/{}/about'.format( r'(?P[0-9a-f-]+)', ), - 'courseware.views.views.program_marketing', + courseware_views.program_marketing, name='program_marketing_view', ), @@ -463,7 +481,7 @@ urlpatterns += ( r'^courses/{}/instructor$'.format( settings.COURSE_ID_PATTERN, ), - 'lms.djangoapps.instructor.views.instructor_dashboard.instructor_dashboard_2', + instructor_dashboard_views.instructor_dashboard_2, name='instructor_dashboard', ), @@ -472,7 +490,7 @@ urlpatterns += ( r'^courses/{}/set_course_mode_price$'.format( settings.COURSE_ID_PATTERN, ), - 'lms.djangoapps.instructor.views.instructor_dashboard.set_course_mode_price', + instructor_dashboard_views.set_course_mode_price, name='set_course_mode_price', ), url( @@ -484,28 +502,28 @@ urlpatterns += ( r'^courses/{}/remove_coupon$'.format( settings.COURSE_ID_PATTERN, ), - 'lms.djangoapps.instructor.views.coupons.remove_coupon', + instructor_coupons_views.remove_coupon, name='remove_coupon', ), url( r'^courses/{}/add_coupon$'.format( settings.COURSE_ID_PATTERN, ), - 'lms.djangoapps.instructor.views.coupons.add_coupon', + instructor_coupons_views.add_coupon, name='add_coupon', ), url( r'^courses/{}/update_coupon$'.format( settings.COURSE_ID_PATTERN, ), - 'lms.djangoapps.instructor.views.coupons.update_coupon', + instructor_coupons_views.update_coupon, name='update_coupon', ), url( r'^courses/{}/get_coupon_info$'.format( settings.COURSE_ID_PATTERN, ), - 'lms.djangoapps.instructor.views.coupons.get_coupon_info', + instructor_coupons_views.get_coupon_info, name='get_coupon_info', ), @@ -521,7 +539,7 @@ urlpatterns += ( r'^courses/{}/discussions/settings$'.format( settings.COURSE_KEY_PATTERN, ), - 'lms.djangoapps.discussion.views.course_discussions_settings_handler', + discussion_views.course_discussions_settings_handler, name='course_discussions_settings', ), @@ -530,63 +548,63 @@ urlpatterns += ( r'^courses/{}/cohorts/settings$'.format( settings.COURSE_KEY_PATTERN, ), - 'openedx.core.djangoapps.course_groups.views.course_cohort_settings_handler', + course_groups_views.course_cohort_settings_handler, name='course_cohort_settings', ), url( r'^courses/{}/cohorts/(?P[0-9]+)?$'.format( settings.COURSE_KEY_PATTERN, ), - 'openedx.core.djangoapps.course_groups.views.cohort_handler', + course_groups_views.cohort_handler, name='cohorts', ), url( r'^courses/{}/cohorts/(?P[0-9]+)$'.format( settings.COURSE_KEY_PATTERN, ), - 'openedx.core.djangoapps.course_groups.views.users_in_cohort', + course_groups_views.users_in_cohort, name='list_cohort', ), url( r'^courses/{}/cohorts/(?P[0-9]+)/add$'.format( settings.COURSE_KEY_PATTERN, ), - 'openedx.core.djangoapps.course_groups.views.add_users_to_cohort', + course_groups_views.add_users_to_cohort, name='add_to_cohort', ), url( r'^courses/{}/cohorts/(?P[0-9]+)/delete$'.format( settings.COURSE_KEY_PATTERN, ), - 'openedx.core.djangoapps.course_groups.views.remove_user_from_cohort', + course_groups_views.remove_user_from_cohort, name='remove_from_cohort', ), url( r'^courses/{}/cohorts/debug$'.format( settings.COURSE_KEY_PATTERN, ), - 'openedx.core.djangoapps.course_groups.views.debug_cohort_mgmt', + course_groups_views.debug_cohort_mgmt, name='debug_cohort_mgmt', ), url( r'^courses/{}/discussion/topics$'.format( settings.COURSE_KEY_PATTERN, ), - 'lms.djangoapps.discussion.views.discussion_topics', + discussion_views.discussion_topics, name='discussion_topics', ), url( r'^courses/{}/verified_track_content/settings'.format( settings.COURSE_KEY_PATTERN, ), - 'openedx.core.djangoapps.verified_track_content.views.cohorting_settings', + verified_track_content_views.cohorting_settings, name='verified_track_cohorting', ), url( r'^courses/{}/notes$'.format( settings.COURSE_ID_PATTERN, ), - 'notes.views.notes', + notes_views.notes, name='notes', ), url( @@ -601,7 +619,7 @@ urlpatterns += ( r'^courses/{}/lti_rest_endpoints/'.format( settings.COURSE_ID_PATTERN, ), - 'courseware.views.views.get_course_lti_endpoints', + courseware_views.get_course_lti_endpoints, name='lti_rest_endpoints', ), @@ -655,11 +673,11 @@ urlpatterns += ( r'^u/', include('openedx.features.learner_profile.urls'), ), -) +] -if settings.FEATURES["ENABLE_TEAMS"]: +if settings.FEATURES['ENABLE_TEAMS']: # Teams endpoints - urlpatterns += ( + urlpatterns += [ url( r'^api/team/', include('lms.djangoapps.teams.api_urls') @@ -671,33 +689,33 @@ if settings.FEATURES["ENABLE_TEAMS"]: include('lms.djangoapps.teams.urls'), name='teams_endpoints', ), - ) + ] # allow course staff to change to student view of courseware if settings.FEATURES.get('ENABLE_MASQUERADE'): - urlpatterns += ( + urlpatterns += [ url( r'^courses/{}/masquerade$'.format( settings.COURSE_KEY_PATTERN, ), - 'courseware.masquerade.handle_ajax', + courseware_masquerade_handle_ajax, name='masquerade_update', ), - ) + ] -urlpatterns += ( +urlpatterns += [ url( r'^courses/{}/generate_user_cert'.format( settings.COURSE_ID_PATTERN, ), - 'courseware.views.views.generate_user_cert', + courseware_views.generate_user_cert, name='generate_user_cert', ), -) +] # discussion forums live within courseware, so courseware must be enabled first if settings.FEATURES.get('ENABLE_DISCUSSION_SERVICE'): - urlpatterns += ( + urlpatterns += [ url( r'^api/discussion/', include('discussion_api.urls') @@ -716,19 +734,19 @@ if settings.FEATURES.get('ENABLE_DISCUSSION_SERVICE'): ), url( r'^notification_prefs/enable/', - 'notification_prefs.views.ajax_enable' + notification_prefs_views.ajax_enable ), url( r'^notification_prefs/disable/', - 'notification_prefs.views.ajax_disable' + notification_prefs_views.ajax_disable ), url( r'^notification_prefs/status/', - 'notification_prefs.views.ajax_status' + notification_prefs_views.ajax_status ), url( r'^notification_prefs/unsubscribe/(?P[a-zA-Z0-9-_=]+)/', - 'notification_prefs.views.set_subscription', + notification_prefs_views.set_subscription, { 'subscribe': False, }, @@ -736,15 +754,15 @@ if settings.FEATURES.get('ENABLE_DISCUSSION_SERVICE'): ), url( r'^notification_prefs/resubscribe/(?P[a-zA-Z0-9-_=]+)/', - 'notification_prefs.views.set_subscription', + notification_prefs_views.set_subscription, { 'subscribe': True, }, name='resubscribe_forum_update', ), - ) + ] -urlpatterns += ( +urlpatterns += [ url( r'^courses/{}/tab/(?P[^/]+)/$'.format( settings.COURSE_ID_PATTERN, @@ -752,9 +770,9 @@ urlpatterns += ( CourseTabView.as_view(), name='course_tab_view', ), -) +] -urlpatterns += ( +urlpatterns += [ # This MUST be the last view in the courseware--it's a catch-all for custom tabs. url( r'^courses/{}/(?P[^/]+)/$'.format( @@ -763,115 +781,115 @@ urlpatterns += ( StaticCourseTabView.as_view(), name='static_tab', ), -) +] if settings.FEATURES.get('ENABLE_STUDENT_HISTORY_VIEW'): - urlpatterns += ( + urlpatterns += [ url( r'^courses/{}/submission_history/(?P[^/]*)/(?P.*?)$'.format( settings.COURSE_ID_PATTERN ), - 'courseware.views.views.submission_history', + courseware_views.submission_history, name='submission_history', ), - ) + ] if settings.FEATURES.get('CLASS_DASHBOARD'): - urlpatterns += ( + urlpatterns += [ url(r'^class_dashboard/', include('class_dashboard.urls')), - ) + ] if settings.DEBUG or settings.FEATURES.get('ENABLE_DJANGO_ADMIN_SITE'): - ## Jasmine and admin - urlpatterns += (url(r'^admin/', include(admin.site.urls)),) + # Jasmine and admin + urlpatterns += [ + url(r'^admin/', include(admin.site.urls)), + ] if settings.FEATURES.get('AUTH_USE_OPENID'): - urlpatterns += ( - url(r'^openid/login/$', 'django_openid_auth.views.login_begin', name='openid-login'), + urlpatterns += [ + url(r'^openid/login/$', django_openid_auth_views.login_begin, name='openid-login'), url( r'^openid/complete/$', - 'openedx.core.djangoapps.external_auth.views.openid_login_complete', + external_auth_views.openid_login_complete, name='openid-complete', ), - url(r'^openid/logo.gif$', 'django_openid_auth.views.logo', name='openid-logo'), - ) + url(r'^openid/logo.gif$', django_openid_auth_views.logo, name='openid-logo'), + ] if settings.FEATURES.get('AUTH_USE_SHIB'): - urlpatterns += ( - url(r'^shib-login/$', 'openedx.core.djangoapps.external_auth.views.shib_login', name='shib-login'), - ) + urlpatterns += [ + url(r'^shib-login/$', external_auth_views.shib_login, name='shib-login'), + ] if settings.FEATURES.get('AUTH_USE_CAS'): - urlpatterns += ( - url(r'^cas-auth/login/$', 'openedx.core.djangoapps.external_auth.views.cas_login', name="cas-login"), - url(r'^cas-auth/logout/$', 'django_cas.views.logout', {'next_page': '/'}, name="cas-logout"), - ) + urlpatterns += [ + url(r'^cas-auth/login/$', external_auth_views.cas_login, name='cas-login'), + url(r'^cas-auth/logout/$', django_cas_views.logout, {'next_page': '/'}, name='cas-logout'), + ] if settings.FEATURES.get('RESTRICT_ENROLL_BY_REG_METHOD'): - urlpatterns += ( + urlpatterns += [ url(r'^course_specific_login/{}/$'.format(settings.COURSE_ID_PATTERN), - 'openedx.core.djangoapps.external_auth.views.course_specific_login', name='course-specific-login'), + external_auth_views.course_specific_login, name='course-specific-login'), url(r'^course_specific_register/{}/$'.format(settings.COURSE_ID_PATTERN), - 'openedx.core.djangoapps.external_auth.views.course_specific_register', name='course-specific-register'), + external_auth_views.course_specific_register, name='course-specific-register'), + ] - ) - -if configuration_helpers.get_value('ENABLE_BULK_ENROLLMENT_VIEW', - settings.FEATURES['ENABLE_BULK_ENROLLMENT_VIEW']): - urlpatterns += ( +if configuration_helpers.get_value('ENABLE_BULK_ENROLLMENT_VIEW', settings.FEATURES['ENABLE_BULK_ENROLLMENT_VIEW']): + urlpatterns += [ url(r'^api/bulk_enroll/v1/', include('bulk_enroll.urls')), - ) + ] # Shopping cart -urlpatterns += ( +urlpatterns += [ url(r'^shoppingcart/', include('shoppingcart.urls')), url(r'^commerce/', include('commerce.urls', namespace='commerce')), -) +] # Course goals -urlpatterns += ( +urlpatterns += [ url(r'^api/course_goals/', include('lms.djangoapps.course_goals.urls', namespace='course_goals_api')), -) +] # Embargo if settings.FEATURES.get('EMBARGO'): - urlpatterns += ( + urlpatterns += [ url(r'^embargo/', include('openedx.core.djangoapps.embargo.urls', namespace='embargo')), url(r'^api/embargo/', include('openedx.core.djangoapps.embargo.urls', namespace='api_embargo')), - ) + ] # Survey Djangoapp -urlpatterns += ( +urlpatterns += [ url(r'^survey/', include('survey.urls')), -) +] if settings.FEATURES.get('AUTH_USE_OPENID_PROVIDER'): - urlpatterns += ( + urlpatterns += [ url( r'^openid/provider/login/$', - 'openedx.core.djangoapps.external_auth.views.provider_login', + external_auth_views.provider_login, name='openid-provider-login', ), url( r'^openid/provider/login/(?:.+)$', - 'openedx.core.djangoapps.external_auth.views.provider_identity', + external_auth_views.provider_identity, name='openid-provider-login-identity' ), url( r'^openid/provider/identity/$', - 'openedx.core.djangoapps.external_auth.views.provider_identity', + external_auth_views.provider_identity, name='openid-provider-identity', ), url( r'^openid/provider/xrds/$', - 'openedx.core.djangoapps.external_auth.views.provider_xrds', + external_auth_views.provider_xrds, name='openid-provider-xrds', ), - ) + ] if settings.FEATURES.get('ENABLE_OAUTH2_PROVIDER'): - urlpatterns += ( + urlpatterns += [ # These URLs dispatch to django-oauth-toolkit or django-oauth2-provider as appropriate. # Developers should use these routes, to maintain compatibility for existing client code url(r'^oauth2/', include('openedx.core.djangoapps.oauth_dispatch.urls')), @@ -883,122 +901,122 @@ if settings.FEATURES.get('ENABLE_OAUTH2_PROVIDER'): # uses reverse() with the 'oauth2_provider' namespace. Developers should not access these # views directly, but should rather use the wrapped views at /oauth2/ url(r'^_o/', include('oauth2_provider.urls', namespace='oauth2_provider')), - ) + ] if settings.FEATURES.get('ENABLE_LMS_MIGRATION'): - urlpatterns += ( - url(r'^migrate/modules$', 'lms_migration.migrate.manage_modulestores'), - url(r'^migrate/reload/(?P[^/]+)$', 'lms_migration.migrate.manage_modulestores'), + urlpatterns += [ + url(r'^migrate/modules$', lms_migrate_views.manage_modulestores), + url(r'^migrate/reload/(?P[^/]+)$', lms_migrate_views.manage_modulestores), url( r'^migrate/reload/(?P[^/]+)/(?P[^/]+)$', - 'lms_migration.migrate.manage_modulestores' + lms_migrate_views.manage_modulestores ), - url(r'^gitreload$', 'lms_migration.migrate.gitreload'), - url(r'^gitreload/(?P[^/]+)$', 'lms_migration.migrate.gitreload'), - ) + url(r'^gitreload$', lms_migrate_views.gitreload), + url(r'^gitreload/(?P[^/]+)$', lms_migrate_views.gitreload), + ] if settings.FEATURES.get('ENABLE_SQL_TRACKING_LOGS'): - urlpatterns += ( - url(r'^event_logs$', 'track.views.view_tracking_log'), - url(r'^event_logs/(?P.+)$', 'track.views.view_tracking_log'), - ) + urlpatterns += [ + url(r'^event_logs$', track_views.view_tracking_log), + url(r'^event_logs/(?P.+)$', track_views.view_tracking_log), + ] if settings.FEATURES.get('ENABLE_SERVICE_STATUS'): - urlpatterns += ( + urlpatterns += [ url(r'^status/', include('openedx.core.djangoapps.service_status.urls')), - ) + ] if settings.FEATURES.get('ENABLE_INSTRUCTOR_BACKGROUND_TASKS'): - urlpatterns += ( + urlpatterns += [ url( r'^instructor_task_status/$', - 'lms.djangoapps.instructor_task.views.instructor_task_status', + instructor_task_views.instructor_task_status, name='instructor_task_status' ), - ) + ] if settings.FEATURES.get('RUN_AS_ANALYTICS_SERVER_ENABLED'): - urlpatterns += ( + urlpatterns += [ url(r'^edinsights_service/', include('edinsights.core.urls')), - ) + ] if settings.FEATURES.get('ENABLE_DEBUG_RUN_PYTHON'): - urlpatterns += ( - url(r'^debug/run_python$', 'debug.views.run_python'), - ) + urlpatterns += [ + url(r'^debug/run_python$', debug_views.run_python), + ] -urlpatterns += ( - url(r'^debug/show_parameters$', 'debug.views.show_parameters'), -) +urlpatterns += [ + url(r'^debug/show_parameters$', debug_views.show_parameters), +] # Third-party auth. if settings.FEATURES.get('ENABLE_THIRD_PARTY_AUTH'): - urlpatterns += ( + urlpatterns += [ url(r'', include('third_party_auth.urls')), url(r'api/third_party_auth/', include('third_party_auth.api.urls')), # NOTE: The following login_oauth_token endpoint is DEPRECATED. # Please use the exchange_access_token endpoint instead. - url(r'^login_oauth_token/(?P[^/]+)/$', 'student.views.login_oauth_token'), - ) + url(r'^login_oauth_token/(?P[^/]+)/$', student_views.login_oauth_token), + ] # Enterprise if enterprise_enabled(): - urlpatterns += ( + urlpatterns += [ url(r'', include('enterprise.urls')), - ) + ] # OAuth token exchange if settings.FEATURES.get('ENABLE_OAUTH2_PROVIDER'): - urlpatterns += ( + urlpatterns += [ url( r'^oauth2/login/$', LoginWithAccessTokenView.as_view(), - name="login_with_access_token" + name='login_with_access_token' ), - ) + ] # Certificates -urlpatterns += ( - url(r'^certificates/', include('certificates.urls', app_name="certificates", namespace="certificates")), +urlpatterns += [ + url(r'^certificates/', include('certificates.urls', app_name='certificates', namespace='certificates')), # Backwards compatibility with XQueue, which uses URLs that are not prefixed with /certificates/ - url(r'^update_certificate$', 'certificates.views.update_certificate'), - url(r'^update_example_certificate$', 'certificates.views.update_example_certificate'), - url(r'^request_certificate$', 'certificates.views.request_certificate'), + url(r'^update_certificate$', certificates_views.update_certificate, name='update_certificate'), + url(r'^update_example_certificate$', certificates_views.update_example_certificate, + name='update_example_certificate'), + url(r'^request_certificate$', certificates_views.request_certificate, + name='request_certificate'), # REST APIs url(r'^api/certificates/', include('lms.djangoapps.certificates.apis.urls', namespace='certificates_api')), -) +] # XDomain proxy -urlpatterns += ( - url(r'^xdomain_proxy.html$', 'openedx.core.djangoapps.cors_csrf.views.xdomain_proxy', name='xdomain_proxy'), -) +urlpatterns += [ + url(r'^xdomain_proxy.html$', cors_csrf_views.xdomain_proxy, name='xdomain_proxy'), +] # Custom courses on edX (CCX) URLs -if settings.FEATURES["CUSTOM_COURSES_EDX"]: - urlpatterns += ( +if settings.FEATURES['CUSTOM_COURSES_EDX']: + urlpatterns += [ url(r'^courses/{}/'.format(settings.COURSE_ID_PATTERN), include('ccx.urls')), url(r'^api/ccx/', include('lms.djangoapps.ccx.api.urls', namespace='ccx_api')), - ) + ] # Access to courseware as an LTI provider -if settings.FEATURES.get("ENABLE_LTI_PROVIDER"): - urlpatterns += ( +if settings.FEATURES.get('ENABLE_LTI_PROVIDER'): + urlpatterns += [ url(r'^lti_provider/', include('lti_provider.urls')), - ) + ] -urlpatterns += ( +urlpatterns += [ url(r'config/self_paced', ConfigurationModelCurrentAPIView.as_view(model=SelfPacedConfiguration)), url(r'config/programs', ConfigurationModelCurrentAPIView.as_view(model=ProgramsApiConfig)), url(r'config/catalog', ConfigurationModelCurrentAPIView.as_view(model=CatalogIntegration)), url(r'config/forums', ConfigurationModelCurrentAPIView.as_view(model=ForumsConfig)), -) - -urlpatterns = patterns(*urlpatterns) +] if settings.DEBUG: urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) @@ -1009,41 +1027,43 @@ if settings.DEBUG: ) # UX reference templates -urlpatterns += url(r'^template/(?P