From 541f5ecdd28a1fdf9fc3e264886153f0e10c007d Mon Sep 17 00:00:00 2001 From: kimth Date: Thu, 2 Aug 2012 14:32:40 -0400 Subject: [PATCH] Filesubmission frontend --- common/lib/capa/capa/capa_problem.py | 2 +- common/lib/capa/capa/inputtypes.py | 13 +++++++ common/lib/capa/capa/responsetypes.py | 2 +- .../capa/capa/templates/filesubmission.html | 3 ++ .../xmodule/js/src/capa/display.coffee | 34 ++++++++++++++++++- lms/djangoapps/courseware/module_render.py | 10 ++++++ 6 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 common/lib/capa/capa/templates/filesubmission.html diff --git a/common/lib/capa/capa/capa_problem.py b/common/lib/capa/capa/capa_problem.py index ed99c71635..55b9096021 100644 --- a/common/lib/capa/capa/capa_problem.py +++ b/common/lib/capa/capa/capa_problem.py @@ -39,7 +39,7 @@ import responsetypes # dict of tagname, Response Class -- this should come from auto-registering response_tag_dict = dict([(x.response_tag, x) for x in responsetypes.__all__]) -entry_types = ['textline', 'schematic', 'textbox', 'imageinput', 'optioninput', 'choicegroup', 'radiogroup', 'checkboxgroup'] +entry_types = ['textline', 'schematic', 'textbox', 'imageinput', 'optioninput', 'choicegroup', 'radiogroup', 'checkboxgroup', 'filesubmission'] solution_types = ['solution'] # extra things displayed after "show answers" is pressed response_properties = ["responseparam", "answer"] # these get captured as student responses diff --git a/common/lib/capa/capa/inputtypes.py b/common/lib/capa/capa/inputtypes.py index 8b3867be5b..32ee479414 100644 --- a/common/lib/capa/capa/inputtypes.py +++ b/common/lib/capa/capa/inputtypes.py @@ -299,6 +299,19 @@ def textline_dynamath(element, value, status, render_template, msg=''): return etree.XML(html) +#----------------------------------------------------------------------------- +@register_render_function +def filesubmission(element, value, status, render_template, msg=''): + ''' + Upload a single file (e.g. for programming assignments) + ''' + eid = element.get('id') + + context = {'id': eid, } + html = render_template("filesubmission.html", context) + return etree.XML(html) + + #----------------------------------------------------------------------------- ## TODO: Make a wrapper for @register_render_function diff --git a/common/lib/capa/capa/responsetypes.py b/common/lib/capa/capa/responsetypes.py index bb62cdfa1c..578352eb44 100644 --- a/common/lib/capa/capa/responsetypes.py +++ b/common/lib/capa/capa/responsetypes.py @@ -805,7 +805,7 @@ class CodeResponse(LoncapaResponse): ''' response_tag = 'coderesponse' - allowed_inputfields = ['textline', 'textbox'] + allowed_inputfields = ['textbox', 'filesubmission'] max_inputfields = 1 def setup_response(self): diff --git a/common/lib/capa/capa/templates/filesubmission.html b/common/lib/capa/capa/templates/filesubmission.html new file mode 100644 index 0000000000..f9073799d4 --- /dev/null +++ b/common/lib/capa/capa/templates/filesubmission.html @@ -0,0 +1,3 @@ +
+
+
diff --git a/common/lib/xmodule/xmodule/js/src/capa/display.coffee b/common/lib/xmodule/xmodule/js/src/capa/display.coffee index 4ee8257e36..d23c096eec 100644 --- a/common/lib/xmodule/xmodule/js/src/capa/display.coffee +++ b/common/lib/xmodule/xmodule/js/src/capa/display.coffee @@ -13,7 +13,7 @@ class @Problem MathJax.Hub.Queue ["Typeset", MathJax.Hub] window.update_schematics() @$('section.action input:button').click @refreshAnswers - @$('section.action input.check').click @check + @$('section.action input.check').click @check_fd @$('section.action input.reset').click @reset @$('section.action input.show').click @show @$('section.action input.save').click @save @@ -45,6 +45,38 @@ class @Problem $('head')[0].appendChild(s[0]) $(placeholder).remove() + check_fd: => + Logger.log 'problem_check', @answers + + if not window.FormData + alert "Sorry, your browser does not support file uploads. If you can, please use Chrome or Safari which have been verified to support this feature." + return + + fd = new FormData() + + # For each file input, allow a single file submission, + # routed to Django 'request.FILES' + @$('input:file').each (index, element) -> + fd.append(element.id, element.files[0]) + + # Simple (non-file) answers, + # routed to Django 'request.POST' + fd.append('answers', @answers) + + settings = + type: "POST" + data: fd + processData: false + contentType: false + success: (response) -> + switch response.success + when 'incorrect', 'correct' + @render(response.contents) + @updateProgress response + else + alert(response.success) + $.ajaxWithPrefix("#{@url}/problem_check", settings) + check: => Logger.log 'problem_check', @answers $.postWithPrefix "#{@url}/problem_check", @answers, (response) => diff --git a/lms/djangoapps/courseware/module_render.py b/lms/djangoapps/courseware/module_render.py index 80a4ef90fc..5b030161db 100644 --- a/lms/djangoapps/courseware/module_render.py +++ b/lms/djangoapps/courseware/module_render.py @@ -270,6 +270,16 @@ def modx_dispatch(request, dispatch=None, id=None): - id -- the module id. Used to look up the XModule instance ''' # ''' (fix emacs broken parsing) + + print ' THK: module_render.modx_dispatch' + print dispatch + print request.POST.keys() + print request.FILES.keys() + if request.POST.has_key('answers'): + print request.POST['answers'] + for filename in request.FILES.keys(): + uploadedFile = request.FILES.get(filename) + print uploadedFile.read() student_module_cache = StudentModuleCache(request.user, modulestore().get_item(id)) instance, instance_module, shared_module, module_type = get_module(request.user, request, id, student_module_cache)