urls.py 23.3 KB
Newer Older
Piotr Mitros committed
1
from django.conf import settings
2
from django.conf.urls import patterns, include, url
Piotr Mitros committed
3
from django.contrib import admin
4
from django.conf.urls.static import static
5
from django.views.generic import RedirectView
6 7 8

from . import one_time_startup

9
import django.contrib.auth.views
Piotr Mitros committed
10 11

# Uncomment the next two lines to enable the admin:
12 13 14
if settings.DEBUG:
    from django.contrib import admin
    admin.autodiscover()
Piotr Mitros committed
15

Piotr Mitros committed
16
urlpatterns = ('',
17 18 19
    # certificate view

    url(r'^update_certificate$', 'certificates.views.update_certificate'),
Calen Pennington committed
20
    url(r'^$', 'branding.views.index', name="root"),   # Main marketing page, or redirect to courseware
21
    url(r'^dashboard$', 'student.views.dashboard', name="dashboard"),
22

23
    url(r'^admin_dashboard$', 'dashboard.views.dashboard'),
24

25 26 27 28
    # Adding to allow debugging issues when prod is mysteriously different from staging
    # (specifically missing get parameters in certain cases)
    url(r'^debug_request$', 'util.views.debug_request'),

29
    url(r'^change_email$', 'student.views.change_email_request', name="change_email"),
30
    url(r'^email_confirm/(?P<key>[^/]*)$', 'student.views.confirm_email_change'),
31
    url(r'^change_name$', 'student.views.change_name_request', name="change_name"),
32 33 34
    url(r'^accept_name_change$', 'student.views.accept_name_change'),
    url(r'^reject_name_change$', 'student.views.reject_name_change'),
    url(r'^pending_name_changes$', 'student.views.pending_name_changes'),
35

36 37 38 39 40
    url(r'^testcenter/login$', 'student.views.test_center_login'),

    # url(r'^testcenter/login$', 'student.test_center_views.login'),
    # url(r'^testcenter/logout$', 'student.test_center_views.logout'),

41
    url(r'^event$', 'track.views.user_track'),
Calen Pennington committed
42
    url(r'^t/(?P<template>[^/]*)$', 'static_template_view.views.index'),   # TODO: Is this used anymore? What is STATIC_GRAB?
43

44 45
    url(r'^accounts/login$', 'student.views.accounts_login', name="accounts_login"),

46
    url(r'^login$', 'student.views.login_user', name="login"),
47
    url(r'^login/(?P<error>[^/]*)$', 'student.views.login_user'),
48
    url(r'^logout$', 'student.views.logout_user', name='logout'),
49
    url(r'^create_account$', 'student.views.create_account'),
50 51
    url(r'^activate/(?P<key>[^/]*)$', 'student.views.activate_account', name="activate"),

52 53
    url(r'^begin_exam_registration/(?P<course_id>[^/]+/[^/]+/[^/]+)$', 'student.views.begin_exam_registration', name="begin_exam_registration"),
    url(r'^create_exam_registration$', 'student.views.create_exam_registration'),
54

55
    url(r'^password_reset/$', 'student.views.password_reset', name='password_reset'),
56 57
    ## Obsolete Django views for password resets
    ## TODO: Replace with Mako-ized views
58 59 60 61 62 63
    url(r'^password_change/$', django.contrib.auth.views.password_change,
        name='auth_password_change'),
    url(r'^password_change_done/$', django.contrib.auth.views.password_change_done,
        name='auth_password_change_done'),
    url(r'^password_reset_confirm/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$',
        django.contrib.auth.views.password_reset_confirm,
Piotr Mitros committed
64
        name='auth_password_reset_confirm'),
65
    url(r'^password_reset_complete/$', django.contrib.auth.views.password_reset_complete,
Piotr Mitros committed
66
        name='auth_password_reset_complete'),
67
    url(r'^password_reset_done/$', django.contrib.auth.views.password_reset_done,
Piotr Mitros committed
68
        name='auth_password_reset_done'),
69

70
    url(r'^heartbeat$', include('heartbeat.urls')),
71

72 73 74 75 76 77
    url(r'^university_profile/UTx$', 'courseware.views.static_university_profile',
        name="static_university_profile", kwargs={'org_id': 'UTx'}),
    url(r'^university_profile/WellesleyX$', 'courseware.views.static_university_profile',
        name="static_university_profile", kwargs={'org_id': 'WellesleyX'}),
    url(r'^university_profile/GeorgetownX$', 'courseware.views.static_university_profile',
        name="static_university_profile", kwargs={'org_id': 'GeorgetownX'}),
78 79 80

    # Dan accidentally sent out a press release with lower case urls for McGill, Toronto,
    # Rice, ANU, Delft, and EPFL.  Hence the redirects.
81 82
    url(r'^university_profile/McGillX$', 'courseware.views.static_university_profile',
        name="static_university_profile", kwargs={'org_id': 'McGillX'}),
83 84 85
    url(r'^university_profile/mcgillx$',
        RedirectView.as_view(url='/university_profile/McGillX')),

86 87
    url(r'^university_profile/TorontoX$', 'courseware.views.static_university_profile',
        name="static_university_profile", kwargs={'org_id': 'TorontoX'}),
88 89 90
    url(r'^university_profile/torontox$',
        RedirectView.as_view(url='/university_profile/TorontoX')),

91 92
    url(r'^university_profile/RiceX$', 'courseware.views.static_university_profile',
        name="static_university_profile", kwargs={'org_id': 'RiceX'}),
93 94 95
    url(r'^university_profile/ricex$',
        RedirectView.as_view(url='/university_profile/RiceX')),

96 97
    url(r'^university_profile/ANUx$', 'courseware.views.static_university_profile',
        name="static_university_profile", kwargs={'org_id': 'ANUx'}),
98 99 100
    url(r'^university_profile/anux$',
        RedirectView.as_view(url='/university_profile/ANUx')),

101 102
    url(r'^university_profile/DelftX$', 'courseware.views.static_university_profile',
        name="static_university_profile", kwargs={'org_id': 'DelftX'}),
103 104 105
    url(r'^university_profile/delftx$',
        RedirectView.as_view(url='/university_profile/DelftX')),

106 107
    url(r'^university_profile/EPFLx$', 'courseware.views.static_university_profile',
        name="static_university_profile", kwargs={'org_id': 'EPFLx'}),
108 109
    url(r'^university_profile/epflx$',
        RedirectView.as_view(url='/university_profile/EPFLx')),
110 111 112

    url(r'^university_profile/(?P<org_id>[^/]+)$', 'courseware.views.university_profile',
        name="university_profile"),
113

114
    #Semi-static views (these need to be rendered and have the login bar, but don't change)
115
    url(r'^404$', 'static_template_view.views.render',
116
        {'template': '404.html'}, name="404"),
117
    url(r'^about$', 'static_template_view.views.render',
118
        {'template': 'about.html'}, name="about_edx"),
119
    url(r'^jobs$', 'static_template_view.views.render',
120
        {'template': 'jobs.html'}, name="jobs"),
121
    url(r'^contact$', 'static_template_view.views.render',
122
        {'template': 'contact.html'}, name="contact"),
123
    url(r'^press$', 'student.views.press', name="press"),
124 125
    url(r'^media-kit$', 'static_template_view.views.render',
        {'template': 'media-kit.html'}, name="media-kit"),
126
    url(r'^faq$', 'static_template_view.views.render',
127
        {'template': 'faq.html'}, name="faq_edx"),
128
    url(r'^help$', 'static_template_view.views.render',
129
        {'template': 'help.html'}, name="help_edx"),
130

131
    url(r'^tos$', 'static_template_view.views.render',
132
        {'template': 'tos.html'}, name="tos"),
133
    url(r'^privacy$', 'static_template_view.views.render',
134
        {'template': 'privacy.html'}, name="privacy_edx"),
135
    # TODO: (bridger) The copyright has been removed until it is updated for edX
136
    # url(r'^copyright$', 'static_template_view.views.render',
137
    #     {'template': 'copyright.html'}, name="copyright"),
138
    url(r'^honor$', 'static_template_view.views.render',
139
        {'template': 'honor.html'}, name="honor"),
140 141 142

    #Press releases
    url(r'^press/mit-and-harvard-announce-edx$', 'static_template_view.views.render',
143
        {'template': 'press_releases/MIT_and_Harvard_announce_edX.html'}, name="press/mit-and-harvard-announce-edx"),
144
    url(r'^press/uc-berkeley-joins-edx$', 'static_template_view.views.render',
145
        {'template': 'press_releases/UC_Berkeley_joins_edX.html'}, name="press/uc-berkeley-joins-edx"),
146 147
    url(r'^press/edX-announces-proctored-exam-testing$', 'static_template_view.views.render',
        {'template': 'press_releases/edX_announces_proctored_exam_testing.html'}, name="press/edX-announces-proctored-exam-testing"),
148 149
    url(r'^press/elsevier-collaborates-with-edx$', 'static_template_view.views.render',
        {'template': 'press_releases/Elsevier_collaborates_with_edX.html'}, name="press/elsevier-collaborates-with-edx"),
150 151
    url(r'^press/ut-joins-edx$', 'static_template_view.views.render',
        {'template': 'press_releases/UT_joins_edX.html'}, name="press/ut-joins-edx"),
152 153
    url(r'^press/cengage-to-provide-book-content$', 'static_template_view.views.render',
        {'template': 'press_releases/Cengage_to_provide_book_content.html'}, name="press/cengage-to-provide-book-content"),
154 155
    url(r'^press/gates-foundation-announcement$', 'static_template_view.views.render',
        {'template': 'press_releases/Gates_Foundation_announcement.html'}, name="press/gates-foundation-announcement"),
156 157
    url(r'^press/wellesley-college-joins-edx$', 'static_template_view.views.render',
        {'template': 'press_releases/Wellesley_College_joins_edX.html'}, name="press/wellesley-college-joins-edx"),
158 159 160
    url(r'^press/georgetown-joins-edx$', 'static_template_view.views.render',
        {'template': 'press_releases/Georgetown_joins_edX.html'}, name="press/georgetown-joins-edx"),
    url(r'^press/spring-courses$', 'static_template_view.views.render',
Victor Shnayder committed
161 162
        {'template': 'press_releases/Spring_2013_course_announcements.html'},
        name="press/spring-courses"),
163
    url(r'^press/lewin-course-announcement$', 'static_template_view.views.render',
Victor Shnayder committed
164 165 166 167 168
        {'template': 'press_releases/Lewin_course_announcement.html'},
        name="press/lewin-course-announcement"),
    url(r'^press/bostonx-announcement$', 'static_template_view.views.render',
        {'template': 'press_releases/bostonx_announcement.html'},
        name="press/bostonx-announcement"),
Victor Shnayder committed
169 170 171
    url(r'^press/eric-lander-secret-of-life$', 'static_template_view.views.render',
        {'template': 'press_releases/eric_lander_secret_of_life.html'},
        name="press/eric-lander-secret-of-life"),
172 173 174
    url(r'^press/edx-expands-internationally$', 'static_template_view.views.render',
        {'template': 'press_releases/edx_expands_internationally.html'},
        name="press/edx-expands-internationally"),
Victor Shnayder committed
175

176

177
    # Should this always update to point to the latest press release?
Victor Shnayder committed
178
    (r'^pressrelease$', 'django.views.generic.simple.redirect_to',
179
     {'url': '/press/edx-expands-internationally'}),
180 181


Bridger Maxwell committed
182
    (r'^favicon\.ico$', 'django.views.generic.simple.redirect_to', {'url': '/static/images/favicon.ico'}),
183

184 185 186
    # TODO: These urls no longer work. They need to be updated before they are re-enabled
    # url(r'^send_feedback$', 'util.views.send_feedback'),
    # url(r'^reactivate/(?P<key>[^/]*)$', 'student.views.reactivation_email'),
Piotr Mitros committed
187 188
)

