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
37d594ce
Commit
37d594ce
authored
May 03, 2013
by
cahrens
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Get rid of non-editable scope.
parent
0a1902e7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
92 additions
and
65 deletions
+92
-65
common/lib/xmodule/xmodule/capa_module.py
+13
-5
common/lib/xmodule/xmodule/discussion_module.py
+10
-4
common/lib/xmodule/xmodule/fields.py
+1
-8
common/lib/xmodule/xmodule/mako_module.py
+0
-33
common/lib/xmodule/xmodule/tests/test_xml_module.py
+18
-12
common/lib/xmodule/xmodule/x_module.py
+42
-0
common/lib/xmodule/xmodule/xml_module.py
+8
-3
No files found.
common/lib/xmodule/xmodule/capa_module.py
View file @
37d594ce
...
...
@@ -17,7 +17,7 @@ from xmodule.x_module import XModule
from
xmodule.raw_module
import
RawDescriptor
from
xmodule.exceptions
import
NotFoundError
,
ProcessingError
from
xblock.core
import
Scope
,
String
,
Boolean
,
Object
from
.fields
import
Timedelta
,
Date
,
StringyInteger
,
StringyFloat
,
NON_EDITABLE_SETTINGS_SCOPE
from
.fields
import
Timedelta
,
Date
,
StringyInteger
,
StringyFloat
from
xmodule.util.date_utils
import
time_to_datetime
log
=
logging
.
getLogger
(
"mitx.courseware"
)
...
...
@@ -63,13 +63,13 @@ class ComplexEncoder(json.JSONEncoder):
class
CapaFields
(
object
):
attempts
=
StringyInteger
(
help
=
"Number of attempts taken by the student on this problem"
,
default
=
0
,
scope
=
Scope
.
user_state
)
max_attempts
=
StringyInteger
(
help
=
"Maximum number of attempts that a student is allowed"
,
scope
=
Scope
.
settings
)
due
=
Date
(
help
=
"Date that this problem is due by"
,
scope
=
NON_EDITABLE_SETTINGS_SCOPE
)
due
=
Date
(
help
=
"Date that this problem is due by"
,
scope
=
Scope
.
settings
)
graceperiod
=
Timedelta
(
help
=
"Amount of time after the due date that submissions will be accepted"
,
scope
=
NON_EDITABLE_SETTINGS_SCOPE
)
scope
=
Scope
.
settings
)
showanswer
=
String
(
help
=
"When to show the problem answer to the student"
,
scope
=
Scope
.
settings
,
default
=
"closed"
,
values
=
[
"answered"
,
"always"
,
"attempted"
,
"closed"
,
"never"
])
force_save_button
=
Boolean
(
help
=
"Whether to force the save button to appear on the page"
,
scope
=
NON_EDITABLE_SETTINGS_SCOPE
,
default
=
False
)
scope
=
Scope
.
settings
,
default
=
False
)
rerandomize
=
Randomization
(
help
=
"When to rerandomize the problem"
,
default
=
"always"
,
scope
=
Scope
.
settings
)
data
=
String
(
help
=
"XML data for the problem"
,
scope
=
Scope
.
content
)
correct_map
=
Object
(
help
=
"Dictionary with the correctness of current student answers"
,
scope
=
Scope
.
user_state
,
default
=
{})
...
...
@@ -78,7 +78,7 @@ class CapaFields(object):
done
=
Boolean
(
help
=
"Whether the student has answered the problem"
,
scope
=
Scope
.
user_state
)
seed
=
StringyInteger
(
help
=
"Random seed for this student"
,
scope
=
Scope
.
user_state
)
weight
=
StringyFloat
(
help
=
"How much to weight this problem by"
,
scope
=
Scope
.
settings
)
markdown
=
String
(
help
=
"Markdown source of this module"
,
scope
=
NON_EDITABLE_SETTINGS_SCOPE
)
markdown
=
String
(
help
=
"Markdown source of this module"
,
scope
=
Scope
.
settings
)
source_code
=
String
(
help
=
"Source code for LaTeX and Word problems. This feature is not well-supported."
,
scope
=
Scope
.
settings
)
...
...
@@ -894,3 +894,10 @@ class CapaDescriptor(CapaFields, RawDescriptor):
'problems/'
+
path
[
8
:],
path
[
8
:],
]
@property
def
non_editable_metadata_fields
(
self
):
non_editable_fields
=
super
(
CapaDescriptor
,
self
)
.
non_editable_metadata_fields
non_editable_fields
.
extend
([
CapaDescriptor
.
due
,
CapaDescriptor
.
graceperiod
,
CapaDescriptor
.
force_save_button
,
CapaDescriptor
.
markdown
])
return
non_editable_fields
\ No newline at end of file
common/lib/xmodule/xmodule/discussion_module.py
View file @
37d594ce
from
pkg_resources
import
resource_string
from
.fields
import
NON_EDITABLE_SETTINGS_SCOPE
from
xmodule.x_module
import
XModule
from
xmodule.raw_module
import
RawDescriptor
from
xmodule.editing_module
import
MetadataOnlyEditingDescriptor
...
...
@@ -8,11 +7,10 @@ from xblock.core import String, Scope
class
DiscussionFields
(
object
):
discussion_id
=
String
(
scope
=
NON_EDITABLE_SETTINGS_SCOPE
)
discussion_id
=
String
(
scope
=
Scope
.
settings
)
discussion_category
=
String
(
scope
=
Scope
.
settings
)
discussion_target
=
String
(
scope
=
Scope
.
settings
)
# We may choose to enable this in the future, but while Kevin is investigating....
sort_key
=
String
(
scope
=
NON_EDITABLE_SETTINGS_SCOPE
)
sort_key
=
String
(
scope
=
Scope
.
settings
)
class
DiscussionModule
(
DiscussionFields
,
XModule
):
...
...
@@ -39,3 +37,10 @@ class DiscussionDescriptor(DiscussionFields, MetadataOnlyEditingDescriptor, RawD
metadata_translations
=
dict
(
RawDescriptor
.
metadata_translations
)
metadata_translations
[
'id'
]
=
'discussion_id'
metadata_translations
[
'for'
]
=
'discussion_target'
@property
def
non_editable_metadata_fields
(
self
):
non_editable_fields
=
super
(
DiscussionDescriptor
,
self
)
.
non_editable_metadata_fields
# We may choose to enable sort_keys in the future, but while Kevin is investigating....
non_editable_fields
.
extend
([
DiscussionDescriptor
.
discussion_id
,
DiscussionDescriptor
.
sort_key
])
return
non_editable_fields
\ No newline at end of file
common/lib/xmodule/xmodule/fields.py
View file @
37d594ce
...
...
@@ -7,18 +7,11 @@ from xblock.core import ModelType
import
datetime
import
dateutil.parser
from
xblock.core
import
Integer
,
Float
,
Boolean
,
Scope
from
xblock.core
import
Integer
,
Float
,
Boolean
log
=
logging
.
getLogger
(
__name__
)
class
NonEditableSettingsScope
(
Scope
):
pass
# Same scope as Settings.scope, but not intended to be edited by users (in Studio).
NON_EDITABLE_SETTINGS_SCOPE
=
NonEditableSettingsScope
(
user
=
Scope
.
settings
.
user
,
block
=
Scope
.
settings
.
block
)
class
Date
(
ModelType
):
'''
Date fields know how to parse and produce json (iso) compatible formats.
...
...
common/lib/xmodule/xmodule/mako_module.py
View file @
37d594ce
from
.x_module
import
XModuleDescriptor
,
DescriptorSystem
from
.fields
import
NonEditableSettingsScope
from
xblock.core
import
Scope
from
xblock.core
import
XBlock
class
MakoDescriptorSystem
(
DescriptorSystem
):
...
...
@@ -43,33 +40,3 @@ class MakoModuleDescriptor(XModuleDescriptor):
return
self
.
system
.
render_template
(
self
.
mako_template
,
self
.
get_context
())
@property
def
editable_metadata_fields
(
self
):
inherited_metadata
=
getattr
(
self
,
'_inherited_metadata'
,
{})
metadata
=
{}
for
field
in
self
.
fields
:
if
field
.
scope
!=
Scope
.
settings
or
isinstance
(
field
.
scope
,
NonEditableSettingsScope
):
continue
# We are not allowing editing of xblock tag and name fields at this time (for any component).
if
field
==
XBlock
.
tags
or
field
==
XBlock
.
name
:
continue
inherited
=
False
default
=
False
value
=
getattr
(
self
,
field
.
name
)
if
field
.
name
in
self
.
_model_data
:
default
=
False
if
field
.
name
in
inherited_metadata
and
self
.
_model_data
.
get
(
field
.
name
)
==
inherited_metadata
.
get
(
field
.
name
):
inherited
=
True
else
:
default
=
True
metadata
[
field
.
name
]
=
{
'field'
:
field
,
'value'
:
value
,
'is_inherited'
:
inherited
,
'is_default'
:
default
}
return
metadata
common/lib/xmodule/xmodule/tests/test_
mako
_module.py
→
common/lib/xmodule/xmodule/tests/test_
xml
_module.py
View file @
37d594ce
from
xmodule.x_module
import
XModuleFields
from
xblock.core
import
Scope
,
String
,
Object
from
xmodule.fields
import
Date
,
StringyInteger
,
NON_EDITABLE_SETTINGS_SCOPE
from
xmodule.
mako_module
import
MakoModule
Descriptor
from
xmodule.fields
import
Date
,
StringyInteger
from
xmodule.
xml_module
import
Xml
Descriptor
import
unittest
from
.
import
test_system
from
mock
import
Mock
class
TestFields
(
object
):
# Will be returned by editable_metadata_fields
because Scope.settings
.
# Will be returned by editable_metadata_fields.
max_attempts
=
StringyInteger
(
scope
=
Scope
.
settings
)
# Will not be returned by editable_metadata_fields because
declared as non-editable Scope.setting
s.
due
=
Date
(
scope
=
NON_EDITABLE_SETTINGS_SCOPE
)
# Will not be returned by editable_metadata_fields because
filtered out by non_editable_metadata_field
s.
due
=
Date
(
scope
=
Scope
.
settings
)
# Will not be returned by editable_metadata_fields because is not Scope.settings.
student_answers
=
Object
(
scope
=
Scope
.
user_state
)
# Will be returned, and can override the inherited value from XModule.
...
...
@@ -21,14 +21,15 @@ class TestFields(object):
class
EditableMetadataFieldsTest
(
unittest
.
TestCase
):
def
test_display_name_field
(
self
):
editable_fields
=
self
.
get_
mako
_editable_fields
({})
editable_fields
=
self
.
get_
xml
_editable_fields
({})
# Tests that the xblock fields (currently tags and name) get filtered out.
self
.
assertEqual
(
1
,
len
(
editable_fields
),
"Expected only 1 editable field for mako descriptor."
)
# Also tests that xml_attributes is filtered out of XmlDescriptor.
self
.
assertEqual
(
1
,
len
(
editable_fields
),
"Expected only 1 editable field for xml descriptor."
)
self
.
assert_display_name_default
(
editable_fields
)
def
test_override_default
(
self
):
# Tests that is_default is correct when a value overrides the default.
editable_fields
=
self
.
get_
mako
_editable_fields
({
'display_name'
:
'foo'
})
editable_fields
=
self
.
get_
xml
_editable_fields
({
'display_name'
:
'foo'
})
display_name
=
editable_fields
[
'display_name'
]
self
.
assertFalse
(
display_name
[
'is_default'
])
self
.
assertEqual
(
'foo'
,
display_name
[
'value'
])
...
...
@@ -47,14 +48,19 @@ class EditableMetadataFieldsTest(unittest.TestCase):
self
.
assert_field_values
(
editable_fields
,
'display_name'
,
XModuleFields
.
display_name
,
False
,
True
,
'inherited'
)
# Start of helper methods
def
get_
mako
_editable_fields
(
self
,
model_data
):
def
get_
xml
_editable_fields
(
self
,
model_data
):
system
=
test_system
()
system
.
render_template
=
Mock
(
return_value
=
"<div>Test Template HTML</div>"
)
return
MakoModule
Descriptor
(
system
=
system
,
location
=
None
,
model_data
=
model_data
)
.
editable_metadata_fields
return
Xml
Descriptor
(
system
=
system
,
location
=
None
,
model_data
=
model_data
)
.
editable_metadata_fields
def
get_module_editable_fields
(
self
,
model_data
):
class
TestModuleDescriptor
(
TestFields
,
MakoModuleDescriptor
):
pass
class
TestModuleDescriptor
(
TestFields
,
XmlDescriptor
):
@property
def
non_editable_metadata_fields
(
self
):
non_editable_fields
=
super
(
TestModuleDescriptor
,
self
)
.
non_editable_metadata_fields
non_editable_fields
.
append
(
TestModuleDescriptor
.
due
)
return
non_editable_fields
system
=
test_system
()
system
.
render_template
=
Mock
(
return_value
=
"<div>Test Template HTML</div>"
)
...
...
common/lib/xmodule/xmodule/x_module.py
View file @
37d594ce
...
...
@@ -606,6 +606,48 @@ class XModuleDescriptor(XModuleFields, HTMLSnippet, ResourceTemplates, XBlock):
model_data
=
self
.
_model_data
,
))
@property
def
non_editable_metadata_fields
(
self
):
"""
Return the list of fields that should not be editable in Studio.
When overriding, be sure to append to the superclasses' list.
"""
# We are not allowing editing of xblock tag and name fields at this time (for any component).
return
[
XBlock
.
tags
,
XBlock
.
name
]
@property
def
editable_metadata_fields
(
self
):
"""
Returns the metadata fields to be edited in Studio. These are fields with scope `Scope.settings`.
Can be limited by extending `non_editable_metadata_fields`.
"""
inherited_metadata
=
getattr
(
self
,
'_inherited_metadata'
,
{})
metadata
=
{}
for
field
in
self
.
fields
:
if
field
.
scope
!=
Scope
.
settings
or
field
in
self
.
non_editable_metadata_fields
:
continue
inherited
=
False
default
=
False
value
=
getattr
(
self
,
field
.
name
)
if
field
.
name
in
self
.
_model_data
:
default
=
False
if
field
.
name
in
inherited_metadata
:
if
self
.
_model_data
.
get
(
field
.
name
)
==
inherited_metadata
.
get
(
field
.
name
):
inherited
=
True
else
:
default
=
True
metadata
[
field
.
name
]
=
{
'field'
:
field
,
'value'
:
value
,
'is_inherited'
:
inherited
,
'is_default'
:
default
}
return
metadata
class
DescriptorSystem
(
object
):
def
__init__
(
self
,
load_item
,
resources_fs
,
error_tracker
,
**
kwargs
):
...
...
common/lib/xmodule/xmodule/xml_module.py
View file @
37d594ce
...
...
@@ -6,11 +6,10 @@ import sys
from
collections
import
namedtuple
from
lxml
import
etree
from
xblock.core
import
Object
from
xblock.core
import
Object
,
Scope
from
xmodule.x_module
import
(
XModuleDescriptor
,
policy_key
)
from
xmodule.modulestore
import
Location
from
xmodule.modulestore.inheritance
import
own_metadata
from
.fields
import
NON_EDITABLE_SETTINGS_SCOPE
log
=
logging
.
getLogger
(
__name__
)
...
...
@@ -86,7 +85,7 @@ class XmlDescriptor(XModuleDescriptor):
"""
xml_attributes
=
Object
(
help
=
"Map of unhandled xml attributes, used only for storage between import and export"
,
default
=
{},
scope
=
NON_EDITABLE_SETTINGS_SCOPE
)
default
=
{},
scope
=
Scope
.
settings
)
# Extension to append to filename paths
filename_extension
=
'xml'
...
...
@@ -420,3 +419,9 @@ class XmlDescriptor(XModuleDescriptor):
"""
raise
NotImplementedError
(
"
%
s does not implement definition_to_xml"
%
self
.
__class__
.
__name__
)
@property
def
non_editable_metadata_fields
(
self
):
non_editable_fields
=
super
(
XmlDescriptor
,
self
)
.
non_editable_metadata_fields
non_editable_fields
.
append
(
XmlDescriptor
.
xml_attributes
)
return
non_editable_fields
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