Commit 8e0d218c by Calen Pennington

Stop using .definition and .metadata directly

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