189
if settings.PERFSTATS:
Calen Pennington committed
190
    urlpatterns += (url(r'^reprofile$', 'perfstats.views.end_profile'),)
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
# 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 django_notify.urls import get_pattern as notify_pattern

    # Note that some of these urls are repeated in course_wiki.course_nav. Make sure to update
    # them together.
    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(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/(?P<course_id>[^/]+/[^/]+/[^/]+)/course_wiki/?$',
            'course_wiki.views.course_wiki_redirect', name="course_wiki"),
        url(r'^courses/(?:[^/]+/[^/]+/[^/]+)/wiki/', include(wiki_pattern())),
    )

218

Piotr Mitros committed
219
if settings.COURSEWARE_ENABLED:
220
    urlpatterns += (
221
        # Hook django-masquerade, allowing staff to view site as other users
Piotr Mitros committed
222
        url(r'^masquerade/', include('masquerade.urls')),
223

224 225
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/jump_to/(?P<location>.*)$',
            'courseware.views.jump_to', name="jump_to"),
226
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/modx/(?P<location>.*?)/(?P<dispatch>[^/]*)$',
227 228
            'courseware.module_render.modx_dispatch',
            name='modx_dispatch'),
229 230


231 232 233 234 235 236 237 238
        # Software Licenses

        # TODO: for now, this is the endpoint of an ajax replay
        # service that retrieve and assigns license numbers for
        # software assigned to a course. The numbers have to be loaded
        # into the database.
        url(r'^software-licenses$', 'licenses.views.user_software_license', name="user_software_license"),

239 240 241
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/xqueue/(?P<userid>[^/]*)/(?P<id>.*?)/(?P<dispatch>[^/]*)$',
            'courseware.module_render.xqueue_callback',
            name='xqueue_callback'),
242 243
        url(r'^change_setting$', 'student.views.change_setting',
            name='change_setting'),
244

245
        # TODO: These views need to be updated before they work
246
        url(r'^calculate$', 'util.views.calculate'),
247 248 249
        # TODO: We should probably remove the circuit package. I believe it was only used in the old way of saving wiki circuits for the wiki
        # url(r'^edit_circuit/(?P<circuit>[^/]*)$', 'circuit.views.edit_circuit'),
        # url(r'^save_circuit/(?P<circuit>[^/]*)$', 'circuit.views.save_circuit'),
250

251
        url(r'^courses/?$', 'branding.views.courses', name="courses"),
252
        url(r'^change_enrollment$',
253
            'student.views.change_enrollment_view', name="change_enrollment"),
254

255
        #About the course
256
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/about$',
257
            'courseware.views.course_about', name="about_course"),
258

259
        #Inside the course
260 261
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/$',
            'courseware.views.course_info', name="course_root"),
262
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/info$',
263
            'courseware.views.course_info', name="info"),
264
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/syllabus$',
Calen Pennington committed
265
            'courseware.views.syllabus', name="syllabus"),   # TODO arjun remove when custom tabs in place, see courseware/courses.py
