Commit 2019e672 by Calen Pennington

Get capa problems to display from a keystore

parent f8dba456
...@@ -19,9 +19,10 @@ setup( ...@@ -19,9 +19,10 @@ setup(
"section = xmodule.translation_module:SemanticSectionDescriptor", "section = xmodule.translation_module:SemanticSectionDescriptor",
"sequential = xmodule.seq_module:SequenceDescriptor", "sequential = xmodule.seq_module:SequenceDescriptor",
"vertical = xmodule.vertical_module:VerticalDescriptor", "vertical = xmodule.vertical_module:VerticalDescriptor",
"problem = xmodule.capa_module:CapaDescriptor",
"problemset = xmodule.seq_module:SequenceDescriptor", "problemset = xmodule.seq_module:SequenceDescriptor",
"videosequence = xmodule.seq_module:SequenceDescriptor",
"video = xmodule.video_module:VideoDescriptor", "video = xmodule.video_module:VideoDescriptor",
"videosequence = xmodule.seq_module:SequenceDescriptor",
] ]
} }
) )
...@@ -10,6 +10,9 @@ class_priority = ['video', 'problem'] ...@@ -10,6 +10,9 @@ class_priority = ['video', 'problem']
class VerticalModule(XModule): class VerticalModule(XModule):
''' Layout module for laying out submodules vertically.''' ''' Layout module for laying out submodules vertically.'''
def get_html(self): def get_html(self):
if self.contents is None:
self.contents = [child.get_html() for child in self.get_display_items()]
return self.system.render_template('vert_module.html', { return self.system.render_template('vert_module.html', {
'items': self.contents 'items': self.contents
}) })
...@@ -31,7 +34,7 @@ class VerticalModule(XModule): ...@@ -31,7 +34,7 @@ class VerticalModule(XModule):
def __init__(self, system, location, definition, instance_state=None, shared_state=None, **kwargs): def __init__(self, system, location, definition, instance_state=None, shared_state=None, **kwargs):
XModule.__init__(self, system, location, definition, instance_state, shared_state, **kwargs) XModule.__init__(self, system, location, definition, instance_state, shared_state, **kwargs)
self.contents = [child.get_html() for child in self.get_display_items()] self.contents = None
class VerticalDescriptor(SequenceDescriptor): class VerticalDescriptor(SequenceDescriptor):
......
...@@ -60,13 +60,7 @@ class I4xSystem(object): ...@@ -60,13 +60,7 @@ class I4xSystem(object):
''' '''
self.ajax_url = ajax_url self.ajax_url = ajax_url
self.track_function = track_function self.track_function = track_function
if not filestore:
self.filestore = OSFS(settings.DATA_DIR)
else:
self.filestore = filestore self.filestore = filestore
if settings.DEBUG:
log.info("[courseware.module_render.I4xSystem] filestore path = %s",
filestore)
self.get_module = get_module self.get_module = get_module
self.render_function = render_function self.render_function = render_function
self.render_template = render_template self.render_template = render_template
...@@ -241,7 +235,7 @@ def get_module(user, request, location, student_module_cache, position=None): ...@@ -241,7 +235,7 @@ def get_module(user, request, location, student_module_cache, position=None):
shared_state = shared_module.state if shared_module is not None else None shared_state = shared_module.state if shared_module is not None else None
# Setup system context for module instance # Setup system context for module instance
ajax_url = settings.MITX_ROOT_URL + '/modx/' + descriptor.type + '/' + descriptor.url + '/' ajax_url = settings.MITX_ROOT_URL + '/modx/' + descriptor.url + '/'
def _get_module(location): def _get_module(location):
(module, _, _, _) = get_module(user, request, location, student_module_cache, position) (module, _, _, _) = get_module(user, request, location, student_module_cache, position)
...@@ -330,94 +324,33 @@ def render_x_module(user, request, module_xml, student_module_cache, position=No ...@@ -330,94 +324,33 @@ def render_x_module(user, request, module_xml, student_module_cache, position=No
return context return context
def modx_dispatch(request, module=None, dispatch=None, id=None): def modx_dispatch(request, dispatch=None, id=None):
''' Generic view for extensions. This is where AJAX calls go. ''' Generic view for extensions. This is where AJAX calls go.
Arguments: Arguments:
- request -- the django request. - request -- the django request.
- module -- the type of the module, as used in the course configuration xml.
e.g. 'problem', 'video', etc
- dispatch -- the command string to pass through to the module's handle_ajax call - dispatch -- the command string to pass through to the module's handle_ajax call
(e.g. 'problem_reset'). If this string contains '?', only pass (e.g. 'problem_reset'). If this string contains '?', only pass
through the part before the first '?'. through the part before the first '?'.
- id -- the module id. Used to look up the student module. - id -- the module id. Used to look up the XModule instance
e.g. filenamexformularesponse
''' '''
# ''' (fix emacs broken parsing) # ''' (fix emacs broken parsing)
if not request.user.is_authenticated():
return redirect('/')
# python concats adjacent strings
error_msg = ("We're sorry, this module is temporarily unavailable. "
"Our staff is working to fix it as soon as possible")
# If there are arguments, get rid of them # If there are arguments, get rid of them
dispatch, _, _ = dispatch.partition('?') dispatch, _, _ = dispatch.partition('?')
ajax_url = '{root}/modx/{module}/{id}'.format(root=settings.MITX_ROOT_URL, student_module_cache = StudentModuleCache(request.user, keystore().get_item(id))
module=module, id=id) instance, instance_module, shared_module, module_type = get_module(request.user, request, id, student_module_cache)
coursename = multicourse_settings.get_coursename_from_request(request)
if coursename and settings.ENABLE_MULTICOURSE:
xp = multicourse_settings.get_course_xmlpath(coursename)
data_root = settings.DATA_DIR + xp
else:
data_root = settings.DATA_DIR
# Grab the XML corresponding to the request from course.xml if instance_module is None:
try: log.debug("Couldn't find module '%s' for user '%s'",
xml = content_parser.module_xml(request.user, module, 'id', id, coursename) id, request.user)
except:
log.exception(
"Unable to load module during ajax call. module=%s, dispatch=%s, id=%s",
module, dispatch, id)
if accepts(request, 'text/html'):
return render_to_response("module-error.html", {})
else:
response = HttpResponse(json.dumps({'success': error_msg}))
return response
module_xml = etree.fromstring(xml)
student_module_cache = StudentModuleCache(request.user, module_xml)
(instance, instance_state, shared_state, module_type) = get_module(
request.user, request, module_xml,
student_module_cache, None)
if instance_state is None:
log.debug("Couldn't find module '%s' for user '%s' and id '%s'",
module, request.user, id)
raise Http404 raise Http404
oldgrade = instance_state.grade oldgrade = instance_module.grade
old_instance_state = instance_state.state old_instance_state = instance_module.state
old_shared_state = shared_state.state if shared_state is not None else None old_shared_state = shared_module.state if shared_module is not None else None
module_from_xml = make_module_from_xml_fn(
request.user, request, student_module_cache, None)
# Create the module
system = I4xSystem(track_function=make_track_function(request),
render_function=None,
module_from_xml=module_from_xml,
render_template=render_to_string,
ajax_url=ajax_url,
request=request,
filestore=OSFS(data_root),
)
try:
module_class = xmodule.get_module_class(module)
instance = module_class(
system, xml, id,
instance_state=old_instance_state,
shared_state=old_shared_state)
except:
log.exception("Unable to load module instance during ajax call")
if accepts(request, 'text/html'):
return render_to_response("module-error.html", {})
else:
response = HttpResponse(json.dumps({'success': error_msg}))
return response
# Let the module handle the AJAX # Let the module handle the AJAX
try: try:
...@@ -427,16 +360,16 @@ def modx_dispatch(request, module=None, dispatch=None, id=None): ...@@ -427,16 +360,16 @@ def modx_dispatch(request, module=None, dispatch=None, id=None):
raise raise
# Save the state back to the database # Save the state back to the database
instance_state.state = instance.get_instance_state() instance_module.state = instance.get_instance_state()
if instance.get_score(): if instance.get_score():
instance_state.grade = instance.get_score()['score'] instance_module.grade = instance.get_score()['score']
if instance_state.grade != oldgrade or instance_state.state != old_instance_state: if instance_module.grade != oldgrade or instance_module.state != old_instance_state:
instance_state.save() instance_module.save()
if shared_state is not None: if shared_module is not None:
shared_state.state = instance.get_shared_state() shared_module.state = instance.get_shared_state()
if shared_state.state != old_shared_state: if shared_module.state != old_shared_state:
shared_state.save() shared_module.save()
# Return whatever the module wanted to return to the client/caller # Return whatever the module wanted to return to the client/caller
return HttpResponse(ajax_return) return HttpResponse(ajax_return)
...@@ -174,7 +174,7 @@ def quickedit(request, id=None, qetemplate='quickedit.html',coursename=None): ...@@ -174,7 +174,7 @@ def quickedit(request, id=None, qetemplate='quickedit.html',coursename=None):
module = 'problem' module = 'problem'
xml = content_parser.module_xml(request.user, module, 'id', id, coursename) xml = content_parser.module_xml(request.user, module, 'id', id, coursename)
ajax_url = settings.MITX_ROOT_URL + '/modx/'+module+'/'+id+'/' ajax_url = settings.MITX_ROOT_URL + '/modx/'+id+'/'
# Create the module (instance of capa_module.Module) # Create the module (instance of capa_module.Module)
system = I4xSystem(track_function = make_track_function(request), system = I4xSystem(track_function = make_track_function(request),
......
...@@ -20,8 +20,8 @@ class @Courseware ...@@ -20,8 +20,8 @@ class @Courseware
id = $(this).attr('id').replace(/video_/, '') id = $(this).attr('id').replace(/video_/, '')
new Video id, $(this).data('streams') new Video id, $(this).data('streams')
$('.course-content .problems-wrapper').each -> $('.course-content .problems-wrapper').each ->
id = $(this).attr('id').replace(/problem_/, '') id = $(this).attr('problem-id')
new Problem id, $(this).data('url') new Problem id, $(this).attr('id'), $(this).data('url')
$('.course-content .histogram').each -> $('.course-content .histogram').each ->
id = $(this).attr('id').replace(/histogram_/, '') id = $(this).attr('id').replace(/histogram_/, '')
new Histogram id, $(this).data('histogram') new Histogram id, $(this).data('histogram')
class @Problem class @Problem
constructor: (@id, url) -> constructor: (@id, @element_id, url) ->
@element = $("#problem_#{id}") @element = $("##{element_id}")
@render() @render()
$: (selector) -> $: (selector) ->
...@@ -26,13 +26,13 @@ class @Problem ...@@ -26,13 +26,13 @@ class @Problem
@element.html(content) @element.html(content)
@bind() @bind()
else else
$.postWithPrefix "/modx/problem/#{@id}/problem_get", (response) => $.postWithPrefix "/modx/#{@id}/problem_get", (response) =>
@element.html(response.html) @element.html(response.html)
@bind() @bind()
check: => check: =>
Logger.log 'problem_check', @answers Logger.log 'problem_check', @answers
$.postWithPrefix "/modx/problem/#{@id}/problem_check", @answers, (response) => $.postWithPrefix "/modx/#{@id}/problem_check", @answers, (response) =>
switch response.success switch response.success
when 'incorrect', 'correct' when 'incorrect', 'correct'
@render(response.contents) @render(response.contents)
...@@ -42,14 +42,14 @@ class @Problem ...@@ -42,14 +42,14 @@ class @Problem
reset: => reset: =>
Logger.log 'problem_reset', @answers Logger.log 'problem_reset', @answers
$.postWithPrefix "/modx/problem/#{@id}/problem_reset", id: @id, (response) => $.postWithPrefix "/modx/#{@id}/problem_reset", id: @id, (response) =>
@render(response.html) @render(response.html)
@updateProgress response @updateProgress response
show: => show: =>
if !@element.hasClass 'showed' if !@element.hasClass 'showed'
Logger.log 'problem_show', problem: @id Logger.log 'problem_show', problem: @id
$.postWithPrefix "/modx/problem/#{@id}/problem_show", (response) => $.postWithPrefix "/modx/#{@id}/problem_show", (response) =>
answers = response.answers answers = response.answers
$.each answers, (key, value) => $.each answers, (key, value) =>
if $.isArray(value) if $.isArray(value)
...@@ -69,7 +69,7 @@ class @Problem ...@@ -69,7 +69,7 @@ class @Problem
save: => save: =>
Logger.log 'problem_save', @answers Logger.log 'problem_save', @answers
$.postWithPrefix "/modx/problem/#{@id}/problem_save", @answers, (response) => $.postWithPrefix "/modx/#{@id}/problem_save", @answers, (response) =>
if response.success if response.success
alert 'Saved' alert 'Saved'
@updateProgress response @updateProgress response
...@@ -94,4 +94,4 @@ class @Problem ...@@ -94,4 +94,4 @@ class @Problem
element.schematic.update_value() element.schematic.update_value()
@$(".CodeMirror").each (index, element) -> @$(".CodeMirror").each (index, element) ->
element.CodeMirror.save() if element.CodeMirror.save element.CodeMirror.save() if element.CodeMirror.save
@answers = @$("[id^=input_#{@id}_]").serialize() @answers = @$("[id^=input_#{@element_id}_]").serialize()
...@@ -88,7 +88,7 @@ class @Sequence ...@@ -88,7 +88,7 @@ class @Sequence
if @position != new_position if @position != new_position
if @position != undefined if @position != undefined
@mark_visited @position @mark_visited @position
$.postWithPrefix "/modx/#{@tag}/#{@id}/goto_position", position: new_position $.postWithPrefix "/modx/#{@id}/goto_position", position: new_position
@mark_active new_position @mark_active new_position
@$('#seq_content').html @elements[new_position - 1].content @$('#seq_content').html @elements[new_position - 1].content
......
<section id="problem_${id}" class="problems-wrapper" data-url="${ajax_url}"></section> <section id="problem_${element_id}" class="problems-wrapper" problem-id="${id}" data-url="${ajax_url}"></section>
...@@ -57,7 +57,7 @@ if settings.COURSEWARE_ENABLED: ...@@ -57,7 +57,7 @@ if settings.COURSEWARE_ENABLED:
url(r'^courseware/(?P<course>[^/]*)/$', 'courseware.views.index', name="courseware_course"), url(r'^courseware/(?P<course>[^/]*)/$', 'courseware.views.index', name="courseware_course"),
url(r'^jumpto/(?P<probname>[^/]+)/$', 'courseware.views.jump_to'), url(r'^jumpto/(?P<probname>[^/]+)/$', 'courseware.views.jump_to'),
url(r'^section/(?P<section>[^/]*)/$', 'courseware.views.render_section'), url(r'^section/(?P<section>[^/]*)/$', 'courseware.views.render_section'),
url(r'^modx/(?P<module>[^/]*)/(?P<id>[^/]*)/(?P<dispatch>[^/]*)$', 'courseware.module_render.modx_dispatch'), #reset_problem'), url(r'^modx/(?P<id>.*?)/(?P<dispatch>[^/]*)$', 'courseware.module_render.modx_dispatch'), #reset_problem'),
url(r'^profile$', 'courseware.views.profile'), url(r'^profile$', 'courseware.views.profile'),
url(r'^profile/(?P<student_id>[^/]*)/$', 'courseware.views.profile'), url(r'^profile/(?P<student_id>[^/]*)/$', 'courseware.views.profile'),
url(r'^change_setting$', 'student.views.change_setting'), url(r'^change_setting$', 'student.views.change_setting'),
......
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