WIP: added a get_modulestore_type. Added some unit tests. changed over the isinstance() with respect to modulestores to use this get_modulestore_type()
This commit is contained in:
@@ -6,7 +6,7 @@ from staticfiles import finders
|
||||
from django.conf import settings
|
||||
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.modulestore.xml import XMLModuleStore
|
||||
from xmodule.modulestore import XML_MODULESTORE_TYPE
|
||||
from xmodule.contentstore.content import StaticContent
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@@ -90,7 +90,7 @@ def replace_course_urls(text, course_id):
|
||||
return re.sub(_url_replace_regex('/course/'), replace_course_url, text)
|
||||
|
||||
|
||||
def replace_static_urls(text, data_directory, course_namespace=None):
|
||||
def replace_static_urls(text, data_directory, course_id=None):
|
||||
"""
|
||||
Replace /static/$stuff urls either with their correct url as generated by collectstatic,
|
||||
(/static/$md5_hashed_stuff) or by the course-specific content static url
|
||||
@@ -99,7 +99,7 @@ def replace_static_urls(text, data_directory, course_namespace=None):
|
||||
|
||||
text: The source text to do the substitution in
|
||||
data_directory: The directory in which course data is stored
|
||||
course_namespace: The course identifier used to distinguish static content for this course in studio
|
||||
course_id: The course identifier used to distinguish static content for this course in studio
|
||||
"""
|
||||
|
||||
def replace_static_url(match):
|
||||
@@ -116,7 +116,7 @@ def replace_static_urls(text, data_directory, course_namespace=None):
|
||||
if settings.DEBUG and finders.find(rest, True):
|
||||
return original
|
||||
# if we're running with a MongoBacked store course_namespace is not None, then use studio style urls
|
||||
elif course_namespace is not None and not isinstance(modulestore(), XMLModuleStore):
|
||||
elif course_id and modulestore().get_modulestore_type(course_id) != XML_MODULESTORE_TYPE:
|
||||
# first look in the static file pipeline and see if we are trying to reference
|
||||
# a piece of static content which is in the mitx repo (e.g. JS associated with an xmodule)
|
||||
if staticfiles_storage.exists(rest):
|
||||
@@ -124,7 +124,7 @@ def replace_static_urls(text, data_directory, course_namespace=None):
|
||||
else:
|
||||
# if not, then assume it's courseware specific content and then look in the
|
||||
# Mongo-backed database
|
||||
url = StaticContent.convert_legacy_static_url(rest, course_namespace)
|
||||
url = StaticContent.convert_legacy_static_url(rest, course_id)
|
||||
# Otherwise, look the file up in staticfiles_storage, and append the data directory if needed
|
||||
else:
|
||||
course_path = "/".join((data_directory, rest))
|
||||
|
||||
@@ -14,6 +14,8 @@ from bson.son import SON
|
||||
|
||||
log = logging.getLogger('mitx.' + 'modulestore')
|
||||
|
||||
MONGO_MODULESTORE_TYPE = 'mongo'
|
||||
XML_MODULESTORE_TYPE = 'xml'
|
||||
|
||||
URL_RE = re.compile("""
|
||||
(?P<tag>[^:]+)://?
|
||||
@@ -391,6 +393,13 @@ class ModuleStore(object):
|
||||
'''
|
||||
raise NotImplementedError
|
||||
|
||||
def get_modulestore_type(self, course_id):
|
||||
"""
|
||||
Returns a type which identifies which modulestore is servicing the given
|
||||
course_id. The return can be either "xml" (for XML based courses) or "mongo" for MongoDB backed courses
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class ModuleStoreBase(ModuleStore):
|
||||
'''
|
||||
|
||||
@@ -118,3 +118,10 @@ class MixedModuleStore(ModuleStoreBase):
|
||||
"""
|
||||
for store in self.modulestores.values():
|
||||
store.set_modulestore_configuration(config_dict)
|
||||
|
||||
def get_modulestore_type(self, course_id):
|
||||
"""
|
||||
Returns a type which identifies which modulestore is servicing the given
|
||||
course_id. The return can be either "xml" (for XML based courses) or "mongo" for MongoDB backed courses
|
||||
"""
|
||||
return self._get_modulestore_for_courseid(course_id).get_modulestore_type(course_id)
|
||||
|
||||
@@ -32,7 +32,7 @@ from xmodule.error_module import ErrorDescriptor
|
||||
from xblock.runtime import DbModel, KeyValueStore, InvalidScopeError
|
||||
from xblock.core import Scope
|
||||
|
||||
from xmodule.modulestore import ModuleStoreBase, Location, namedtuple_to_son
|
||||
from xmodule.modulestore import ModuleStoreBase, Location, namedtuple_to_son, MONGO_MODULESTORE_TYPE
|
||||
from xmodule.modulestore.exceptions import ItemNotFoundError
|
||||
from xmodule.modulestore.inheritance import own_metadata, INHERITABLE_METADATA, inherit_metadata
|
||||
|
||||
@@ -841,6 +841,13 @@ class MongoModuleStore(ModuleStoreBase):
|
||||
{'_id': True})
|
||||
return [i['_id'] for i in items]
|
||||
|
||||
def get_modulestore_type(self, course_id):
|
||||
"""
|
||||
Returns a type which identifies which modulestore is servicing the given
|
||||
course_id. The return can be either "xml" (for XML based courses) or "mongo" for MongoDB backed courses
|
||||
"""
|
||||
return MONGO_MODULESTORE_TYPE
|
||||
|
||||
def _create_new_model_data(self, category, location, definition_data, metadata):
|
||||
"""
|
||||
To instantiate a new xmodule which will be saved latter, set up the dbModel and kvs
|
||||
@@ -854,9 +861,9 @@ class MongoModuleStore(ModuleStoreBase):
|
||||
)
|
||||
|
||||
class_ = XModuleDescriptor.load_class(
|
||||
category,
|
||||
self.default_class
|
||||
)
|
||||
category,
|
||||
self.default_class
|
||||
)
|
||||
model_data = DbModel(kvs, class_, None, MongoUsage(None, location))
|
||||
model_data['category'] = category
|
||||
model_data['location'] = location
|
||||
|
||||
@@ -45,8 +45,7 @@ class TestMongoModuleStore(object):
|
||||
@staticmethod
|
||||
def initdb():
|
||||
# connect to the db
|
||||
store = MongoModuleStore(HOST, DB, COLLECTION, FS_ROOT, RENDER_TEMPLATE,
|
||||
default_class=DEFAULT_CLASS)
|
||||
store = MongoModuleStore(HOST, DB, COLLECTION, FS_ROOT, RENDER_TEMPLATE, default_class=DEFAULT_CLASS)
|
||||
# Explicitly list the courses to load (don't want the big one)
|
||||
courses = ['toy', 'simple']
|
||||
import_from_xml(store, DATA_DIR, courses)
|
||||
@@ -71,6 +70,10 @@ class TestMongoModuleStore(object):
|
||||
|
||||
pprint([Location(i['_id']).url() for i in ids])
|
||||
|
||||
def test_mongo_modulestore_type(self):
|
||||
store = MongoModuleStore(HOST, DB, COLLECTION, FS_ROOT, RENDER_TEMPLATE, default_class=DEFAULT_CLASS)
|
||||
assert_equals(store.get_modulestore_type('foo/bar/baz'), 'mongo')
|
||||
|
||||
def test_get_courses(self):
|
||||
'''Make sure the course objects loaded properly'''
|
||||
courses = self.store.get_courses()
|
||||
@@ -117,6 +120,7 @@ class TestMongoModuleStore(object):
|
||||
'{0} is a template course'.format(course)
|
||||
)
|
||||
|
||||
|
||||
class TestMongoKeyValueStore(object):
|
||||
|
||||
def setUp(self):
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import os.path
|
||||
|
||||
from nose.tools import assert_raises
|
||||
from nose.tools import assert_raises, assert_equals
|
||||
|
||||
from xmodule.course_module import CourseDescriptor
|
||||
from xmodule.modulestore.xml import XMLModuleStore
|
||||
from xmodule.modulestore import XML_MODULESTORE_TYPE
|
||||
|
||||
from xmodule.tests import DATA_DIR
|
||||
from xmodule.modulestore.tests.test_modulestore import check_path_to_location
|
||||
from .test_modulestore import check_path_to_location
|
||||
from . import DATA_DIR
|
||||
|
||||
|
||||
class TestXMLModuleStore(object):
|
||||
@@ -19,6 +20,10 @@ class TestXMLModuleStore(object):
|
||||
|
||||
check_path_to_location(modulestore)
|
||||
|
||||
def test_xml_modulestore_type(self):
|
||||
store = XMLModuleStore(DATA_DIR, course_dirs=['toy', 'simple'])
|
||||
assert_equals(store.get_modulestore_type('foo/bar/baz'), XML_MODULESTORE_TYPE)
|
||||
|
||||
def test_unicode_chars_in_xml_content(self):
|
||||
# edX/full/6.002_Spring_2012 has non-ASCII chars, and during
|
||||
# uniquification of names, would raise a UnicodeError. It no longer does.
|
||||
|
||||
@@ -21,7 +21,7 @@ from xmodule.x_module import XModuleDescriptor, XMLParsingSystem
|
||||
|
||||
from xmodule.html_module import HtmlDescriptor
|
||||
|
||||
from . import ModuleStoreBase, Location
|
||||
from . import ModuleStoreBase, Location, XML_MODULESTORE_TYPE
|
||||
from .exceptions import ItemNotFoundError
|
||||
from .inheritance import compute_inherited_metadata
|
||||
|
||||
@@ -601,3 +601,10 @@ class XMLModuleStore(ModuleStoreBase):
|
||||
raise ItemNotFoundError("{0} not in {1}".format(location, course_id))
|
||||
|
||||
return self.parent_trackers[course_id].parents(location)
|
||||
|
||||
def get_modulestore_type(self, course_id):
|
||||
"""
|
||||
Returns a type which identifies which modulestore is servicing the given
|
||||
course_id. The return can be either "xml" (for XML based courses) or "mongo" for MongoDB backed courses
|
||||
"""
|
||||
return XML_MODULESTORE_TYPE
|
||||
|
||||
@@ -161,12 +161,7 @@ class VideoModule(VideoFields, XModule):
|
||||
return json.dumps({'position': self.position})
|
||||
|
||||
def get_html(self):
|
||||
if isinstance(modulestore(), MongoModuleStore):
|
||||
caption_asset_path = StaticContent.get_base_url_path_for_course_assets(self.location) + '/subs_'
|
||||
else:
|
||||
# VS[compat]
|
||||
# cdodge: filesystem static content support.
|
||||
caption_asset_path = "/static/subs/"
|
||||
caption_asset_path = "/static/subs/"
|
||||
|
||||
get_ext = lambda filename: filename.rpartition('.')[-1]
|
||||
sources = {get_ext(src): src for src in self.html5_sources}
|
||||
|
||||
@@ -8,7 +8,7 @@ from django.http import Http404
|
||||
|
||||
from .module_render import get_module
|
||||
from xmodule.course_module import CourseDescriptor
|
||||
from xmodule.modulestore import Location
|
||||
from xmodule.modulestore import Location, MONGO_MODULESTORE_TYPE
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.contentstore.content import StaticContent
|
||||
from xmodule.modulestore.xml import XMLModuleStore
|
||||
@@ -82,7 +82,7 @@ def get_opt_course_with_access(user, course_id, action):
|
||||
def course_image_url(course):
|
||||
"""Try to look up the image url for the course. If it's not found,
|
||||
log an error and return the dead link"""
|
||||
if isinstance(modulestore(), XMLModuleStore):
|
||||
if modulestore().get_modulestore_type(course.course_id) == MONGO_MODULESTORE_TYPE:
|
||||
return '/static/' + course.data_dir + "/images/course_image.jpg"
|
||||
else:
|
||||
loc = course.location._replace(tag='c4x', category='asset', name='images_course_image.jpg')
|
||||
|
||||
Reference in New Issue
Block a user