266
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/book/(?P<book_index>[^/]*)/$',
267
            'staticbook.views.index', name="book"),
268
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/book/(?P<book_index>[^/]*)/(?P<page>[^/]*)$',
Bridger Maxwell committed
269
            'staticbook.views.index'),
270
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/book-shifted/(?P<page>[^/]*)$',
Bridger Maxwell committed
271
            'staticbook.views.index_shifted'),
Brian Wilson committed
272 273 274 275 276 277

        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/pdfbook/(?P<book_index>[^/]*)/$',
            'staticbook.views.pdf_index', name="pdf_book"),
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/pdfbook/(?P<book_index>[^/]*)/(?P<page>[^/]*)$',
            'staticbook.views.pdf_index'),

278 279 280 281
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/pdfbook/(?P<book_index>[^/]*)/chapter/(?P<chapter>[^/]*)/$',
            'staticbook.views.pdf_index'),
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/pdfbook/(?P<book_index>[^/]*)/chapter/(?P<chapter>[^/]*)/(?P<page>[^/]*)$',
            'staticbook.views.pdf_index'),
Brian Wilson committed
282

283 284
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/htmlbook/(?P<book_index>[^/]*)/$',
            'staticbook.views.html_index', name="html_book"),
285 286 287 288 289
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/htmlbook/(?P<book_index>[^/]*)/chapter/(?P<chapter>[^/]*)/$',
            'staticbook.views.html_index'),
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/htmlbook/(?P<book_index>[^/]*)/chapter/(?P<chapter>[^/]*)/(?P<anchor_id>[^/]*)/$',
            'staticbook.views.html_index'),
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/htmlbook/(?P<book_index>[^/]*)/(?P<anchor_id>[^/]*)/$',
290 291
            'staticbook.views.html_index'),

