Commit cff93d32 by Chris Dodge

WIP

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