Commit 8e0d218c by Calen Pennington

Stop using .definition and .metadata directly

parent 60fa8619
......@@ -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">
......
% 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
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
......
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