292
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/courseware/?$',
293
            'courseware.views.index', name="courseware"),
294 295
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/courseware/(?P<chapter>[^/]*)/$',
            'courseware.views.index', name="courseware_chapter"),
296
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/courseware/(?P<chapter>[^/]*)/(?P<section>[^/]*)/$',
297
            'courseware.views.index', name="courseware_section"),
298 299
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/courseware/(?P<chapter>[^/]*)/(?P<section>[^/]*)/(?P<position>[^/]*)/?$',
            'courseware.views.index', name="courseware_position"),
Brian Wilson committed
300

301 302
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/progress$',
            'courseware.views.progress', name="progress"),
303
        # Takes optional student_id for instructor use--shows profile as that student sees it.
304 305
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/progress/(?P<student_id>[^/]*)/$',
            'courseware.views.progress', name="student_progress"),
306

307
        # For the instructor
308
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/instructor$',
309
            'instructor.views.instructor_dashboard', name="instructor_dashboard"),
310

311
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/gradebook$',
312
            'instructor.views.gradebook', name='gradebook'),
313
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/grade_summary$',
314
            'instructor.views.grade_summary', name='grade_summary'),
315
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/enroll_students$',
316
            'instructor.views.enroll_students', name='enroll_students'),
317
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/staff_grading$',
318
            'open_ended_grading.views.staff_grading', name='staff_grading'),
319
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/staff_grading/get_next$',
320
            'open_ended_grading.staff_grading_service.get_next', name='staff_grading_get_next'),
321
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/staff_grading/save_grade$',
322
            'open_ended_grading.staff_grading_service.save_grade', name='staff_grading_save_grade'),
323
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/staff_grading/save_grade$',
324
            'open_ended_grading.staff_grading_service.save_grade', name='staff_grading_save_grade'),
325
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/staff_grading/get_problem_list$',
326
            'open_ended_grading.staff_grading_service.get_problem_list', name='staff_grading_get_problem_list'),
327

328 329 330
        # Open Ended problem list
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/open_ended_problems$',
            'open_ended_grading.views.student_problem_list', name='open_ended_problems'),
331 332 333 334

        # Open Ended flagged problem list
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/open_ended_flagged_problems$',
            'open_ended_grading.views.flagged_problem_list', name='open_ended_flagged_problems'),
335
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/open_ended_flagged_problems/take_action_on_flags$',
336
            'open_ended_grading.views.take_action_on_flags', name='open_ended_flagged_problems_take_action'),
Calen Pennington committed
337

338
		# Cohorts management
339 340 341 342 343 344 345 346 347 348 349
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/cohorts$',
            'course_groups.views.list_cohorts', name="cohorts"),
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/cohorts/add$',
            'course_groups.views.add_cohort',
            name="add_cohort"),
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/cohorts/(?P<cohort_id>[0-9]+)$',
            'course_groups.views.users_in_cohort',
            name="list_cohort"),
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/cohorts/(?P<cohort_id>[0-9]+)/add$',
            'course_groups.views.add_users_to_cohort',
            name="add_to_cohort"),
350 351 352
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/cohorts/(?P<cohort_id>[0-9]+)/delete$',
            'course_groups.views.remove_user_from_cohort',
            name="remove_from_cohort"),
353 354 355 356
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/cohorts/debug$',
            'course_groups.views.debug_cohort_mgmt',
            name="debug_cohort_mgmt"),

357 358 359
        # Open Ended Notifications
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/open_ended_notifications$',
            'open_ended_grading.views.combined_notifications', name='open_ended_notifications'),
