Stop using .definition and .metadata directly
This commit is contained in:
@@ -24,7 +24,7 @@ def get_course_updates(location):
|
||||
|
||||
# purely to handle free formed updates not done via editor. Actually kills them, but at least doesn't break.
|
||||
try:
|
||||
course_html_parsed = etree.fromstring(course_updates.definition['data'])
|
||||
course_html_parsed = etree.fromstring(course_updates.data)
|
||||
except etree.XMLSyntaxError:
|
||||
course_html_parsed = etree.fromstring("<ol></ol>")
|
||||
|
||||
@@ -61,7 +61,7 @@ def update_course_updates(location, update, passed_id=None):
|
||||
|
||||
# purely to handle free formed updates not done via editor. Actually kills them, but at least doesn't break.
|
||||
try:
|
||||
course_html_parsed = etree.fromstring(course_updates.definition['data'])
|
||||
course_html_parsed = etree.fromstring(course_updates.data)
|
||||
except etree.XMLSyntaxError:
|
||||
course_html_parsed = etree.fromstring("<ol></ol>")
|
||||
|
||||
@@ -82,8 +82,8 @@ def update_course_updates(location, update, passed_id=None):
|
||||
passed_id = course_updates.location.url() + "/" + str(idx)
|
||||
|
||||
# update db record
|
||||
course_updates.definition['data'] = etree.tostring(course_html_parsed)
|
||||
modulestore('direct').update_item(location, course_updates.definition['data'])
|
||||
course_updates.data = etree.tostring(course_html_parsed)
|
||||
modulestore('direct').update_item(location, course_updates.data)
|
||||
|
||||
return {"id" : passed_id,
|
||||
"date" : update['date'],
|
||||
@@ -105,7 +105,7 @@ def delete_course_update(location, update, passed_id):
|
||||
# TODO use delete_blank_text parser throughout and cache as a static var in a class
|
||||
# purely to handle free formed updates not done via editor. Actually kills them, but at least doesn't break.
|
||||
try:
|
||||
course_html_parsed = etree.fromstring(course_updates.definition['data'])
|
||||
course_html_parsed = etree.fromstring(course_updates.data)
|
||||
except etree.XMLSyntaxError:
|
||||
course_html_parsed = etree.fromstring("<ol></ol>")
|
||||
|
||||
@@ -118,9 +118,9 @@ def delete_course_update(location, update, passed_id):
|
||||
course_html_parsed.remove(element_to_delete)
|
||||
|
||||
# update db record
|
||||
course_updates.definition['data'] = etree.tostring(course_html_parsed)
|
||||
course_updates.data = etree.tostring(course_html_parsed)
|
||||
store = modulestore('direct')
|
||||
store.update_item(location, course_updates.definition['data'])
|
||||
store.update_item(location, course_updates.data)
|
||||
|
||||
return get_course_updates(location)
|
||||
|
||||
|
||||
@@ -218,7 +218,7 @@ def edit_subsection(request, location):
|
||||
# remove all metadata from the generic dictionary that is presented in a more normalized UI
|
||||
|
||||
policy_metadata = dict(
|
||||
(key,value)
|
||||
(field.name, field.read_from(item))
|
||||
for field
|
||||
in item.fields
|
||||
if field.name not in ['display_name', 'start', 'due', 'format'] and
|
||||
|
||||
@@ -230,13 +230,13 @@ class CourseGradingModel:
|
||||
|
||||
descriptor = get_modulestore(location).get_item(location)
|
||||
if 'graderType' in jsondict and jsondict['graderType'] != u"Not Graded":
|
||||
descriptor.metadata['format'] = jsondict.get('graderType')
|
||||
descriptor.metadata['graded'] = True
|
||||
descriptor.lms.format = jsondict.get('graderType')
|
||||
descriptor.lms.graded = True
|
||||
else:
|
||||
if 'format' in descriptor.metadata: del descriptor.metadata['format']
|
||||
if 'graded' in descriptor.metadata: del descriptor.metadata['graded']
|
||||
del descriptor.lms.format
|
||||
del descriptor.lms.graded
|
||||
|
||||
get_modulestore(location).update_metadata(location, descriptor.metadata)
|
||||
get_modulestore(location).update_metadata(location, descriptor._model_data._kvs._data)
|
||||
|
||||
|
||||
@staticmethod
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
<div class="row gradable">
|
||||
<label>Graded as:</label>
|
||||
|
||||
<div class="gradable-status" data-initial-status="${subsection.metadata.get('format', 'Not Graded')}">
|
||||
<div class="gradable-status" data-initial-status="${subsection.lms.format if subsection.lms.format is None else 'Not Graded'}">
|
||||
</div>
|
||||
|
||||
<div class="due-date-input row">
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
% if metadata:
|
||||
<%
|
||||
import hashlib
|
||||
hlskey = hashlib.md5(module.location.url()).hexdigest()
|
||||
%>
|
||||
<section class="metadata_edit">
|
||||
<ul>
|
||||
% for keyname in editable_metadata_fields:
|
||||
% for field_name, field_value in editable_metadata_fields.items():
|
||||
<li>
|
||||
% if keyname=='source_code':
|
||||
<a href="#hls-modal-${hlskey}" style="color:yellow;" id="hls-trig-${hlskey}" >Edit High Level Source</a>
|
||||
% else:
|
||||
<label>${keyname}:</label>
|
||||
<input type='text' data-metadata-name='${keyname}' value='${metadata[keyname]}' size='60' />
|
||||
% endif
|
||||
% if field_name == 'source_code':
|
||||
<a href="#hls-modal-${hlskey}" style="color:yellow;" id="hls-trig-${hlskey}" >Edit High Level Source</a>
|
||||
% else:
|
||||
<label>${field_name}:</label>
|
||||
<input type='text' data-metadata-name='${field_name}' value='${field_value}' size='60' />
|
||||
% endif
|
||||
</li>
|
||||
% endfor
|
||||
</ul>
|
||||
@@ -22,4 +21,3 @@
|
||||
% endif
|
||||
|
||||
</section>
|
||||
% endif
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from x_module import XModuleDescriptor, DescriptorSystem
|
||||
from .x_module import XModuleDescriptor, DescriptorSystem
|
||||
from .model import Scope
|
||||
import logging
|
||||
|
||||
|
||||
@@ -32,7 +33,10 @@ class MakoModuleDescriptor(XModuleDescriptor):
|
||||
"""
|
||||
Return the context to render the mako template with
|
||||
"""
|
||||
return {'module': self}
|
||||
return {
|
||||
'module': self,
|
||||
'editable_metadata_fields': self.editable_metadata_fields,
|
||||
}
|
||||
|
||||
def get_html(self):
|
||||
return self.system.render_template(
|
||||
@@ -41,6 +45,24 @@ class MakoModuleDescriptor(XModuleDescriptor):
|
||||
# cdodge: encapsulate a means to expose "editable" metadata fields (i.e. not internal system metadata)
|
||||
@property
|
||||
def editable_metadata_fields(self):
|
||||
subset = [field.name for field in self.fields if field.name not in self.system_metadata_fields]
|
||||
return subset
|
||||
fields = {}
|
||||
for field in self.fields:
|
||||
if field.scope != Scope.settings:
|
||||
continue
|
||||
|
||||
if field.name in self.system_metadata_fields:
|
||||
continue
|
||||
|
||||
fields[field.name] = field.read_from(self)
|
||||
|
||||
for field in self.lms.fields:
|
||||
if field.scope != Scope.settings:
|
||||
continue
|
||||
|
||||
if field.name in self.system_metadata_fields:
|
||||
continue
|
||||
|
||||
fields[field.name] = field.read_from(self)
|
||||
|
||||
return fields
|
||||
|
||||
|
||||
@@ -64,11 +64,42 @@ class ModelType(object):
|
||||
return self._seq < other._seq
|
||||
|
||||
def to_json(self, value):
|
||||
"""
|
||||
Return value in the form of nested lists and dictionaries (suitable
|
||||
for passing to json.dumps).
|
||||
|
||||
This is called during field writes to convert the native python
|
||||
type to the value stored in the database
|
||||
"""
|
||||
return value
|
||||
|
||||
def from_json(self, value):
|
||||
"""
|
||||
Return value as a native full featured python type (the inverse of to_json)
|
||||
|
||||
Called during field reads to convert the stored value into a full featured python
|
||||
object
|
||||
"""
|
||||
return value
|
||||
|
||||
def read_from(self, model):
|
||||
"""
|
||||
Retrieve the value for this field from the specified model object
|
||||
"""
|
||||
return self.__get__(model, model.__class__)
|
||||
|
||||
def write_to(self, model, value):
|
||||
"""
|
||||
Set the value for this field to value on the supplied model object
|
||||
"""
|
||||
self.__set__(model, value)
|
||||
|
||||
def delete_from(self, model):
|
||||
"""
|
||||
Delete the value for this field from the supplied model object
|
||||
"""
|
||||
self.__delete__(model)
|
||||
|
||||
Int = Float = Boolean = Object = List = String = Any = ModelType
|
||||
|
||||
|
||||
|
||||
@@ -173,13 +173,11 @@ class DraftModuleStore(ModuleStoreBase):
|
||||
Save a current draft to the underlying modulestore
|
||||
"""
|
||||
draft = self.get_item(location)
|
||||
metadata = {}
|
||||
metadata.update(draft.metadata)
|
||||
metadata.cms.published_date = datetime.utcnow()
|
||||
metadata.cms.published_by = published_by_id
|
||||
super(DraftModuleStore, self).update_item(location, draft.definition.get('data', {}))
|
||||
super(DraftModuleStore, self).update_children(location, draft.definition.get('children', []))
|
||||
super(DraftModuleStore, self).update_metadata(location, metadata)
|
||||
draft.cms.published_date = datetime.utcnow()
|
||||
draft.cms.published_by = published_by_id
|
||||
super(DraftModuleStore, self).update_item(location, draft._model_data._kvs._data)
|
||||
super(DraftModuleStore, self).update_children(location, draft._model_data._kvs._children)
|
||||
super(DraftModuleStore, self).update_metadata(location, draft._model_data._kvs._metadata)
|
||||
self.delete_item(location)
|
||||
|
||||
def unpublish(self, location):
|
||||
|
||||
@@ -250,7 +250,7 @@ class MongoModuleStore(ModuleStoreBase):
|
||||
"""
|
||||
Load an XModuleDescriptor from item, using the children stored in data_cache
|
||||
"""
|
||||
data_dir = item.get('metadata', {}).get('data_dir', item['location']['course'])
|
||||
data_dir = getattr(item, 'data_dir', item['location']['course'])
|
||||
root = self.fs_root / data_dir
|
||||
|
||||
if not root.isdir():
|
||||
@@ -361,9 +361,9 @@ class MongoModuleStore(ModuleStoreBase):
|
||||
if location.category == 'static_tab':
|
||||
course = self.get_course_for_item(item.location)
|
||||
existing_tabs = course.tabs or []
|
||||
existing_tabs.append({'type':'static_tab', 'name' : item.metadata.get('display_name'), 'url_slug' : item.location.name})
|
||||
existing_tabs.append({'type':'static_tab', 'name' : item.lms.display_name, 'url_slug' : item.location.name})
|
||||
course.tabs = existing_tabs
|
||||
self.update_metadata(course.location, course.metadata)
|
||||
self.update_metadata(course.location, course._model_data._kvs._metadata)
|
||||
|
||||
return item
|
||||
except pymongo.errors.DuplicateKeyError:
|
||||
|
||||
@@ -8,6 +8,7 @@ from collections import namedtuple
|
||||
from pkg_resources import resource_listdir, resource_string, resource_isdir
|
||||
|
||||
from xmodule.modulestore import Location
|
||||
from xmodule.modulestore.exceptions import ItemNotFoundError
|
||||
|
||||
from .model import ModelMetaclass, ParentModelMetaclass, NamespacesMetaclass
|
||||
from .plugin import Plugin
|
||||
|
||||
Reference in New Issue
Block a user