diff --git a/cms/djangoapps/contentstore/course_info_model.py b/cms/djangoapps/contentstore/course_info_model.py index 87dfa5da8f..ef60a0c1b3 100644 --- a/cms/djangoapps/contentstore/course_info_model.py +++ b/cms/djangoapps/contentstore/course_info_model.py @@ -4,6 +4,7 @@ from xmodule.modulestore.django import modulestore from lxml import etree import re from django.http import HttpResponseBadRequest +from contentstore.utils import get_modulestore ## TODO store as array of { date, content } and override course_info_module.definition_from_xml ## This should be in a class which inherits from XmlDescriptor @@ -13,10 +14,10 @@ def get_course_updates(location): [{id : location.url() + idx to make unique, date : string, content : html string}] """ try: - course_updates = modulestore('direct').get_item(location) + course_updates = get_modulestore(location).get_item(location) except ItemNotFoundError: template = Location(['i4x', 'edx', "templates", 'course_info', "Empty"]) - course_updates = modulestore('direct').clone_item(template, Location(location)) + course_updates = get_modulestore(location).clone_item(template, Location(location)) # current db rep: {"_id" : locationjson, "definition" : { "data" : "
    [
  1. date

    content
  2. ]
"} "metadata" : ignored} location_base = course_updates.location.url() @@ -53,7 +54,7 @@ def update_course_updates(location, update, passed_id=None): into the html structure. """ try: - course_updates = modulestore('direct').get_item(location) + course_updates = get_modulestore(location).get_item(location) except ItemNotFoundError: return HttpResponseBadRequest @@ -99,7 +100,7 @@ def update_course_updates(location, update, passed_id=None): # update db record course_updates.definition['data'] = etree.tostring(course_html_parsed) - modulestore('direct').update_item(location, course_updates.definition['data']) + get_modulestore(location).update_item(location, course_updates.definition['data']) return {"id" : passed_id, "date" : update['date'], @@ -114,7 +115,7 @@ def delete_course_update(location, update, passed_id): return HttpResponseBadRequest try: - course_updates = modulestore('direct').get_item(location) + course_updates = get_modulestore(location).get_item(location) except ItemNotFoundError: return HttpResponseBadRequest @@ -133,7 +134,7 @@ def delete_course_update(location, update, passed_id): # update db record course_updates.definition['data'] = etree.tostring(course_html_parsed) - store = modulestore('direct') + store = get_modulestore(location) store.update_item(location, course_updates.definition['data']) return get_course_updates(location) diff --git a/cms/djangoapps/contentstore/utils.py b/cms/djangoapps/contentstore/utils.py index 508236a1e9..62c46cc9d4 100644 --- a/cms/djangoapps/contentstore/utils.py +++ b/cms/djangoapps/contentstore/utils.py @@ -3,6 +3,19 @@ from xmodule.modulestore import Location from xmodule.modulestore.django import modulestore from xmodule.modulestore.exceptions import ItemNotFoundError +DIRECT_ONLY_CATEGORIES = ['course', 'chapter', 'sequential', 'about', 'static_tab', 'course_info'] + +def get_modulestore(location): + """ + Returns the correct modulestore to use for modifying the specified location + """ + if not isinstance(location, Location): + location = Location(location) + + if location.category in DIRECT_ONLY_CATEGORIES: + return modulestore('direct') + else: + return modulestore() def get_course_location_for_item(location): ''' diff --git a/cms/djangoapps/contentstore/views.py b/cms/djangoapps/contentstore/views.py index c810dc7df7..ec529315b4 100644 --- a/cms/djangoapps/contentstore/views.py +++ b/cms/djangoapps/contentstore/views.py @@ -46,36 +46,19 @@ import time from contentstore import course_info_model from models.settings.course_details import CourseDetails from models.settings.course_details import CourseDetailsEncoder +from contentstore.utils import get_modulestore # to install PIL on MacOSX: 'easy_install http://dist.repoze.org/PIL-1.1.6.tar.gz' - - - - - - log = logging.getLogger(__name__) COMPONENT_TYPES = ['customtag', 'discussion', 'html', 'problem', 'video'] -DIRECT_ONLY_CATEGORIES = ['course', 'chapter', 'sequential', 'about', 'static_tab', 'course_info'] - # cdodge: these are categories which should not be parented, they are detached from the hierarchy DETACHED_CATEGORIES = ['about', 'static_tab', 'course_info'] -def _modulestore(location): - """ - Returns the correct modulestore to use for modifying the specified location - """ - if location.category in DIRECT_ONLY_CATEGORIES: - return modulestore('direct') - else: - return modulestore() - - # ==== Public views ================================================== @ensure_csrf_cookie @@ -543,7 +526,7 @@ def delete_item(request): item = modulestore().get_item(item_location) - store = _modulestore(item_loc) + store = get_modulestore(item_loc) # @TODO: this probably leaves draft items dangling. My preferance would be for the semantic to be @@ -574,7 +557,7 @@ def save_item(request): if not has_access(request.user, item_location): raise PermissionDenied() - store = _modulestore(Location(item_location)); + store = get_modulestore(Location(item_location)); if request.POST.get('data') is not None: data = request.POST['data'] @@ -677,10 +660,10 @@ def clone_item(request): if not has_access(request.user, parent_location): raise PermissionDenied() - parent = _modulestore(template).get_item(parent_location) + parent = get_modulestore(template).get_item(parent_location) dest_location = parent_location._replace(category=template.category, name=uuid4().hex) - new_item = _modulestore(template).clone_item(template, dest_location) + new_item = get_modulestore(template).clone_item(template, dest_location) # TODO: This needs to be deleted when we have proper storage for static content new_item.metadata['data_dir'] = parent.metadata['data_dir'] @@ -689,10 +672,10 @@ def clone_item(request): if display_name is not None: new_item.metadata['display_name'] = display_name - _modulestore(template).update_metadata(new_item.location.url(), new_item.own_metadata) + get_modulestore(template).update_metadata(new_item.location.url(), new_item.own_metadata) if new_item.location.category not in DETACHED_CATEGORIES: - _modulestore(parent.location).update_children(parent_location, parent.definition.get('children', []) + [new_item.location.url()]) + get_modulestore(parent.location).update_children(parent_location, parent.definition.get('children', []) + [new_item.location.url()]) return HttpResponse(json.dumps({'id': dest_location.url()})) diff --git a/common/djangoapps/models/settings/course_details.py b/common/djangoapps/models/settings/course_details.py index 29820795f3..fb97784588 100644 --- a/common/djangoapps/models/settings/course_details.py +++ b/common/djangoapps/models/settings/course_details.py @@ -5,6 +5,7 @@ import json from json.encoder import JSONEncoder import time from util.converters import jsdate_to_time, time_to_date +from contentstore.utils import get_modulestore class CourseDetails: def __init__(self, location): @@ -28,7 +29,7 @@ class CourseDetails: course = cls(course_location) - descriptor = modulestore('direct').get_item(course_location) + descriptor = get_modulestore(course_location).get_item(course_location) course.start_date = descriptor.start course.end_date = descriptor.end @@ -37,25 +38,25 @@ class CourseDetails: temploc = course_location._replace(category='about', name='syllabus') try: - course.syllabus = modulestore('direct').get_item(temploc).definition['data'] + course.syllabus = get_modulestore(temploc).get_item(temploc).definition['data'] except ItemNotFoundError: pass temploc = temploc._replace(name='overview') try: - course.overview = modulestore('direct').get_item(temploc).definition['data'] + course.overview = get_modulestore(temploc).get_item(temploc).definition['data'] except ItemNotFoundError: pass temploc = temploc._replace(name='effort') try: - course.effort = modulestore('direct').get_item(temploc).definition['data'] + course.effort = get_modulestore(temploc).get_item(temploc).definition['data'] except ItemNotFoundError: pass temploc = temploc._replace(name='video') try: - course.intro_video = modulestore('direct').get_item(temploc).definition['data'] + course.intro_video = get_modulestore(temploc).get_item(temploc).definition['data'] except ItemNotFoundError: pass @@ -69,7 +70,7 @@ class CourseDetails: ## TODO make it an error for this to be undefined & for it to not be retrievable from modulestore course_location = jsondict['course_location'] ## Will probably want to cache the inflight courses because every blur generates an update - descriptor = modulestore('direct').get_item(course_location) + descriptor = get_modulestore(course_location).get_item(course_location) dirty = False @@ -110,21 +111,21 @@ class CourseDetails: descriptor.enrollment_end = converted if dirty: - modulestore('direct').update_metadata(course_location, descriptor.metadata) + get_modulestore(course_location).update_metadata(course_location, descriptor.metadata) # NOTE: below auto writes to the db w/o verifying that any of the fields actually changed # to make faster, could compare against db or could have client send over a list of which fields changed. temploc = Location(course_location)._replace(category='about', name='syllabus') - modulestore('direct').update_item(temploc, jsondict['syllabus']) + get_modulestore(temploc).update_item(temploc, jsondict['syllabus']) temploc = temploc._replace(name='overview') - modulestore('direct').update_item(temploc, jsondict['overview']) + get_modulestore(temploc).update_item(temploc, jsondict['overview']) temploc = temploc._replace(name='effort') - modulestore('direct').update_item(temploc, jsondict['effort']) + get_modulestore(temploc).update_item(temploc, jsondict['effort']) temploc = temploc._replace(name='video') - modulestore('direct').update_item(temploc, jsondict['intro_video']) + get_modulestore(temploc).update_item(temploc, jsondict['intro_video']) # Could just generate and return a course obj w/o doing any db reads, but I put the reads in as a means to confirm