360 361 362

        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/peer_grading$',
            'open_ended_grading.views.peer_grading', name='peer_grading'),
363
    )
364

365
    # discussion forums live within courseware, so courseware must be enabled first
Rocky Duan committed
366
    if settings.MITX_FEATURES.get('ENABLE_DISCUSSION_SERVICE'):
367
        urlpatterns += (
368
            url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/news$',
369 370 371 372
                'courseware.views.news', name="news"),
            url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/discussion/',
                include('django_comment_client.urls'))
            )
373 374
    urlpatterns += (
        # This MUST be the last view in the courseware--it's a catch-all for custom tabs.
375
        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/(?P<tab_slug>[^/]+)/$',
376 377
        'courseware.views.static_tab', name="static_tab"),
        )
378

379 380 381 382 383 384 385 386
    if settings.MITX_FEATURES.get('ENABLE_STUDENT_HISTORY_VIEW'):
        urlpatterns += (
            url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/submission_history/(?P<student_username>[^/]*)/(?P<location>.*?)$',
                'courseware.views.submission_history',
                name='submission_history'),
        )


387
if settings.ENABLE_JASMINE:
388 389
    urlpatterns += (url(r'^_jasmine/', include('django_jasmine.urls')),)

390
if settings.DEBUG:
391
    ## Jasmine and admin
392
    urlpatterns += (url(r'^admin/', include(admin.site.urls)),)
393

ichuang committed
394 395 396
if settings.MITX_FEATURES.get('AUTH_USE_OPENID'):
    urlpatterns += (
        url(r'^openid/login/$', 'django_openid_auth.views.login_begin', name='openid-login'),
397
        url(r'^openid/complete/$', 'external_auth.views.openid_login_complete', name='openid-complete'),
ichuang committed
398
        url(r'^openid/logo.gif$', 'django_openid_auth.views.logo', name='openid-logo'),
399 400 401 402
    )

if settings.MITX_FEATURES.get('AUTH_USE_OPENID_PROVIDER'):
    urlpatterns += (
403
        url(r'^openid/provider/login/$', 'external_auth.views.provider_login', name='openid-provider-login'),
404
        url(r'^openid/provider/login/(?:.+)$', 'external_auth.views.provider_identity', name='openid-provider-login-identity'),
405 406
        url(r'^openid/provider/identity/$', 'external_auth.views.provider_identity', name='openid-provider-identity'),
        url(r'^openid/provider/xrds/$', 'external_auth.views.provider_xrds', name='openid-provider-xrds')
407
    )
ichuang committed
408

409 410 411 412
if settings.MITX_FEATURES.get('ENABLE_LMS_MIGRATION'):
    urlpatterns += (
        url(r'^migrate/modules$', 'lms_migration.migrate.manage_modulestores'),
        url(r'^migrate/reload/(?P<reload_dir>[^/]+)$', 'lms_migration.migrate.manage_modulestores'),
413
        url(r'^migrate/reload/(?P<reload_dir>[^/]+)/(?P<commit_id>[^/]+)$', 'lms_migration.migrate.manage_modulestores'),
414 415
        url(r'^gitreload$', 'lms_migration.migrate.gitreload'),
        url(r'^gitreload/(?P<reload_dir>[^/]+)$', 'lms_migration.migrate.gitreload'),
416 417
        )

418 419 420
if settings.MITX_FEATURES.get('ENABLE_SQL_TRACKING_LOGS'):
    urlpatterns += (
        url(r'^event_logs$', 'track.views.view_tracking_log'),
421
        url(r'^event_logs/(?P<args>.+)$', 'track.views.view_tracking_log'),
422 423
        )

Victor Shnayder committed
424 425 426 427 428 429
# FoldIt views
urlpatterns += (
    # The path is hardcoded into their app...
    url(r'^comm/foldit_ops', 'foldit.views.foldit_ops', name="foldit_ops"),
)

430 431
urlpatterns = patterns(*urlpatterns)

432
if settings.DEBUG:
433
    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
434 435

#Custom error pages
436 437
handler404 = 'static_template_view.views.render_404'
handler500 = 'static_template_view.views.render_500'