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
1c47573b
Commit
1c47573b
authored
Mar 29, 2013
by
chrisndodge
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1669 from MITx/fix/vik/add-oe-tab
Fix/vik/add oe tab
parents
c655c814
033f5ce7
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
85 additions
and
9 deletions
+85
-9
cms/djangoapps/contentstore/utils.py
+35
-0
cms/djangoapps/contentstore/views.py
+41
-6
cms/djangoapps/models/settings/course_metadata.py
+9
-3
No files found.
cms/djangoapps/contentstore/utils.py
View file @
1c47573b
...
...
@@ -4,9 +4,12 @@ from xmodule.modulestore import Location
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.exceptions
import
ItemNotFoundError
from
django.core.urlresolvers
import
reverse
import
copy
DIRECT_ONLY_CATEGORIES
=
[
'course'
,
'chapter'
,
'sequential'
,
'about'
,
'static_tab'
,
'course_info'
]
#In order to instantiate an open ended tab automatically, need to have this data
OPEN_ENDED_PANEL
=
{
"name"
:
"Open Ended Panel"
,
"type"
:
"open_ended"
}
def
get_modulestore
(
location
):
"""
...
...
@@ -192,3 +195,35 @@ class CoursePageNames:
SettingsGrading
=
"settings_grading"
CourseOutline
=
"course_index"
Checklists
=
"checklists"
def
add_open_ended_panel_tab
(
course
):
"""
Used to add the open ended panel tab to a course if it does not exist.
@param course: A course object from the modulestore.
@return: Boolean indicating whether or not a tab was added and a list of tabs for the course.
"""
#Copy course tabs
course_tabs
=
copy
.
copy
(
course
.
tabs
)
changed
=
False
#Check to see if open ended panel is defined in the course
if
OPEN_ENDED_PANEL
not
in
course_tabs
:
#Add panel to the tabs if it is not defined
course_tabs
.
append
(
OPEN_ENDED_PANEL
)
changed
=
True
return
changed
,
course_tabs
def
remove_open_ended_panel_tab
(
course
):
"""
Used to remove the open ended panel tab from a course if it exists.
@param course: A course object from the modulestore.
@return: Boolean indicating whether or not a tab was added and a list of tabs for the course.
"""
#Copy course tabs
course_tabs
=
copy
.
copy
(
course
.
tabs
)
changed
=
False
#Check to see if open ended panel is defined in the course
if
OPEN_ENDED_PANEL
in
course_tabs
:
#Add panel to the tabs if it is not defined
course_tabs
=
[
ct
for
ct
in
course_tabs
if
ct
!=
OPEN_ENDED_PANEL
]
changed
=
True
return
changed
,
course_tabs
cms/djangoapps/contentstore/views.py
View file @
1c47573b
...
...
@@ -52,7 +52,8 @@ from auth.authz import is_user_in_course_group_role, get_users_in_course_group_b
from
auth.authz
import
get_user_by_email
,
add_user_to_course_group
,
remove_user_from_course_group
from
auth.authz
import
INSTRUCTOR_ROLE_NAME
,
STAFF_ROLE_NAME
,
create_all_course_groups
from
.utils
import
get_course_location_for_item
,
get_lms_link_for_item
,
compute_unit_state
,
\
get_date_display
,
UnitState
,
get_course_for_item
,
get_url_reverse
get_date_display
,
UnitState
,
get_course_for_item
,
get_url_reverse
,
add_open_ended_panel_tab
,
\
remove_open_ended_panel_tab
from
xmodule.modulestore.xml_importer
import
import_from_xml
from
contentstore.course_info_model
import
get_course_updates
,
\
...
...
@@ -73,7 +74,8 @@ log = logging.getLogger(__name__)
COMPONENT_TYPES
=
[
'customtag'
,
'discussion'
,
'html'
,
'problem'
,
'video'
]
ADVANCED_COMPONENT_TYPES
=
[
'annotatable'
,
'combinedopenended'
,
'peergrading'
]
OPEN_ENDED_COMPONENT_TYPES
=
[
"combinedopenended"
,
"peergrading"
]
ADVANCED_COMPONENT_TYPES
=
[
'annotatable'
]
+
OPEN_ENDED_COMPONENT_TYPES
ADVANCED_COMPONENT_CATEGORY
=
'advanced'
ADVANCED_COMPONENT_POLICY_KEY
=
'advanced_modules'
...
...
@@ -1262,15 +1264,48 @@ def course_advanced_updates(request, org, course, name):
location
=
get_location_and_verify_access
(
request
,
org
,
course
,
name
)
real_method
=
get_request_method
(
request
)
if
real_method
==
'GET'
:
return
HttpResponse
(
json
.
dumps
(
CourseMetadata
.
fetch
(
location
)),
mimetype
=
"application/json"
)
elif
real_method
==
'DELETE'
:
return
HttpResponse
(
json
.
dumps
(
CourseMetadata
.
delete_key
(
location
,
json
.
loads
(
request
.
body
))),
mimetype
=
"application/json"
)
return
HttpResponse
(
json
.
dumps
(
CourseMetadata
.
delete_key
(
location
,
json
.
loads
(
request
.
body
))),
mimetype
=
"application/json"
)
elif
real_method
==
'POST'
or
real_method
==
'PUT'
:
# NOTE: request.POST is messed up because expect_json cloned_request.POST.copy() is creating a defective entry w/ the whole payload as the key
return
HttpResponse
(
json
.
dumps
(
CourseMetadata
.
update_from_json
(
location
,
json
.
loads
(
request
.
body
))),
mimetype
=
"application/json"
)
request_body
=
json
.
loads
(
request
.
body
)
#Whether or not to filter the tabs key out of the settings metadata
filter_tabs
=
True
#Check to see if the user instantiated any advanced components. This is a hack to add the open ended panel tab
#to a course automatically if the user has indicated that they want to edit the combinedopenended or peergrading
#module, and to remove it if they have removed the open ended elements.
if
ADVANCED_COMPONENT_POLICY_KEY
in
request_body
:
#Check to see if the user instantiated any open ended components
found_oe_type
=
False
#Get the course so that we can scrape current tabs
course_module
=
modulestore
()
.
get_item
(
location
)
for
oe_type
in
OPEN_ENDED_COMPONENT_TYPES
:
if
oe_type
in
request_body
[
ADVANCED_COMPONENT_POLICY_KEY
]:
#Add an open ended tab to the course if needed
changed
,
new_tabs
=
add_open_ended_panel_tab
(
course_module
)
#If a tab has been added to the course, then send the metadata along to CourseMetadata.update_from_json
if
changed
:
request_body
.
update
({
'tabs'
:
new_tabs
})
#Indicate that tabs should not be filtered out of the metadata
filter_tabs
=
False
#Set this flag to avoid the open ended tab removal code below.
found_oe_type
=
True
break
#If we did not find an open ended module type in the advanced settings,
# we may need to remove the open ended tab from the course.
if
not
found_oe_type
:
#Remove open ended tab to the course if needed
changed
,
new_tabs
=
remove_open_ended_panel_tab
(
course_module
)
if
changed
:
request_body
.
update
({
'tabs'
:
new_tabs
})
#Indicate that tabs should not be filtered out of the metadata
filter_tabs
=
False
response_json
=
json
.
dumps
(
CourseMetadata
.
update_from_json
(
location
,
request_body
,
filter_tabs
=
filter_tabs
))
return
HttpResponse
(
response_json
,
mimetype
=
"application/json"
)
@ensure_csrf_cookie
@login_required
...
...
cms/djangoapps/models/settings/course_metadata.py
View file @
1c47573b
...
...
@@ -4,7 +4,7 @@ from xmodule.x_module import XModuleDescriptor
from
xmodule.modulestore.inheritance
import
own_metadata
from
xblock.core
import
Scope
from
xmodule.course_module
import
CourseDescriptor
import
copy
class
CourseMetadata
(
object
):
'''
...
...
@@ -39,7 +39,7 @@ class CourseMetadata(object):
return
course
@classmethod
def
update_from_json
(
cls
,
course_location
,
jsondict
):
def
update_from_json
(
cls
,
course_location
,
jsondict
,
filter_tabs
=
True
):
"""
Decode the json into CourseMetadata and save any changed attrs to the db.
...
...
@@ -48,10 +48,16 @@ class CourseMetadata(object):
descriptor
=
get_modulestore
(
course_location
)
.
get_item
(
course_location
)
dirty
=
False
#Copy the filtered list to avoid permanently changing the class attribute
filtered_list
=
copy
.
copy
(
cls
.
FILTERED_LIST
)
#Don't filter on the tab attribute if filter_tabs is False
if
not
filter_tabs
:
filtered_list
.
remove
(
"tabs"
)
for
k
,
v
in
jsondict
.
iteritems
():
# should it be an error if one of the filtered list items is in the payload?
if
k
in
cls
.
FILTERED_LIST
:
if
k
in
filtered_list
:
continue
if
hasattr
(
descriptor
,
k
)
and
getattr
(
descriptor
,
k
)
!=
v
:
...
...
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