WIP
This commit is contained in:
@@ -116,7 +116,7 @@ def preview_module_system(request, preview_id, descriptor):
|
||||
get_module=partial(load_preview_module, request, preview_id),
|
||||
render_template=render_from_lms,
|
||||
debug=True,
|
||||
replace_urls=partial(static_replace.replace_static_urls, data_directory=None, course_namespace=descriptor.location),
|
||||
replace_urls=partial(static_replace.replace_static_urls, data_directory=None, course_id=course_id),
|
||||
user=request.user,
|
||||
xblock_model_data=preview_model_data,
|
||||
can_execute_unsafe_code=(lambda: can_execute_unsafe_code(course_id)),
|
||||
@@ -158,7 +158,7 @@ def load_preview_module(request, preview_id, descriptor):
|
||||
module.get_html = replace_static_urls(
|
||||
module.get_html,
|
||||
getattr(module, 'data_dir', module.location.course),
|
||||
course_namespace=Location([module.location.tag, module.location.org, module.location.course, None, None])
|
||||
course_id=module.location.org+'/'+module.location.course+'/REPLACE_WITH_RUN'
|
||||
)
|
||||
|
||||
module.get_html = save_module(
|
||||
|
||||
@@ -6,11 +6,14 @@ from xmodule.modulestore import InvalidLocationError
|
||||
from cache_toolbox.core import get_cached_content, set_cached_content
|
||||
from xmodule.exceptions import NotFoundError
|
||||
|
||||
import logging
|
||||
|
||||
|
||||
class StaticContentServer(object):
|
||||
def process_request(self, request):
|
||||
# look to see if the request is prefixed with 'c4x' tag
|
||||
if request.path.startswith('/' + XASSET_LOCATION_TAG + '/'):
|
||||
logging.debug('**** path = {0}'.format(request.path))
|
||||
try:
|
||||
loc = StaticContent.get_location_from_path(request.path)
|
||||
except InvalidLocationError:
|
||||
@@ -24,8 +27,10 @@ class StaticContentServer(object):
|
||||
if content is None:
|
||||
# nope, not in cache, let's fetch from DB
|
||||
try:
|
||||
logging.debug('!!!! loc = {0}'.format(loc))
|
||||
content = contentstore().find(loc, as_stream=True)
|
||||
except NotFoundError:
|
||||
logging.debug('**** NOT FOUND')
|
||||
response = HttpResponse()
|
||||
response.status_code = 404
|
||||
return response
|
||||
|
||||
@@ -124,7 +124,7 @@ def replace_static_urls(text, data_directory, course_id=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_id)
|
||||
url = StaticContent.convert_legacy_static_url_with_course_id(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))
|
||||
|
||||
@@ -95,6 +95,7 @@ def index(request, extra_context={}, user=None):
|
||||
courses = sort_by_announcement(courses)
|
||||
|
||||
context = {'courses': courses}
|
||||
|
||||
context.update(extra_context)
|
||||
return render_to_response('index.html', context)
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ def replace_course_urls(get_html, course_id):
|
||||
return _get_html
|
||||
|
||||
|
||||
def replace_static_urls(get_html, data_dir, course_namespace=None):
|
||||
def replace_static_urls(get_html, data_dir, course_id=None):
|
||||
"""
|
||||
Updates the supplied module with a new get_html function that wraps
|
||||
the old get_html function and substitutes urls of the form /static/...
|
||||
@@ -85,7 +85,7 @@ def replace_static_urls(get_html, data_dir, course_namespace=None):
|
||||
|
||||
@wraps(get_html)
|
||||
def _get_html():
|
||||
return static_replace.replace_static_urls(get_html(), data_dir, course_namespace)
|
||||
return static_replace.replace_static_urls(get_html(), data_dir, course_id)
|
||||
return _get_html
|
||||
|
||||
|
||||
|
||||
@@ -100,6 +100,12 @@ class StaticContent(object):
|
||||
loc = StaticContent.compute_location(course_namespace.org, course_namespace.course, path)
|
||||
return StaticContent.get_url_path_from_location(loc)
|
||||
|
||||
@staticmethod
|
||||
def convert_legacy_static_url_with_course_id(path, course_id):
|
||||
org, course_num, run = course_id.split("/")
|
||||
loc = StaticContent.compute_location(org, course_num, path)
|
||||
return StaticContent.get_url_path_from_location(loc)
|
||||
|
||||
def stream_data(self):
|
||||
yield self._data
|
||||
|
||||
|
||||
@@ -8,6 +8,9 @@ IMPORTANT: This modulestore is experimental AND INCOMPLETE. Therefore this shoul
|
||||
|
||||
from . import ModuleStoreBase
|
||||
from django import create_modulestore_instance
|
||||
import logging
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class MixedModuleStore(ModuleStoreBase):
|
||||
@@ -23,6 +26,9 @@ class MixedModuleStore(ModuleStoreBase):
|
||||
|
||||
self.modulestores = {}
|
||||
self.mappings = mappings
|
||||
if 'default' not in stores:
|
||||
raise Exception('Missing a default modulestore in the MixedModuleStore __init__ method.')
|
||||
|
||||
for key in stores:
|
||||
self.modulestores[key] = create_modulestore_instance(stores[key]['ENGINE'],
|
||||
stores[key]['OPTIONS'])
|
||||
@@ -32,7 +38,8 @@ class MixedModuleStore(ModuleStoreBase):
|
||||
For a given course_id, look in the mapping table and see if it has been pinned
|
||||
to a particular modulestore
|
||||
"""
|
||||
return self.mappings.get(course_id, self.mappings['default'])
|
||||
mapping = self.mappings.get(course_id, 'default')
|
||||
return self.modulestores[mapping]
|
||||
|
||||
def has_item(self, course_id, location):
|
||||
return self._get_modulestore_for_courseid(course_id).has_item(course_id, location)
|
||||
@@ -96,7 +103,8 @@ class MixedModuleStore(ModuleStoreBase):
|
||||
'''
|
||||
courses = []
|
||||
for key in self.modulestores:
|
||||
courses.append(self.modulestores[key].get_courses)
|
||||
courses = courses + (self.modulestores[key].get_courses())
|
||||
|
||||
return courses
|
||||
|
||||
def get_course(self, course_id):
|
||||
@@ -125,3 +133,12 @@ class MixedModuleStore(ModuleStoreBase):
|
||||
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)
|
||||
|
||||
def get_errored_courses(self):
|
||||
"""
|
||||
Return a dictionary of course_dir -> [(msg, exception_str)], for each
|
||||
course_dir where course loading failed.
|
||||
"""
|
||||
errs = {}
|
||||
for store in self.modulestores.values():
|
||||
errs.update(store.get_errored_courses())
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.course_module import CourseDescriptor
|
||||
from django.conf import settings
|
||||
@@ -15,7 +14,9 @@ def get_visible_courses(domain=None):
|
||||
"""
|
||||
Return the set of CourseDescriptors that should be visible in this branded instance
|
||||
"""
|
||||
courses = [c for c in modulestore().get_courses()
|
||||
_courses = modulestore().get_courses()
|
||||
|
||||
courses = [c for c in _courses
|
||||
if isinstance(c, CourseDescriptor)]
|
||||
courses = sorted(courses, key=lambda course: course.number)
|
||||
|
||||
|
||||
@@ -8,10 +8,9 @@ from django.http import Http404
|
||||
|
||||
from .module_render import get_module
|
||||
from xmodule.course_module import CourseDescriptor
|
||||
from xmodule.modulestore import Location, MONGO_MODULESTORE_TYPE
|
||||
from xmodule.modulestore import Location, XML_MODULESTORE_TYPE
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.contentstore.content import StaticContent
|
||||
from xmodule.modulestore.xml import XMLModuleStore
|
||||
from xmodule.modulestore.exceptions import ItemNotFoundError, InvalidLocationError
|
||||
from courseware.model_data import ModelDataCache
|
||||
from static_replace import replace_static_urls
|
||||
@@ -82,12 +81,12 @@ 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 modulestore().get_modulestore_type(course.course_id) == MONGO_MODULESTORE_TYPE:
|
||||
if modulestore().get_modulestore_type(course.location.course_id) == XML_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')
|
||||
path = StaticContent.get_url_path_from_location(loc)
|
||||
return path
|
||||
_path = StaticContent.get_url_path_from_location(loc)
|
||||
return _path
|
||||
|
||||
|
||||
def find_file(fs, dirs, filename):
|
||||
@@ -243,7 +242,7 @@ def get_course_syllabus_section(course, section_key):
|
||||
return replace_static_urls(
|
||||
htmlFile.read().decode('utf-8'),
|
||||
getattr(course, 'data_dir', None),
|
||||
course_namespace=course.location
|
||||
course_id=course.location.course_id
|
||||
)
|
||||
except ResourceNotFoundError:
|
||||
log.exception("Missing syllabus section {key} in course {url}".format(
|
||||
|
||||
@@ -332,6 +332,7 @@ def get_module_for_descriptor_internal(user, descriptor, model_data_cache, cours
|
||||
# TODO (cpennington): When modules are shared between courses, the static
|
||||
# prefix is going to have to be specific to the module, not the directory
|
||||
# that the xml was loaded from
|
||||
|
||||
system = ModuleSystem(
|
||||
track_function=track_function,
|
||||
render_template=render_to_string,
|
||||
@@ -347,7 +348,7 @@ def get_module_for_descriptor_internal(user, descriptor, model_data_cache, cours
|
||||
replace_urls=partial(
|
||||
static_replace.replace_static_urls,
|
||||
data_directory=getattr(descriptor, 'data_dir', None),
|
||||
course_namespace=descriptor.location._replace(category=None, name=None),
|
||||
course_id=course_id,
|
||||
),
|
||||
replace_course_urls=partial(
|
||||
static_replace.replace_course_urls,
|
||||
@@ -368,6 +369,7 @@ def get_module_for_descriptor_internal(user, descriptor, model_data_cache, cours
|
||||
cache=cache,
|
||||
can_execute_unsafe_code=(lambda: can_execute_unsafe_code(course_id)),
|
||||
)
|
||||
|
||||
# pass position specified in URL to module through ModuleSystem
|
||||
system.set('position', position)
|
||||
system.set('DEBUG', settings.DEBUG)
|
||||
@@ -405,8 +407,12 @@ def get_module_for_descriptor_internal(user, descriptor, model_data_cache, cours
|
||||
module.get_html = replace_static_urls(
|
||||
_get_html,
|
||||
getattr(descriptor, 'data_dir', None),
|
||||
<<<<<<< HEAD
|
||||
course_namespace=module.location._replace(category=None, name=None)
|
||||
)
|
||||
=======
|
||||
course_id=course_id)
|
||||
>>>>>>> WIP
|
||||
|
||||
# Allow URLs of the form '/course/' refer to the root of multicourse directory
|
||||
# hierarchy of this course
|
||||
|
||||
@@ -50,7 +50,7 @@ def remap_static_url(original_url, course):
|
||||
output_url = replace_static_urls(
|
||||
input_url,
|
||||
getattr(course, 'data_dir', None),
|
||||
course_namespace=course.location,
|
||||
coures_id=course.location.course_id,
|
||||
)
|
||||
# strip off the quotes again...
|
||||
return output_url[1:-1]
|
||||
|
||||
@@ -9,8 +9,7 @@ MODULESTORE = {
|
||||
'ENGINE': 'xmodule.modulestore.mixed.MixedModuleStore',
|
||||
'OPTIONS': {
|
||||
'mappings': {
|
||||
'6.002/a/a': 'xml',
|
||||
'6.002/b/b': 'xml'
|
||||
'MITx/2.01x/2013_Spring': 'xml'
|
||||
},
|
||||
'stores': {
|
||||
'xml': {
|
||||
|
||||
Reference in New Issue
Block a user