Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
355ebd62
Commit
355ebd62
authored
Oct 23, 2013
by
cahrens
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Convert course team management to new URL scheme.
Move RESTful URLs into our "done" section.
parent
1cec44e5
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
115 additions
and
106 deletions
+115
-106
CHANGELOG.rst
+4
-0
cms/djangoapps/contentstore/tests/test_checklists.py
+2
-2
cms/djangoapps/contentstore/tests/test_contentstore.py
+5
-5
cms/djangoapps/contentstore/tests/test_course_index.py
+3
-6
cms/djangoapps/contentstore/tests/test_users.py
+11
-38
cms/djangoapps/contentstore/views/checklist.py
+11
-6
cms/djangoapps/contentstore/views/user.py
+43
-16
cms/templates/manage_users.html
+10
-16
cms/templates/settings.html
+7
-2
cms/templates/settings_advanced.html
+7
-2
cms/templates/settings_graders.html
+7
-2
cms/templates/widgets/header.html
+2
-1
cms/urls.py
+3
-10
No files found.
CHANGELOG.rst
View file @
355ebd62
...
@@ -5,6 +5,10 @@ These are notable changes in edx-platform. This is a rolling list of changes,
...
@@ -5,6 +5,10 @@ These are notable changes in edx-platform. This is a rolling list of changes,
in roughly chronological order, most recent first. Add your entries at or near
in roughly chronological order, most recent first. Add your entries at or near
the top. Include a label indicating the component affected.
the top. Include a label indicating the component affected.
Studio: Change course overview page, checklists, and course staff management
page URLs to a RESTful interface. Also removed "\listing", which duplicated
"\index".
Blades: When start time and end time are specified for a video, a visual range
Blades: When start time and end time are specified for a video, a visual range
will be shown on the time slider to highlight the place in the video that will
will be shown on the time slider to highlight the place in the video that will
be played.
be played.
...
...
cms/djangoapps/contentstore/tests/test_checklists.py
View file @
355ebd62
...
@@ -42,7 +42,7 @@ class ChecklistTestCase(CourseTestCase):
...
@@ -42,7 +42,7 @@ class ChecklistTestCase(CourseTestCase):
response
=
self
.
client
.
get
(
self
.
checklists_url
)
response
=
self
.
client
.
get
(
self
.
checklists_url
)
self
.
assertContains
(
response
,
"Getting Started With Studio"
)
self
.
assertContains
(
response
,
"Getting Started With Studio"
)
# Verify expansion of action URL happened.
# Verify expansion of action URL happened.
self
.
assertContains
(
response
,
'
/mitX/333/team/
Checklists_Course'
)
self
.
assertContains
(
response
,
'
course_team/mitX.333.
Checklists_Course'
)
# Verify persisted checklist does NOT have expanded URL.
# Verify persisted checklist does NOT have expanded URL.
checklist_0
=
self
.
get_persisted_checklists
()[
0
]
checklist_0
=
self
.
get_persisted_checklists
()[
0
]
self
.
assertEqual
(
'ManageUsers'
,
get_action_url
(
checklist_0
,
0
))
self
.
assertEqual
(
'ManageUsers'
,
get_action_url
(
checklist_0
,
0
))
...
@@ -137,7 +137,7 @@ class ChecklistTestCase(CourseTestCase):
...
@@ -137,7 +137,7 @@ class ChecklistTestCase(CourseTestCase):
# Verify no side effect in the original list.
# Verify no side effect in the original list.
self
.
assertEqual
(
get_action_url
(
checklist
,
index
),
stored
)
self
.
assertEqual
(
get_action_url
(
checklist
,
index
),
stored
)
test_expansion
(
self
.
course
.
checklists
[
0
],
0
,
'ManageUsers'
,
'/
mitX/333/team
/Checklists_Course'
)
test_expansion
(
self
.
course
.
checklists
[
0
],
0
,
'ManageUsers'
,
'/
course_team/mitX.333.Checklists_Course/branch/draft/block
/Checklists_Course'
)
test_expansion
(
self
.
course
.
checklists
[
1
],
1
,
'CourseOutline'
,
'/course/mitX.333.Checklists_Course/branch/draft/block/Checklists_Course'
)
test_expansion
(
self
.
course
.
checklists
[
1
],
1
,
'CourseOutline'
,
'/course/mitX.333.Checklists_Course/branch/draft/block/Checklists_Course'
)
test_expansion
(
self
.
course
.
checklists
[
2
],
0
,
'http://help.edge.edx.org/'
,
'http://help.edge.edx.org/'
)
test_expansion
(
self
.
course
.
checklists
[
2
],
0
,
'http://help.edge.edx.org/'
,
'http://help.edge.edx.org/'
)
...
...
cms/djangoapps/contentstore/tests/test_contentstore.py
View file @
355ebd62
...
@@ -1585,6 +1585,8 @@ class ContentStoreTest(ModuleStoreTestCase):
...
@@ -1585,6 +1585,8 @@ class ContentStoreTest(ModuleStoreTestCase):
"""
"""
import_from_xml
(
modulestore
(
'direct'
),
'common/test/data/'
,
[
'simple'
])
import_from_xml
(
modulestore
(
'direct'
),
'common/test/data/'
,
[
'simple'
])
loc
=
Location
([
'i4x'
,
'edX'
,
'simple'
,
'course'
,
'2012_Fall'
,
None
])
loc
=
Location
([
'i4x'
,
'edX'
,
'simple'
,
'course'
,
'2012_Fall'
,
None
])
new_location
=
loc_mapper
()
.
translate_location
(
loc
.
course_id
,
loc
,
False
,
True
)
resp
=
self
.
_show_course_overview
(
loc
)
resp
=
self
.
_show_course_overview
(
loc
)
self
.
assertEqual
(
resp
.
status_code
,
200
)
self
.
assertEqual
(
resp
.
status_code
,
200
)
self
.
assertContains
(
resp
,
'Chapter 2'
)
self
.
assertContains
(
resp
,
'Chapter 2'
)
...
@@ -1605,11 +1607,9 @@ class ContentStoreTest(ModuleStoreTestCase):
...
@@ -1605,11 +1607,9 @@ class ContentStoreTest(ModuleStoreTestCase):
'name'
:
loc
.
name
}))
'name'
:
loc
.
name
}))
self
.
assertEqual
(
resp
.
status_code
,
200
)
self
.
assertEqual
(
resp
.
status_code
,
200
)
# manage users
# course team
resp
=
self
.
client
.
get
(
reverse
(
'manage_users'
,
url
=
new_location
.
url_reverse
(
'course_team/'
,
''
)
kwargs
=
{
'org'
:
loc
.
org
,
resp
=
self
.
client
.
get
(
url
,
HTTP_ACCEPT
=
'text/html'
)
'course'
:
loc
.
course
,
'name'
:
loc
.
name
}))
self
.
assertEqual
(
resp
.
status_code
,
200
)
self
.
assertEqual
(
resp
.
status_code
,
200
)
# course info
# course info
...
...
cms/djangoapps/contentstore/tests/test_course_index.py
View file @
355ebd62
...
@@ -73,12 +73,9 @@ class TestCourseIndex(CourseTestCase):
...
@@ -73,12 +73,9 @@ class TestCourseIndex(CourseTestCase):
"""
"""
course_staff_client
,
course_staff
=
self
.
createNonStaffAuthedUserClient
()
course_staff_client
,
course_staff
=
self
.
createNonStaffAuthedUserClient
()
for
course
in
[
self
.
course
,
self
.
odd_course
]:
for
course
in
[
self
.
course
,
self
.
odd_course
]:
permission_url
=
reverse
(
"course_team_user"
,
kwargs
=
{
new_location
=
loc_mapper
()
.
translate_location
(
course
.
location
.
course_id
,
course
.
location
,
False
,
True
)
"org"
:
course
.
location
.
org
,
permission_url
=
new_location
.
url_reverse
(
"course_team/"
,
course_staff
.
email
)
"course"
:
course
.
location
.
course
,
"name"
:
course
.
location
.
name
,
"email"
:
course_staff
.
email
,
})
self
.
client
.
post
(
self
.
client
.
post
(
permission_url
,
permission_url
,
data
=
json
.
dumps
({
"role"
:
"staff"
}),
data
=
json
.
dumps
({
"role"
:
"staff"
}),
...
...
cms/djangoapps/contentstore/tests/test_users.py
View file @
355ebd62
...
@@ -4,9 +4,9 @@ Tests for contentstore/views/user.py.
...
@@ -4,9 +4,9 @@ Tests for contentstore/views/user.py.
import
json
import
json
from
.utils
import
CourseTestCase
from
.utils
import
CourseTestCase
from
django.contrib.auth.models
import
User
,
Group
from
django.contrib.auth.models
import
User
,
Group
from
django.core.urlresolvers
import
reverse
from
auth.authz
import
get_course_groupname_for_role
from
auth.authz
import
get_course_groupname_for_role
from
student.models
import
CourseEnrollment
from
student.models
import
CourseEnrollment
from
xmodule.modulestore.django
import
loc_mapper
class
UsersTestCase
(
CourseTestCase
):
class
UsersTestCase
(
CourseTestCase
):
...
@@ -23,34 +23,17 @@ class UsersTestCase(CourseTestCase):
...
@@ -23,34 +23,17 @@ class UsersTestCase(CourseTestCase):
self
.
inactive_user
.
is_staff
=
False
self
.
inactive_user
.
is_staff
=
False
self
.
inactive_user
.
save
()
self
.
inactive_user
.
save
()
self
.
index_url
=
reverse
(
"manage_users"
,
kwargs
=
{
self
.
location
=
loc_mapper
()
.
translate_location
(
self
.
course
.
location
.
course_id
,
self
.
course
.
location
,
False
,
True
)
"org"
:
self
.
course
.
location
.
org
,
"course"
:
self
.
course
.
location
.
course
,
self
.
index_url
=
self
.
location
.
url_reverse
(
'course_team'
,
''
)
"name"
:
self
.
course
.
location
.
name
,
self
.
detail_url
=
self
.
location
.
url_reverse
(
'course_team'
,
self
.
ext_user
.
email
)
})
self
.
inactive_detail_url
=
self
.
location
.
url_reverse
(
'course_team'
,
self
.
inactive_user
.
email
)
self
.
detail_url
=
reverse
(
"course_team_user"
,
kwargs
=
{
self
.
invalid_detail_url
=
self
.
location
.
url_reverse
(
'course_team'
,
"nonexistent@user.com"
)
"org"
:
self
.
course
.
location
.
org
,
"course"
:
self
.
course
.
location
.
course
,
"name"
:
self
.
course
.
location
.
name
,
"email"
:
self
.
ext_user
.
email
,
})
self
.
inactive_detail_url
=
reverse
(
"course_team_user"
,
kwargs
=
{
"org"
:
self
.
course
.
location
.
org
,
"course"
:
self
.
course
.
location
.
course
,
"name"
:
self
.
course
.
location
.
name
,
"email"
:
self
.
inactive_user
.
email
,
})
self
.
invalid_detail_url
=
reverse
(
"course_team_user"
,
kwargs
=
{
"org"
:
self
.
course
.
location
.
org
,
"course"
:
self
.
course
.
location
.
course
,
"name"
:
self
.
course
.
location
.
name
,
"email"
:
"nonexistent@user.com"
,
})
self
.
staff_groupname
=
get_course_groupname_for_role
(
self
.
course
.
location
,
"staff"
)
self
.
staff_groupname
=
get_course_groupname_for_role
(
self
.
course
.
location
,
"staff"
)
self
.
inst_groupname
=
get_course_groupname_for_role
(
self
.
course
.
location
,
"instructor"
)
self
.
inst_groupname
=
get_course_groupname_for_role
(
self
.
course
.
location
,
"instructor"
)
def
test_index
(
self
):
def
test_index
(
self
):
resp
=
self
.
client
.
get
(
self
.
index_url
)
resp
=
self
.
client
.
get
(
self
.
index_url
,
HTTP_ACCEPT
=
'text/html'
)
# ext_user is not currently a member of the course team, and so should
# ext_user is not currently a member of the course team, and so should
# not show up on the page.
# not show up on the page.
self
.
assertNotContains
(
resp
,
self
.
ext_user
.
email
)
self
.
assertNotContains
(
resp
,
self
.
ext_user
.
email
)
...
@@ -60,7 +43,7 @@ class UsersTestCase(CourseTestCase):
...
@@ -60,7 +43,7 @@ class UsersTestCase(CourseTestCase):
self
.
ext_user
.
groups
.
add
(
group
)
self
.
ext_user
.
groups
.
add
(
group
)
self
.
ext_user
.
save
()
self
.
ext_user
.
save
()
resp
=
self
.
client
.
get
(
self
.
index_url
)
resp
=
self
.
client
.
get
(
self
.
index_url
,
HTTP_ACCEPT
=
'text/html'
)
self
.
assertContains
(
resp
,
self
.
ext_user
.
email
)
self
.
assertContains
(
resp
,
self
.
ext_user
.
email
)
def
test_detail
(
self
):
def
test_detail
(
self
):
...
@@ -261,12 +244,7 @@ class UsersTestCase(CourseTestCase):
...
@@ -261,12 +244,7 @@ class UsersTestCase(CourseTestCase):
self
.
user
.
is_staff
=
False
self
.
user
.
is_staff
=
False
self
.
user
.
save
()
self
.
user
.
save
()
self_url
=
reverse
(
"course_team_user"
,
kwargs
=
{
self_url
=
self
.
location
.
url_reverse
(
'course_team'
,
self
.
user
.
email
)
"org"
:
self
.
course
.
location
.
org
,
"course"
:
self
.
course
.
location
.
course
,
"name"
:
self
.
course
.
location
.
name
,
"email"
:
self
.
user
.
email
,
})
resp
=
self
.
client
.
post
(
resp
=
self
.
client
.
post
(
self_url
,
self_url
,
...
@@ -298,12 +276,7 @@ class UsersTestCase(CourseTestCase):
...
@@ -298,12 +276,7 @@ class UsersTestCase(CourseTestCase):
self
.
user
.
is_staff
=
False
self
.
user
.
is_staff
=
False
self
.
user
.
save
()
self
.
user
.
save
()
self_url
=
reverse
(
"course_team_user"
,
kwargs
=
{
self_url
=
self
.
location
.
url_reverse
(
'course_team'
,
self
.
user
.
email
)
"org"
:
self
.
course
.
location
.
org
,
"course"
:
self
.
course
.
location
.
course
,
"name"
:
self
.
course
.
location
.
name
,
"email"
:
self
.
user
.
email
,
})
resp
=
self
.
client
.
delete
(
self_url
)
resp
=
self
.
client
.
delete
(
self_url
)
self
.
assertEqual
(
resp
.
status_code
,
204
)
self
.
assertEqual
(
resp
.
status_code
,
204
)
...
...
cms/djangoapps/contentstore/views/checklist.py
View file @
355ebd62
...
@@ -113,20 +113,25 @@ def expand_checklist_action_url(course_module, checklist):
...
@@ -113,20 +113,25 @@ def expand_checklist_action_url(course_module, checklist):
The method does a copy of the input checklist and does not modify the input argument.
The method does a copy of the input checklist and does not modify the input argument.
"""
"""
expanded_checklist
=
copy
.
deepcopy
(
checklist
)
expanded_checklist
=
copy
.
deepcopy
(
checklist
)
urlconf_map
=
{
oldurlconf_map
=
{
"ManageUsers"
:
"manage_users"
,
"SettingsDetails"
:
"settings_details"
,
"SettingsDetails"
:
"settings_details"
,
"SettingsGrading"
:
"settings_grading"
"SettingsGrading"
:
"settings_grading"
}
}
urlconf_map
=
{
"ManageUsers"
:
"course_team"
,
"CourseOutline"
:
"course"
}
for
item
in
expanded_checklist
.
get
(
'items'
):
for
item
in
expanded_checklist
.
get
(
'items'
):
action_url
=
item
.
get
(
'action_url'
)
action_url
=
item
.
get
(
'action_url'
)
if
action_url
==
"CourseOutline"
:
if
action_url
in
urlconf_map
:
url_prefix
=
urlconf_map
[
action_url
]
ctx_loc
=
course_module
.
location
ctx_loc
=
course_module
.
location
location
=
loc_mapper
()
.
translate_location
(
ctx_loc
.
course_id
,
ctx_loc
,
False
,
True
)
location
=
loc_mapper
()
.
translate_location
(
ctx_loc
.
course_id
,
ctx_loc
,
False
,
True
)
item
[
'action_url'
]
=
location
.
url_reverse
(
'course/'
,
''
)
item
[
'action_url'
]
=
location
.
url_reverse
(
url_prefix
,
''
)
elif
action_url
in
urlconf_map
:
elif
action_url
in
old
urlconf_map
:
urlconf_name
=
urlconf_map
[
action_url
]
urlconf_name
=
old
urlconf_map
[
action_url
]
item
[
'action_url'
]
=
reverse
(
urlconf_name
,
kwargs
=
{
item
[
'action_url'
]
=
reverse
(
urlconf_name
,
kwargs
=
{
'org'
:
course_module
.
location
.
org
,
'org'
:
course_module
.
location
.
org
,
'course'
:
course_module
.
location
.
course
,
'course'
:
course_module
.
location
.
course
,
...
...
cms/djangoapps/contentstore/views/user.py
View file @
355ebd62
...
@@ -12,7 +12,6 @@ from mitxmako.shortcuts import render_to_response
...
@@ -12,7 +12,6 @@ from mitxmako.shortcuts import render_to_response
from
django.core.context_processors
import
csrf
from
django.core.context_processors
import
csrf
from
xmodule.modulestore.django
import
modulestore
,
loc_mapper
from
xmodule.modulestore.django
import
modulestore
,
loc_mapper
from
xmodule.modulestore
import
Location
from
xmodule.error_module
import
ErrorDescriptor
from
xmodule.error_module
import
ErrorDescriptor
from
contentstore.utils
import
get_lms_link_for_item
from
contentstore.utils
import
get_lms_link_for_item
from
util.json_request
import
JsonResponse
from
util.json_request
import
JsonResponse
...
@@ -25,6 +24,11 @@ from course_creators.views import (
...
@@ -25,6 +24,11 @@ from course_creators.views import (
from
.access
import
has_access
from
.access
import
has_access
from
student.models
import
CourseEnrollment
from
student.models
import
CourseEnrollment
from
xmodule.modulestore.locator
import
BlockUsageLocator
from
django.http
import
HttpResponseNotFound
__all__
=
[
'index'
,
'request_course_creator'
,
'course_team_handler'
]
@login_required
@login_required
...
@@ -65,7 +69,7 @@ def index(request):
...
@@ -65,7 +69,7 @@ def index(request):
return
render_to_response
(
'index.html'
,
{
return
render_to_response
(
'index.html'
,
{
'courses'
:
[
format_course_for_view
(
c
)
for
c
in
courses
if
not
isinstance
(
c
,
ErrorDescriptor
)],
'courses'
:
[
format_course_for_view
(
c
)
for
c
in
courses
if
not
isinstance
(
c
,
ErrorDescriptor
)],
'user'
:
request
.
user
,
'user'
:
request
.
user
,
'request_course_creator_url'
:
reverse
(
'request_course_creator'
),
'request_course_creator_url'
:
reverse
(
'
contentstore.views.
request_course_creator'
),
'course_creator_status'
:
_get_course_creator_status
(
request
.
user
),
'course_creator_status'
:
_get_course_creator_status
(
request
.
user
),
'csrf'
:
csrf
(
request
)[
'csrf_token'
]
'csrf'
:
csrf
(
request
)[
'csrf_token'
]
})
})
...
@@ -83,16 +87,42 @@ def request_course_creator(request):
...
@@ -83,16 +87,42 @@ def request_course_creator(request):
@login_required
@login_required
@ensure_csrf_cookie
@ensure_csrf_cookie
def
manage_users
(
request
,
org
,
course
,
name
):
@require_http_methods
((
"GET"
,
"POST"
,
"PUT"
,
"DELETE"
))
'''
def
course_team_handler
(
request
,
tag
=
None
,
course_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
,
email
=
None
):
"""
The restful handler for course team users.
GET
html: return html page for managing course team
json: return json representation of a particular course team member (email is required).
POST or PUT
json: modify the permissions for a particular course team member (email is required, as well as role in the payload).
DELETE:
json: remove a particular course team member from the course team (email is required).
"""
location
=
BlockUsageLocator
(
course_id
=
course_id
,
branch
=
branch
,
version_guid
=
version_guid
,
usage_id
=
block
)
if
not
has_access
(
request
.
user
,
location
):
raise
PermissionDenied
()
if
'application/json'
in
request
.
META
.
get
(
'HTTP_ACCEPT'
,
'application/json'
):
return
_course_team_user
(
request
,
location
,
email
)
elif
request
.
method
==
'GET'
:
# assume html
return
_manage_users
(
request
,
location
)
else
:
return
HttpResponseNotFound
()
def
_manage_users
(
request
,
location
):
"""
This view will return all CMS users who are editors for the specified course
This view will return all CMS users who are editors for the specified course
'''
"""
location
=
Location
(
'i4x'
,
org
,
course
,
'course'
,
name
)
old_location
=
loc_mapper
()
.
translate_locator_to_location
(
location
)
# check that logged in user has permissions to this item
# check that logged in user has permissions to this item
if
not
has_access
(
request
.
user
,
location
,
role
=
INSTRUCTOR_ROLE_NAME
)
and
not
has_access
(
request
.
user
,
location
,
role
=
STAFF_ROLE_NAME
):
if
not
has_access
(
request
.
user
,
location
,
role
=
INSTRUCTOR_ROLE_NAME
)
and
not
has_access
(
request
.
user
,
location
,
role
=
STAFF_ROLE_NAME
):
raise
PermissionDenied
()
raise
PermissionDenied
()
course_module
=
modulestore
()
.
get_item
(
location
)
course_module
=
modulestore
()
.
get_item
(
old_
location
)
staff_groupname
=
get_course_groupname_for_role
(
location
,
"staff"
)
staff_groupname
=
get_course_groupname_for_role
(
location
,
"staff"
)
staff_group
,
__
=
Group
.
objects
.
get_or_create
(
name
=
staff_groupname
)
staff_group
,
__
=
Group
.
objects
.
get_or_create
(
name
=
staff_groupname
)
...
@@ -107,11 +137,8 @@ def manage_users(request, org, course, name):
...
@@ -107,11 +137,8 @@ def manage_users(request, org, course, name):
})
})
@login_required
def
_course_team_user
(
request
,
location
,
email
):
@ensure_csrf_cookie
old_location
=
loc_mapper
()
.
translate_locator_to_location
(
location
)
@require_http_methods
((
"GET"
,
"POST"
,
"PUT"
,
"DELETE"
))
def
course_team_user
(
request
,
org
,
course
,
name
,
email
):
location
=
Location
(
'i4x'
,
org
,
course
,
'course'
,
name
)
# check that logged in user has permissions to this item
# check that logged in user has permissions to this item
if
has_access
(
request
.
user
,
location
,
role
=
INSTRUCTOR_ROLE_NAME
):
if
has_access
(
request
.
user
,
location
,
role
=
INSTRUCTOR_ROLE_NAME
):
# instructors have full permissions
# instructors have full permissions
...
@@ -146,7 +173,7 @@ def course_team_user(request, org, course, name, email):
...
@@ -146,7 +173,7 @@ def course_team_user(request, org, course, name, email):
# what's the highest role that this user has?
# what's the highest role that this user has?
groupnames
=
set
(
g
.
name
for
g
in
user
.
groups
.
all
())
groupnames
=
set
(
g
.
name
for
g
in
user
.
groups
.
all
())
for
role
in
roles
:
for
role
in
roles
:
role_groupname
=
get_course_groupname_for_role
(
location
,
role
)
role_groupname
=
get_course_groupname_for_role
(
old_
location
,
role
)
if
role_groupname
in
groupnames
:
if
role_groupname
in
groupnames
:
msg
[
"role"
]
=
role
msg
[
"role"
]
=
role
break
break
...
@@ -162,7 +189,7 @@ def course_team_user(request, org, course, name, email):
...
@@ -162,7 +189,7 @@ def course_team_user(request, org, course, name, email):
# make sure that the role groups exist
# make sure that the role groups exist
groups
=
{}
groups
=
{}
for
role
in
roles
:
for
role
in
roles
:
groupname
=
get_course_groupname_for_role
(
location
,
role
)
groupname
=
get_course_groupname_for_role
(
old_
location
,
role
)
group
,
__
=
Group
.
objects
.
get_or_create
(
name
=
groupname
)
group
,
__
=
Group
.
objects
.
get_or_create
(
name
=
groupname
)
groups
[
role
]
=
group
groups
[
role
]
=
group
...
@@ -208,7 +235,7 @@ def course_team_user(request, org, course, name, email):
...
@@ -208,7 +235,7 @@ def course_team_user(request, org, course, name, email):
user
.
groups
.
add
(
groups
[
"instructor"
])
user
.
groups
.
add
(
groups
[
"instructor"
])
user
.
save
()
user
.
save
()
# auto-enroll the course creator in the course so that "View Live" will work.
# auto-enroll the course creator in the course so that "View Live" will work.
CourseEnrollment
.
enroll
(
user
,
location
.
course_id
)
CourseEnrollment
.
enroll
(
user
,
old_
location
.
course_id
)
elif
role
==
"staff"
:
elif
role
==
"staff"
:
# if we're trying to downgrade a user from "instructor" to "staff",
# if we're trying to downgrade a user from "instructor" to "staff",
# make sure we have at least one other instructor in the course team.
# make sure we have at least one other instructor in the course team.
...
@@ -223,7 +250,7 @@ def course_team_user(request, org, course, name, email):
...
@@ -223,7 +250,7 @@ def course_team_user(request, org, course, name, email):
user
.
groups
.
add
(
groups
[
"staff"
])
user
.
groups
.
add
(
groups
[
"staff"
])
user
.
save
()
user
.
save
()
# auto-enroll the course creator in the course so that "View Live" will work.
# auto-enroll the course creator in the course so that "View Live" will work.
CourseEnrollment
.
enroll
(
user
,
location
.
course_id
)
CourseEnrollment
.
enroll
(
user
,
old_
location
.
course_id
)
return
JsonResponse
()
return
JsonResponse
()
...
...
cms/templates/manage_users.html
View file @
355ebd62
...
@@ -2,12 +2,13 @@
...
@@ -2,12 +2,13 @@
<
%!
from
django
.
core
.
urlresolvers
import
reverse
%
>
<
%!
from
django
.
core
.
urlresolvers
import
reverse
%
>
<
%!
from
auth
.
authz
import
is_user_in_course_group_role
%
>
<
%!
from
auth
.
authz
import
is_user_in_course_group_role
%
>
<
%!
import
json
%
>
<
%!
import
json
%
>
<
%!
from
xmodule
.
modulestore
.
django
import
loc_mapper
%
>
<
%
inherit
file=
"base.html"
/>
<
%
inherit
file=
"base.html"
/>
<
%
block
name=
"title"
>
${_("Course Team Settings")}
</
%
block>
<
%
block
name=
"title"
>
${_("Course Team Settings")}
</
%
block>
<
%
block
name=
"bodyclass"
>
is-signedin course users view-team
</
%
block>
<
%
block
name=
"bodyclass"
>
is-signedin course users view-team
</
%
block>
<
%
block
name=
"content"
>
<
%
block
name=
"content"
>
<div
class=
"wrapper-mast wrapper"
>
<div
class=
"wrapper-mast wrapper"
>
<header
class=
"mast has-actions has-subtitle"
>
<header
class=
"mast has-actions has-subtitle"
>
<h1
class=
"page-header"
>
<h1
class=
"page-header"
>
...
@@ -59,15 +60,10 @@
...
@@ -59,15 +60,10 @@
%endif
%endif
<ol
class=
"user-list"
>
<ol
class=
"user-list"
>
<
%
new_location =
loc_mapper().translate_location(context_course.location.course_id,
context_course
.
location
,
False
,
True
)
%
>
% for user in staff:
% for user in staff:
<
%
api_url =
reverse('course_team_user',
kwargs=
dict(
org=
context_course.location.org,
<li
class=
"user-item"
data-email=
"${user.email}"
data-url=
"${new_location.url_reverse('course_team/', user.email) }"
>
course=
context_course.location.course,
name=
context_course.location.name,
email=
user.email,
))
%
>
<li
class=
"user-item"
data-email=
"${user.email}"
data-url=
"${api_url}"
>
<
%
is_instuctor =
is_user_in_course_group_role(user,
context_course
.
location
,
'
instructor
',
check_staff=
False)
%
>
<
%
is_instuctor =
is_user_in_course_group_role(user,
context_course
.
location
,
'
instructor
',
check_staff=
False)
%
>
% if is_instuctor:
% if is_instuctor:
...
@@ -166,13 +162,11 @@ require(["jquery", "underscore", "gettext", "js/views/feedback_prompt"],
...
@@ -166,13 +162,11 @@ require(["jquery", "underscore", "gettext", "js/views/feedback_prompt"],
function
(
$
,
_
,
gettext
,
PromptView
)
{
function
(
$
,
_
,
gettext
,
PromptView
)
{
var
staffEmails
=
$
{
json
.
dumps
([
user
.
email
for
user
in
staff
])};
var
staffEmails
=
$
{
json
.
dumps
([
user
.
email
for
user
in
staff
])};
var
tplUserURL
=
"${reverse('course_team_user', kwargs=dict(
var
tplUserURL
=
"${loc_mapper().
\
org=context_course.location.org,
translate_location(context_course.location.course_id, context_course.location, False, True).
\
course=context_course.location.course,
url_reverse('course_team/', "
@@
EMAIL
@@
")}"
;
name=context_course.location.name,
email="
@@
EMAIL
@@
",
var
unknownErrorMessage
=
gettext
(
"Unknown"
);
))}"
;
var
unknownErrorMessage
=
gettext
(
"Unknown"
)
$
(
document
).
ready
(
function
()
{
$
(
document
).
ready
(
function
()
{
var
$createUserForm
=
$
(
'#create-user-form'
);
var
$createUserForm
=
$
(
'#create-user-form'
);
...
...
cms/templates/settings.html
View file @
355ebd62
...
@@ -284,13 +284,18 @@ require(["domReady!", "jquery", "js/models/settings/course_details", "js/views/s
...
@@ -284,13 +284,18 @@ require(["domReady!", "jquery", "js/models/settings/course_details", "js/views/s
<div
class=
"bit"
>
<div
class=
"bit"
>
% if context_course:
% if context_course:
<
%
ctx_loc =
context_course.location
%
>
<
%!
from
xmodule
.
modulestore
.
django
import
loc_mapper
%
>
<
%!
from
django
.
core
.
urlresolvers
import
reverse
%
>
<
%!
from
django
.
core
.
urlresolvers
import
reverse
%
>
<
%
ctx_loc =
context_course.location
location =
loc_mapper().translate_location(ctx_loc.course_id,
ctx_loc
,
False
,
True
)
course_team_url =
location.url_reverse('course_team/',
'')
%
>
<h3
class=
"title-3"
>
${_("Other Course Settings")}
</h3>
<h3
class=
"title-3"
>
${_("Other Course Settings")}
</h3>
<nav
class=
"nav-related"
>
<nav
class=
"nav-related"
>
<ul>
<ul>
<li
class=
"nav-item"
><a
href=
"${reverse('contentstore.views.course_config_graders_page', kwargs={'org' : ctx_loc.org, 'course' : ctx_loc.course, 'name': ctx_loc.name})}"
>
${_("Grading")}
</a></li>
<li
class=
"nav-item"
><a
href=
"${reverse('contentstore.views.course_config_graders_page', kwargs={'org' : ctx_loc.org, 'course' : ctx_loc.course, 'name': ctx_loc.name})}"
>
${_("Grading")}
</a></li>
<li
class=
"nav-item"
><a
href=
"${
reverse('manage_users', kwargs=dict(org=ctx_loc.org, course=ctx_loc.course, name=ctx_loc.name))
}"
>
${_("Course Team")}
</a></li>
<li
class=
"nav-item"
><a
href=
"${
course_team_url
}"
>
${_("Course Team")}
</a></li>
<li
class=
"nav-item"
><a
href=
"${reverse('course_advanced_settings', kwargs={'org' : ctx_loc.org, 'course' : ctx_loc.course, 'name': ctx_loc.name})}"
>
${_("Advanced Settings")}
</a></li>
<li
class=
"nav-item"
><a
href=
"${reverse('course_advanced_settings', kwargs={'org' : ctx_loc.org, 'course' : ctx_loc.course, 'name': ctx_loc.name})}"
>
${_("Advanced Settings")}
</a></li>
</ul>
</ul>
</nav>
</nav>
...
...
cms/templates/settings_advanced.html
View file @
355ebd62
...
@@ -86,14 +86,19 @@ require(["domReady!", "jquery", "js/models/settings/advanced", "js/views/setting
...
@@ -86,14 +86,19 @@ require(["domReady!", "jquery", "js/models/settings/advanced", "js/views/setting
<div
class=
"bit"
>
<div
class=
"bit"
>
% if context_course:
% if context_course:
<
%
ctx_loc =
context_course.location
%
>
<
%!
from
xmodule
.
modulestore
.
django
import
loc_mapper
%
>
<
%!
from
django
.
core
.
urlresolvers
import
reverse
%
>
<
%!
from
django
.
core
.
urlresolvers
import
reverse
%
>
<
%
ctx_loc =
context_course.location
location =
loc_mapper().translate_location(ctx_loc.course_id,
ctx_loc
,
False
,
True
)
course_team_url =
location.url_reverse('course_team/',
'')
%
>
<h3
class=
"title-3"
>
${_("Other Course Settings")}
</h3>
<h3
class=
"title-3"
>
${_("Other Course Settings")}
</h3>
<nav
class=
"nav-related"
>
<nav
class=
"nav-related"
>
<ul>
<ul>
<li
class=
"nav-item"
><a
href=
"${reverse('contentstore.views.get_course_settings', kwargs=dict(org=ctx_loc.org, course=ctx_loc.course, name=ctx_loc.name))}"
>
${_("Details
&
Schedule")}
</a></li>
<li
class=
"nav-item"
><a
href=
"${reverse('contentstore.views.get_course_settings', kwargs=dict(org=ctx_loc.org, course=ctx_loc.course, name=ctx_loc.name))}"
>
${_("Details
&
Schedule")}
</a></li>
<li
class=
"nav-item"
><a
href=
"${reverse('contentstore.views.course_config_graders_page', kwargs={'org' : ctx_loc.org, 'course' : ctx_loc.course, 'name': ctx_loc.name})}"
>
${_("Grading")}
</a></li>
<li
class=
"nav-item"
><a
href=
"${reverse('contentstore.views.course_config_graders_page', kwargs={'org' : ctx_loc.org, 'course' : ctx_loc.course, 'name': ctx_loc.name})}"
>
${_("Grading")}
</a></li>
<li
class=
"nav-item"
><a
href=
"${
reverse('manage_users', kwargs={'org' : ctx_loc.org, 'course' : ctx_loc.course, 'name': ctx_loc.name})
}"
>
${_("Course Team")}
</a></li>
<li
class=
"nav-item"
><a
href=
"${
course_team_url
}"
>
${_("Course Team")}
</a></li>
</ul>
</ul>
</nav>
</nav>
% endif
% endif
...
...
cms/templates/settings_graders.html
View file @
355ebd62
...
@@ -132,13 +132,18 @@ require(["domReady!", "jquery", "js/views/settings/grading", "js/models/settings
...
@@ -132,13 +132,18 @@ require(["domReady!", "jquery", "js/views/settings/grading", "js/models/settings
<div
class=
"bit"
>
<div
class=
"bit"
>
% if context_course:
% if context_course:
<
%
ctx_loc =
context_course.location
%
>
<
%!
from
xmodule
.
modulestore
.
django
import
loc_mapper
%
>
<
%!
from
django
.
core
.
urlresolvers
import
reverse
%
>
<
%!
from
django
.
core
.
urlresolvers
import
reverse
%
>
<
%
ctx_loc =
context_course.location
location =
loc_mapper().translate_location(ctx_loc.course_id,
ctx_loc
,
False
,
True
)
course_team_url =
location.url_reverse('course_team/',
'')
%
>
<h3
class=
"title-3"
>
${_("Other Course Settings")}
</h3>
<h3
class=
"title-3"
>
${_("Other Course Settings")}
</h3>
<nav
class=
"nav-related"
>
<nav
class=
"nav-related"
>
<ul>
<ul>
<li
class=
"nav-item"
><a
href=
"${reverse('contentstore.views.get_course_settings', kwargs=dict(org=ctx_loc.org, course=ctx_loc.course, name=ctx_loc.name))}"
>
${_("Details
&
Schedule")}
</a></li>
<li
class=
"nav-item"
><a
href=
"${reverse('contentstore.views.get_course_settings', kwargs=dict(org=ctx_loc.org, course=ctx_loc.course, name=ctx_loc.name))}"
>
${_("Details
&
Schedule")}
</a></li>
<li
class=
"nav-item"
><a
href=
"${
reverse('manage_users', kwargs={'org' : ctx_loc.org, 'course' : ctx_loc.course, 'name': ctx_loc.name})
}"
>
${_("Course Team")}
</a></li>
<li
class=
"nav-item"
><a
href=
"${
course_team_url
}"
>
${_("Course Team")}
</a></li>
<li
class=
"nav-item"
><a
href=
"${reverse('course_advanced_settings', kwargs={'org' : ctx_loc.org, 'course' : ctx_loc.course, 'name': ctx_loc.name})}"
>
${_("Advanced Settings")}
</a></li>
<li
class=
"nav-item"
><a
href=
"${reverse('course_advanced_settings', kwargs={'org' : ctx_loc.org, 'course' : ctx_loc.course, 'name': ctx_loc.name})}"
>
${_("Advanced Settings")}
</a></li>
</ul>
</ul>
</nav>
</nav>
...
...
cms/templates/widgets/header.html
View file @
355ebd62
...
@@ -18,6 +18,7 @@
...
@@ -18,6 +18,7 @@
location =
loc_mapper().translate_location(ctx_loc.course_id,
ctx_loc
,
False
,
True
)
location =
loc_mapper().translate_location(ctx_loc.course_id,
ctx_loc
,
False
,
True
)
index_url =
location.url_reverse('course/',
'')
index_url =
location.url_reverse('course/',
'')
checklists_url =
location.url_reverse('checklists/',
'')
checklists_url =
location.url_reverse('checklists/',
'')
course_team_url =
location.url_reverse('course_team/',
'')
%
>
%
>
<h2
class=
"info-course"
>
<h2
class=
"info-course"
>
<span
class=
"sr"
>
${_("Current Course:")}
</span>
<span
class=
"sr"
>
${_("Current Course:")}
</span>
...
@@ -69,7 +70,7 @@
...
@@ -69,7 +70,7 @@
<a
href=
"${reverse('contentstore.views.course_config_graders_page', kwargs={'org' : ctx_loc.org, 'course' : ctx_loc.course, 'name': ctx_loc.name})}"
>
${_("Grading")}
</a>
<a
href=
"${reverse('contentstore.views.course_config_graders_page', kwargs={'org' : ctx_loc.org, 'course' : ctx_loc.course, 'name': ctx_loc.name})}"
>
${_("Grading")}
</a>
</li>
</li>
<li
class=
"nav-item nav-course-settings-team"
>
<li
class=
"nav-item nav-course-settings-team"
>
<a
href=
"${
reverse('manage_users', kwargs=dict(org=ctx_loc.org, course=ctx_loc.course, name=ctx_loc.name))
}"
>
${_("Course Team")}
</a>
<a
href=
"${
course_team_url
}"
>
${_("Course Team")}
</a>
</li>
</li>
<li
class=
"nav-item nav-course-settings-advanced"
>
<li
class=
"nav-item nav-course-settings-advanced"
>
<a
href=
"${reverse('course_advanced_settings', kwargs={'org' : ctx_loc.org, 'course' : ctx_loc.course, 'name': ctx_loc.name})}"
>
${_("Advanced Settings")}
</a>
<a
href=
"${reverse('course_advanced_settings', kwargs={'org' : ctx_loc.org, 'course' : ctx_loc.course, 'name': ctx_loc.name})}"
>
${_("Advanced Settings")}
</a>
...
...
cms/urls.py
View file @
355ebd62
...
@@ -13,8 +13,6 @@ admin.autodiscover()
...
@@ -13,8 +13,6 @@ admin.autodiscover()
urlpatterns
=
patterns
(
''
,
# nopep8
urlpatterns
=
patterns
(
''
,
# nopep8
url
(
r'^$'
,
'contentstore.views.howitworks'
,
name
=
'homepage'
),
url
(
r'^$'
,
'contentstore.views.howitworks'
,
name
=
'homepage'
),
url
(
r'^listing'
,
'contentstore.views.index'
,
name
=
'index'
),
url
(
r'^request_course_creator$'
,
'contentstore.views.request_course_creator'
,
name
=
'request_course_creator'
),
url
(
r'^edit/(?P<location>.*?)$'
,
'contentstore.views.edit_unit'
,
name
=
'edit_unit'
),
url
(
r'^edit/(?P<location>.*?)$'
,
'contentstore.views.edit_unit'
,
name
=
'edit_unit'
),
url
(
r'^subsection/(?P<location>.*?)$'
,
'contentstore.views.edit_subsection'
,
name
=
'edit_subsection'
),
url
(
r'^subsection/(?P<location>.*?)$'
,
'contentstore.views.edit_subsection'
,
name
=
'edit_subsection'
),
url
(
r'^preview_component/(?P<location>.*?)$'
,
'contentstore.views.preview_component'
,
name
=
'preview_component'
),
url
(
r'^preview_component/(?P<location>.*?)$'
,
'contentstore.views.preview_component'
,
name
=
'preview_component'
),
...
@@ -51,12 +49,6 @@ urlpatterns = patterns('', # nopep8
...
@@ -51,12 +49,6 @@ urlpatterns = patterns('', # nopep8
url
(
r'^(?P<org>[^/]+)/(?P<course>[^/]+)/course/(?P<coursename>[^/]+)/upload_asset$'
,
url
(
r'^(?P<org>[^/]+)/(?P<course>[^/]+)/course/(?P<coursename>[^/]+)/upload_asset$'
,
'contentstore.views.upload_asset'
,
name
=
'upload_asset'
),
'contentstore.views.upload_asset'
,
name
=
'upload_asset'
),
url
(
r'^(?P<org>[^/]+)/(?P<course>[^/]+)/team/(?P<name>[^/]+)$'
,
'contentstore.views.manage_users'
,
name
=
'manage_users'
),
url
(
r'^(?P<org>[^/]+)/(?P<course>[^/]+)/team/(?P<name>[^/]+)/(?P<email>[^/]+)$'
,
'contentstore.views.course_team_user'
,
name
=
'course_team_user'
),
url
(
r'^(?P<org>[^/]+)/(?P<course>[^/]+)/info/(?P<name>[^/]+)$'
,
url
(
r'^(?P<org>[^/]+)/(?P<course>[^/]+)/info/(?P<name>[^/]+)$'
,
'contentstore.views.course_info'
,
name
=
'course_info'
),
'contentstore.views.course_info'
,
name
=
'course_info'
),
url
(
r'^(?P<org>[^/]+)/(?P<course>[^/]+)/course_info/updates/(?P<provided_id>.*)$'
,
url
(
r'^(?P<org>[^/]+)/(?P<course>[^/]+)/course_info/updates/(?P<provided_id>.*)$'
,
...
@@ -130,17 +122,18 @@ urlpatterns += patterns(
...
@@ -130,17 +122,18 @@ urlpatterns += patterns(
url
(
r'^login_post$'
,
'student.views.login_user'
,
name
=
'login_post'
),
url
(
r'^login_post$'
,
'student.views.login_user'
,
name
=
'login_post'
),
url
(
r'^logout$'
,
'student.views.logout_user'
,
name
=
'logout'
),
url
(
r'^logout$'
,
'student.views.logout_user'
,
name
=
'logout'
),
)
)
# restful api
# restful api
urlpatterns
+=
patterns
(
urlpatterns
+=
patterns
(
'contentstore.views'
,
'contentstore.views'
,
url
(
r'^course$'
,
'index'
),
url
(
r'^course$'
,
'index'
,
name
=
'index'
),
url
(
r'^request_course_creator$'
,
'request_course_creator'
),
# (?ix) == ignore case and verbose (multiline regex)
# (?ix) == ignore case and verbose (multiline regex)
url
(
r'(?ix)^course/{}$'
.
format
(
parsers
.
URL_RE_SOURCE
),
'course_handler'
),
url
(
r'(?ix)^course/{}$'
.
format
(
parsers
.
URL_RE_SOURCE
),
'course_handler'
),
url
(
r'(?ix)^checklists/{}(/)?(?P<checklist_index>\d+)?$'
.
format
(
parsers
.
URL_RE_SOURCE
),
'checklists_handler'
),
url
(
r'(?ix)^checklists/{}(/)?(?P<checklist_index>\d+)?$'
.
format
(
parsers
.
URL_RE_SOURCE
),
'checklists_handler'
),
url
(
r'(?ix)^course_team/{}(/)?(?P<email>.+)?$'
.
format
(
parsers
.
URL_RE_SOURCE
),
'course_team_handler'
),
url
(
r'(?ix)^orphan/{}$'
.
format
(
parsers
.
URL_RE_SOURCE
),
'orphan'
)
url
(
r'(?ix)^orphan/{}$'
.
format
(
parsers
.
URL_RE_SOURCE
),
'orphan'
)
)
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment