Commit 0daf7b04 by ichuang

merging of stable-edx4edx into master - bugfixes and debugging

parent 4356ec5c
...@@ -135,7 +135,7 @@ class CapaModule(XModule): ...@@ -135,7 +135,7 @@ class CapaModule(XModule):
try: try:
self.lcp = LoncapaProblem(self.definition['data'], self.location.html_id(), instance_state, seed=seed, system=self.system) self.lcp = LoncapaProblem(self.definition['data'], self.location.html_id(), instance_state, seed=seed, system=self.system)
except Exception: except Exception:
msg = 'cannot create LoncapaProblem %s' % self.url msg = 'cannot create LoncapaProblem %s' % self.location.url
log.exception(msg) log.exception(msg)
if self.system.DEBUG: if self.system.DEBUG:
msg = '<p>%s</p>' % msg.replace('<', '&lt;') msg = '<p>%s</p>' % msg.replace('<', '&lt;')
......
...@@ -6,6 +6,9 @@ that are stored in a database an accessible using their Location as an identifie ...@@ -6,6 +6,9 @@ that are stored in a database an accessible using their Location as an identifie
import re import re
from collections import namedtuple from collections import namedtuple
from .exceptions import InvalidLocationError from .exceptions import InvalidLocationError
import logging
log = logging.getLogger('mitx.' + 'modulestore')
URL_RE = re.compile(""" URL_RE = re.compile("""
(?P<tag>[^:]+):// (?P<tag>[^:]+)://
...@@ -74,11 +77,13 @@ class Location(_LocationBase): ...@@ -74,11 +77,13 @@ class Location(_LocationBase):
def check_list(list_): def check_list(list_):
for val in list_: for val in list_:
if val is not None and INVALID_CHARS.search(val) is not None: if val is not None and INVALID_CHARS.search(val) is not None:
log.debug('invalid characters val="%s", list_="%s"' % (val,list_))
raise InvalidLocationError(location) raise InvalidLocationError(location)
if isinstance(location, basestring): if isinstance(location, basestring):
match = URL_RE.match(location) match = URL_RE.match(location)
if match is None: if match is None:
log.debug('location is instance of %s but no URL match' % basestring)
raise InvalidLocationError(location) raise InvalidLocationError(location)
else: else:
groups = match.groupdict() groups = match.groupdict()
...@@ -86,6 +91,7 @@ class Location(_LocationBase): ...@@ -86,6 +91,7 @@ class Location(_LocationBase):
return _LocationBase.__new__(_cls, **groups) return _LocationBase.__new__(_cls, **groups)
elif isinstance(location, (list, tuple)): elif isinstance(location, (list, tuple)):
if len(location) not in (5, 6): if len(location) not in (5, 6):
log.debug('location has wrong length')
raise InvalidLocationError(location) raise InvalidLocationError(location)
if len(location) == 5: if len(location) == 5:
......
...@@ -12,7 +12,7 @@ from .exceptions import ItemNotFoundError ...@@ -12,7 +12,7 @@ from .exceptions import ItemNotFoundError
etree.set_default_parser(etree.XMLParser(dtd_validation=False, load_dtd=False, etree.set_default_parser(etree.XMLParser(dtd_validation=False, load_dtd=False,
remove_comments=True, remove_blank_text=True)) remove_comments=True, remove_blank_text=True))
log = logging.getLogger(__name__) log = logging.getLogger('mitx.' + __name__)
class XMLModuleStore(ModuleStore): class XMLModuleStore(ModuleStore):
...@@ -35,9 +35,13 @@ class XMLModuleStore(ModuleStore): ...@@ -35,9 +35,13 @@ class XMLModuleStore(ModuleStore):
self.default_class = None self.default_class = None
else: else:
module_path, _, class_name = default_class.rpartition('.') module_path, _, class_name = default_class.rpartition('.')
log.debug('module_path = %s' % module_path)
class_ = getattr(import_module(module_path), class_name) class_ = getattr(import_module(module_path), class_name)
self.default_class = class_ self.default_class = class_
log.debug('XMLModuleStore: eager=%s, data_dir = %s' % (eager,self.data_dir))
log.debug('default_class = %s' % self.default_class)
with open(self.data_dir / "course.xml") as course_file: with open(self.data_dir / "course.xml") as course_file:
class ImportSystem(XMLParsingSystem, MakoDescriptorSystem): class ImportSystem(XMLParsingSystem, MakoDescriptorSystem):
def __init__(self, modulestore): def __init__(self, modulestore):
...@@ -65,9 +69,11 @@ class XMLModuleStore(ModuleStore): ...@@ -65,9 +69,11 @@ class XMLModuleStore(ModuleStore):
slug = '{slug}_{count}'.format(slug=slug, count=self.unnamed_modules) slug = '{slug}_{count}'.format(slug=slug, count=self.unnamed_modules)
self.used_slugs.add(slug) self.used_slugs.add(slug)
# log.debug('-> slug=%s' % slug)
xml_data.set('slug', slug) xml_data.set('slug', slug)
module = XModuleDescriptor.load_from_xml(etree.tostring(xml_data), self, org, course, modulestore.default_class) module = XModuleDescriptor.load_from_xml(etree.tostring(xml_data), self, org, course, modulestore.default_class)
log.debug('==> importing module location %s' % repr(module.location))
modulestore.modules[module.location] = module modulestore.modules[module.location] = module
if eager: if eager:
...@@ -84,6 +90,7 @@ class XMLModuleStore(ModuleStore): ...@@ -84,6 +90,7 @@ class XMLModuleStore(ModuleStore):
XMLParsingSystem.__init__(self, **system_kwargs) XMLParsingSystem.__init__(self, **system_kwargs)
self.course = ImportSystem(self).process_xml(course_file.read()) self.course = ImportSystem(self).process_xml(course_file.read())
log.debug('========> Done with course import')
def get_item(self, location): def get_item(self, location):
""" """
......
...@@ -344,6 +344,8 @@ class XModuleDescriptor(Plugin): ...@@ -344,6 +344,8 @@ class XModuleDescriptor(Plugin):
etree.fromstring(xml_data).tag, etree.fromstring(xml_data).tag,
default_class default_class
) )
# leave next line in code, commented out - useful for low-level debugging
# log.debug('[XModuleDescriptor.load_from_xml] tag=%s, class_=%s' % (etree.fromstring(xml_data).tag,class_))
return class_.from_xml(xml_data, system, org, course) return class_.from_xml(xml_data, system, org, course)
@classmethod @classmethod
......
...@@ -125,6 +125,7 @@ class XmlDescriptor(XModuleDescriptor): ...@@ -125,6 +125,7 @@ class XmlDescriptor(XModuleDescriptor):
definition_xml = copy.deepcopy(xml_object) definition_xml = copy.deepcopy(xml_object)
else: else:
filepath = cls._format_filepath(xml_object.tag, filename) filepath = cls._format_filepath(xml_object.tag, filename)
log.debug('filepath=%s, resources_fs=%s' % (filepath,system.resources_fs))
with system.resources_fs.open(filepath) as file: with system.resources_fs.open(filepath) as file:
try: try:
definition_xml = etree.parse(file).getroot() definition_xml = etree.parse(file).getroot()
......
...@@ -209,9 +209,12 @@ def index(request, course=None, chapter=None, section=None, ...@@ -209,9 +209,12 @@ def index(request, course=None, chapter=None, section=None,
chapter = clean(chapter) chapter = clean(chapter)
section = clean(section) section = clean(section)
if settings.ENABLE_MULTICOURSE:
settings.MODULESTORE['default']['OPTIONS']['data_dir'] = settings.DATA_DIR + multicourse_settings.get_course_xmlpath(course)
context = { context = {
'csrf': csrf(request)['csrf_token'], 'csrf': csrf(request)['csrf_token'],
'accordion': render_accordion(request, course, chapter, section), 'accordion': render_accordion(request, course, chapter, section), # triggers course load!
'COURSE_TITLE': multicourse_settings.get_course_title(course), 'COURSE_TITLE': multicourse_settings.get_course_title(course),
'init': '', 'init': '',
'content': '' 'content': ''
......
...@@ -39,6 +39,7 @@ MITX_FEATURES = { ...@@ -39,6 +39,7 @@ MITX_FEATURES = {
'USE_DJANGO_PIPELINE' : True, 'USE_DJANGO_PIPELINE' : True,
'DISPLAY_HISTOGRAMS_TO_STAFF' : True, 'DISPLAY_HISTOGRAMS_TO_STAFF' : True,
'REROUTE_ACTIVATION_EMAIL' : False, # nonempty string = address for all activation emails 'REROUTE_ACTIVATION_EMAIL' : False, # nonempty string = address for all activation emails
'DEBUG_LEVEL' : 0, # 0 = lowest level, least verbose, 255 = max level, most verbose
} }
# Used for A/B testing # Used for A/B testing
......
...@@ -35,20 +35,22 @@ EDX4EDX_ROOT = ENV_ROOT / "data/edx4edx" ...@@ -35,20 +35,22 @@ EDX4EDX_ROOT = ENV_ROOT / "data/edx4edx"
DEBUG = True DEBUG = True
ENABLE_MULTICOURSE = True # set to False to disable multicourse display (see lib.util.views.mitxhome) ENABLE_MULTICOURSE = True # set to False to disable multicourse display (see lib.util.views.mitxhome)
QUICKEDIT = True QUICKEDIT = False
MAKO_TEMPLATES['course'] = [DATA_DIR, EDX4EDX_ROOT ] MAKO_TEMPLATES['course'] = [DATA_DIR, EDX4EDX_ROOT ]
#MITX_FEATURES['USE_DJANGO_PIPELINE'] = False #MITX_FEATURES['USE_DJANGO_PIPELINE'] = False
MITX_FEATURES['DISPLAY_HISTOGRAMS_TO_STAFF'] = False MITX_FEATURES['DISPLAY_HISTOGRAMS_TO_STAFF'] = False
MITX_FEATURES['DISPLAY_EDIT_LINK'] = True MITX_FEATURES['DISPLAY_EDIT_LINK'] = True
MITX_FEATURES['DEBUG_LEVEL'] = 10 # 0 = lowest level, least verbose, 255 = max level, most verbose
COURSE_SETTINGS = {'6.002x_Fall_2012': {'number' : '6.002x', COURSE_SETTINGS = {'6002x_Fall_2012': {'number' : '6.002x',
'title' : 'Circuits and Electronics', 'title' : 'Circuits and Electronics',
'xmlpath': '/6002x-fall-2012/', 'xmlpath': '/6002x-fall-2012/',
'active' : True, 'active' : True,
'default_chapter' : 'Week_1', 'default_chapter' : 'Week_1',
'default_section' : 'Administrivia_and_Circuit_Elements', 'default_section' : 'Administrivia_and_Circuit_Elements',
'location': 'i4x://edx/6002xs12/course/6002x Fall 2012',
}, },
'8.02_Spring_2013': {'number' : '8.02x', '8.02_Spring_2013': {'number' : '8.02x',
'title' : 'Electricity &amp; Magnetism', 'title' : 'Electricity &amp; Magnetism',
...@@ -81,6 +83,7 @@ COURSE_SETTINGS = {'6.002x_Fall_2012': {'number' : '6.002x', ...@@ -81,6 +83,7 @@ COURSE_SETTINGS = {'6.002x_Fall_2012': {'number' : '6.002x',
'active' : True, 'active' : True,
'default_chapter' : 'Introduction', 'default_chapter' : 'Introduction',
'default_section' : 'edx4edx_Course', 'default_section' : 'edx4edx_Course',
'location': 'i4x://edx/6002xs12/course/edx4edx',
}, },
'7.03x_Fall_2012': {'number' : '7.03x', '7.03x_Fall_2012': {'number' : '7.03x',
'title' : 'Genetics', 'title' : 'Genetics',
......
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