Commit 8705ff88 by cahrens

Remove system_metadata_fields.

parent cd53dd22
......@@ -75,11 +75,7 @@ def set_module_info(store, location, post_data):
# IMPORTANT NOTE: if the client passed pack 'null' (None) for a piece of metadata that means 'remove it'
for metadata_key, value in posted_metadata.items():
# let's strip out any metadata fields from the postback which have been identified as system metadata
# and therefore should not be user-editable, so we should accept them back from the client
if metadata_key in module.system_metadata_fields:
del posted_metadata[metadata_key]
elif posted_metadata[metadata_key] is None:
if posted_metadata[metadata_key] is None:
# remove both from passed in collection as well as the collection read in from the modulestore
if metadata_key in module._model_data:
del module._model_data[metadata_key]
......
......@@ -687,11 +687,7 @@ def save_item(request):
# IMPORTANT NOTE: if the client passed pack 'null' (None) for a piece of metadata that means 'remove it'
for metadata_key, value in posted_metadata.items():
# let's strip out any metadata fields from the postback which have been identified as system metadata
# and therefore should not be user-editable, so we should accept them back from the client
if metadata_key in existing_item.system_metadata_fields:
del posted_metadata[metadata_key]
elif posted_metadata[metadata_key] is None:
if posted_metadata[metadata_key] is None:
# remove both from passed in collection as well as the collection read in from the modulestore
if metadata_key in existing_item._model_data:
del existing_item._model_data[metadata_key]
......
......@@ -14,13 +14,14 @@ class CourseMetadata(object):
The objects have no predefined attrs but instead are obj encodings of the
editable metadata.
'''
FILTERED_LIST = XModuleDescriptor.system_metadata_fields + ['start',
'end',
'enrollment_start',
'enrollment_end',
'tabs',
'graceperiod',
'checklists']
FILTERED_LIST = ['xml_attributes',
'start',
'end',
'enrollment_start',
'enrollment_end',
'tabs',
'graceperiod',
'checklists']
@classmethod
def fetch(cls, course_location):
......
......@@ -7,10 +7,24 @@
% for field_name, field_value in editable_metadata_fields.items():
<li>
% if field_name == 'source_code':
<a href="#hls-modal-${hlskey}" style="color:yellow;" id="hls-trig-${hlskey}" >Edit High Level Source</a>
% if field_value['is_default'] is False:
<a href="#hls-modal-${hlskey}" style="color:yellow;" id="hls-trig-${hlskey}" >Edit High Level Source</a>
% endif
% else:
<label>${field_name}:</label>
<input type='text' data-metadata-name='${field_name}' value='${field_value}' size='60' />
<label>${field_value['field'].display_name}:</label>
<input type='text' data-metadata-name='${field_value["field"].display_name}' value='${field_value["field"].to_json(field_value["value"])}' size='60' />
% if False:
<label>Help: ${field_value['field'].help}</label>
<label>Type: ${type(field_value['field']).__name__}</label>
<label>Inherited: ${field_value['is_inherited']}</label>
<label>Default: ${field_value['is_default']}</label>
% if field_value['field'].values:
<label>Possible values:</label>
% for value in field_value['field'].values:
<label>${value}</label>
% endfor
% endif
% endif
% endif
</li>
% endfor
......
......@@ -13,7 +13,7 @@ from capa.responsetypes import StudentInputError,\
ResponseError, LoncapaProblemError
from capa.util import convert_files_to_filenames
from .progress import Progress
from xmodule.x_module import XModule
from xmodule.x_module import XModule, XModuleFields
from xmodule.raw_module import RawDescriptor
from xmodule.exceptions import NotFoundError, ProcessingError
from xblock.core import Scope, String, Boolean, Object
......@@ -62,20 +62,26 @@ 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=Scope.settings)
graceperiod = Timedelta(help="Amount of time after the due date that submissions will be accepted", scope=Scope.settings)
showanswer = String(help="When to show the problem answer to the student", scope=Scope.settings, default="closed")
force_save_button = Boolean(help="Whether to force the save button to appear on the page", scope=Scope.settings, default=False)
rerandomize = Randomization(help="When to rerandomize the problem", default="always", scope=Scope.settings)
max_attempts = StringyInteger(display_name="Maximum Allowed Attempts",
help="Maximum number of attempts that a student is allowed", scope=Scope.settings)
due = Date(help="Date that this problem is due by", scope=XModuleFields.nonEditableSettingsScope)
graceperiod = Timedelta(help="Amount of time after the due date that submissions will be accepted",
scope=XModuleFields.nonEditableSettingsScope)
showanswer = String(display_name="Show Answer",
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=XModuleFields.nonEditableSettingsScope, default=False)
rerandomize = Randomization(display_name="Rerandomize", 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={})
input_state = Object(help="Dictionary for maintaining the state of inputtypes", scope=Scope.user_state)
student_answers = Object(help="Dictionary with the current student responses", scope=Scope.user_state)
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=Scope.settings)
weight = StringyFloat(display_name="Problem Weight", help="How much to weight this problem by", scope=Scope.settings)
markdown = String(help="Markdown source of this module", scope=XModuleFields.nonEditableSettingsScope)
source_code = String(help="Source code for LaTeX and Word problems. This feature is not well-supported.", scope=Scope.settings)
......@@ -882,16 +888,6 @@ class CapaDescriptor(CapaFields, RawDescriptor):
'enable_markdown': self.markdown is not None})
return _context
@property
def editable_metadata_fields(self):
"""Remove metadata from the editable fields since it has its own editor"""
subset = super(CapaDescriptor, self).editable_metadata_fields
if 'markdown' in subset:
del subset['markdown']
if 'empty' in subset:
del subset['empty']
return subset
# VS[compat]
# TODO (cpennington): Delete this method once all fall 2012 course are being
# edited in the cms
......
from pkg_resources import resource_string
from xmodule.x_module import XModule
from xmodule.x_module import XModule, XModuleFields
from xmodule.raw_module import RawDescriptor
from xmodule.editing_module import MetadataOnlyEditingDescriptor
from xblock.core import String, Scope
class DiscussionFields(object):
discussion_id = String(scope=Scope.settings)
discussion_category = String(scope=Scope.settings)
discussion_target = String(scope=Scope.settings)
sort_key = String(scope=Scope.settings)
discussion_id = String(scope=XModuleFields.nonEditableSettingsScope)
discussion_category = String(display_name="Category Name", scope=Scope.settings)
discussion_target = String(display_name="Subcategory Name", scope=Scope.settings)
# We may choose to enable this in the future, but while Kevin is investigating....
sort_key = String(scope=XModuleFields.nonEditableSettingsScope)
class DiscussionModule(DiscussionFields, XModule):
......
......@@ -166,16 +166,6 @@ class HtmlDescriptor(HtmlFields, XmlDescriptor, EditingDescriptor):
elt.set("filename", relname)
return elt
@property
def editable_metadata_fields(self):
"""Remove any metadata from the editable fields which have their own editor or shouldn't be edited by user."""
subset = super(HtmlDescriptor, self).editable_metadata_fields
if 'empty' in subset:
del subset['empty']
return subset
class AboutDescriptor(HtmlDescriptor):
"""
......
from .x_module import XModuleDescriptor, DescriptorSystem
from .modulestore.inheritance import own_metadata
from .x_module import XModuleDescriptor, DescriptorSystem, NonEditableSettingsScope
from xblock.core import Scope
from xblock.core import XBlock
class MakoDescriptorSystem(DescriptorSystem):
......@@ -34,20 +35,40 @@ class MakoModuleDescriptor(XModuleDescriptor):
"""
return {
'module': self,
'editable_metadata_fields': self.editable_metadata_fields,
'editable_metadata_fields': self.editable_metadata_fields
}
def get_html(self):
return self.system.render_template(
self.mako_template, self.get_context())
# cdodge: encapsulate a means to expose "editable" metadata fields (i.e. not internal system metadata)
@property
def editable_metadata_fields(self):
fields = {}
for field, value in own_metadata(self).items():
if field in self.system_metadata_fields:
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
fields[field] = value
return fields
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
......@@ -78,12 +78,18 @@ class HTMLSnippet(object):
.format(self.__class__))
class NonEditableSettingsScope(Scope):
pass
class XModuleFields(object):
display_name = String(
display_name="Display Name",
help="Display name for this module",
scope=Scope.settings,
default=None,
default=None
)
nonEditableSettingsScope = NonEditableSettingsScope(user=Scope.settings.user, block=Scope.settings.block)
class XModule(XModuleFields, HTMLSnippet, XBlock):
......@@ -334,12 +340,6 @@ class XModuleDescriptor(XModuleFields, HTMLSnippet, ResourceTemplates, XBlock):
# (like a practice problem).
has_score = False
# cdodge: this is a list of metadata names which are 'system' metadata
# and should not be edited by an end-user
system_metadata_fields = ['data_dir', 'published_date', 'published_by', 'is_draft',
'discussion_id', 'xml_attributes']
# A list of descriptor attributes that must be equal for the descriptors to
# be equal
equality_attributes = ('_model_data', 'location')
......
......@@ -6,10 +6,11 @@ import sys
from collections import namedtuple
from lxml import etree
from xblock.core import Object, Scope
from xblock.core import Object
from xmodule.x_module import (XModuleDescriptor, policy_key)
from xmodule.modulestore import Location
from xmodule.modulestore.inheritance import own_metadata
from xmodule.x_module import XModuleFields
log = logging.getLogger(__name__)
......@@ -84,7 +85,8 @@ class XmlDescriptor(XModuleDescriptor):
Mixin class for standardized parsing of from xml
"""
xml_attributes = Object(help="Map of unhandled xml attributes, used only for storage between import and export", default={}, scope=Scope.settings)
xml_attributes = Object(help="Map of unhandled xml attributes, used only for storage between import and export",
default={}, scope=XModuleFields.nonEditableSettingsScope)
# Extension to append to filename paths
filename_extension = 'xml'
......
......@@ -6,4 +6,4 @@
# XBlock:
# Might change frequently, so put it in local-requirements.txt,
# but conceptually is an external package, so it is in a separate repo.
-e git+https://github.com/edx/XBlock.git@2e0770ff#egg=XBlock
-e git+https://github.com/edx/XBlock.git@49181a1b#egg=XBlock
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment