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
...
@@ -4,9 +4,12 @@ from xmodule.modulestore import Location
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.exceptions
import
ItemNotFoundError
from
xmodule.modulestore.exceptions
import
ItemNotFoundError
from
django.core.urlresolvers
import
reverse
from
django.core.urlresolvers
import
reverse
import
copy
DIRECT_ONLY_CATEGORIES
=
[
'course'
,
'chapter'
,
'sequential'
,
'about'
,
'static_tab'
,
'course_info'
]
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
):
def
get_modulestore
(
location
):
"""
"""
...
@@ -192,3 +195,35 @@ class CoursePageNames:
...
@@ -192,3 +195,35 @@ class CoursePageNames:
SettingsGrading
=
"settings_grading"
SettingsGrading
=
"settings_grading"
CourseOutline
=
"course_index"
CourseOutline
=
"course_index"
Checklists
=
"checklists"
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
...
@@ -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
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
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
,
\
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
xmodule.modulestore.xml_importer
import
import_from_xml
from
contentstore.course_info_model
import
get_course_updates
,
\
from
contentstore.course_info_model
import
get_course_updates
,
\
...
@@ -73,7 +74,8 @@ log = logging.getLogger(__name__)
...
@@ -73,7 +74,8 @@ log = logging.getLogger(__name__)
COMPONENT_TYPES
=
[
'customtag'
,
'discussion'
,
'html'
,
'problem'
,
'video'
]
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_CATEGORY
=
'advanced'
ADVANCED_COMPONENT_POLICY_KEY
=
'advanced_modules'
ADVANCED_COMPONENT_POLICY_KEY
=
'advanced_modules'
...
@@ -1262,15 +1264,48 @@ def course_advanced_updates(request, org, course, name):
...
@@ -1262,15 +1264,48 @@ def course_advanced_updates(request, org, course, name):
location
=
get_location_and_verify_access
(
request
,
org
,
course
,
name
)
location
=
get_location_and_verify_access
(
request
,
org
,
course
,
name
)
real_method
=
get_request_method
(
request
)
real_method
=
get_request_method
(
request
)
if
real_method
==
'GET'
:
if
real_method
==
'GET'
:
return
HttpResponse
(
json
.
dumps
(
CourseMetadata
.
fetch
(
location
)),
mimetype
=
"application/json"
)
return
HttpResponse
(
json
.
dumps
(
CourseMetadata
.
fetch
(
location
)),
mimetype
=
"application/json"
)
elif
real_method
==
'DELETE'
:
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'
:
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
# 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
@ensure_csrf_cookie
@login_required
@login_required
...
...
cms/djangoapps/models/settings/course_metadata.py
View file @
1c47573b
...
@@ -4,7 +4,7 @@ from xmodule.x_module import XModuleDescriptor
...
@@ -4,7 +4,7 @@ from xmodule.x_module import XModuleDescriptor
from
xmodule.modulestore.inheritance
import
own_metadata
from
xmodule.modulestore.inheritance
import
own_metadata
from
xblock.core
import
Scope
from
xblock.core
import
Scope
from
xmodule.course_module
import
CourseDescriptor
from
xmodule.course_module
import
CourseDescriptor
import
copy
class
CourseMetadata
(
object
):
class
CourseMetadata
(
object
):
'''
'''
...
@@ -39,7 +39,7 @@ class CourseMetadata(object):
...
@@ -39,7 +39,7 @@ class CourseMetadata(object):
return
course
return
course
@classmethod
@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.
Decode the json into CourseMetadata and save any changed attrs to the db.
...
@@ -48,10 +48,16 @@ class CourseMetadata(object):
...
@@ -48,10 +48,16 @@ class CourseMetadata(object):
descriptor
=
get_modulestore
(
course_location
)
.
get_item
(
course_location
)
descriptor
=
get_modulestore
(
course_location
)
.
get_item
(
course_location
)
dirty
=
False
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
():
for
k
,
v
in
jsondict
.
iteritems
():
# should it be an error if one of the filtered list items is in the payload?
# 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
continue
if
hasattr
(
descriptor
,
k
)
and
getattr
(
descriptor
,
k
)
!=
v
:
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