From 11ffc6bb88ebfa5ff91a02d761741266d5bada79 Mon Sep 17 00:00:00 2001 From: Arjun Singh Date: Tue, 21 Aug 2012 02:40:21 -0700 Subject: [PATCH] Allowing filesubmissions to specify which files are allowed and require that certain files are present. --- common/lib/capa/capa/inputtypes.py | 9 ++++++- .../capa/capa/templates/filesubmission.html | 2 +- .../xmodule/js/src/capa/display.coffee | 24 ++++++++++++++++--- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/common/lib/capa/capa/inputtypes.py b/common/lib/capa/capa/inputtypes.py index 8c513e7aec..7b89510a12 100644 --- a/common/lib/capa/capa/inputtypes.py +++ b/common/lib/capa/capa/inputtypes.py @@ -29,6 +29,7 @@ Each input type takes the xml tree as 'element', the previous answer as 'value', import logging import re import shlex # for splitting quoted strings +import json from lxml import etree import xml.sax.saxutils as saxutils @@ -336,6 +337,11 @@ def filesubmission(element, value, status, render_template, msg=''): Upload a single file (e.g. for programming assignments) ''' eid = element.get('id') + escapedict = {'"': '"'} + allowed_files = json.dumps(element.get('allowed_files', '').split()) + allowed_files = saxutils.escape(allowed_files, escapedict) + required_files = json.dumps(element.get('required_files', '').split()) + required_files = saxutils.escape(required_files, escapedict) # Check if problem has been queued queue_len = 0 @@ -345,7 +351,8 @@ def filesubmission(element, value, status, render_template, msg=''): msg = 'Submitted to grader. (Queue length: %s)' % queue_len context = { 'id': eid, 'state': status, 'msg': msg, 'value': value, - 'queue_len': queue_len + 'queue_len': queue_len, 'allowed_files': allowed_files, + 'required_files': required_files } html = render_template("filesubmission.html", context) return etree.XML(html) diff --git a/common/lib/capa/capa/templates/filesubmission.html b/common/lib/capa/capa/templates/filesubmission.html index fccf469015..a859dc8458 100644 --- a/common/lib/capa/capa/templates/filesubmission.html +++ b/common/lib/capa/capa/templates/filesubmission.html @@ -1,5 +1,5 @@
-
+
% if state == 'unsubmitted': % elif state == 'correct': diff --git a/common/lib/xmodule/xmodule/js/src/capa/display.coffee b/common/lib/xmodule/xmodule/js/src/capa/display.coffee index a242757357..23fa4d70fe 100644 --- a/common/lib/xmodule/xmodule/js/src/capa/display.coffee +++ b/common/lib/xmodule/xmodule/js/src/capa/display.coffee @@ -160,24 +160,42 @@ class @Problem max_filesize = 4*1000*1000 # 4 MB file_too_large = false file_not_selected = false + required_files_not_submitted = false + unallowed_file_submitted = false + + errors = [] @inputs.each (index, element) -> if element.type is 'file' + required_files = $(element).data("required_files") + allowed_files = $(element).data("allowed_files") for file in element.files + if allowed_files.length != 0 and file.name not in allowed_files + unallowed_file_submitted = true + errors.push "You submitted #{file.name}; only #{allowed_files} are allowed." + if file.name in required_files + required_files.splice(required_files.indexOf(file.name), 1) if file.size > max_filesize file_too_large = true - alert 'Submission aborted! Your file "' + file.name '" is too large (max size: ' + max_filesize/(1000*1000) + ' MB)' + errors.push 'Your file "' + file.name '" is too large (max size: ' + max_filesize/(1000*1000) + ' MB)' fd.append(element.id, file) if element.files.length == 0 file_not_selected = true fd.append(element.id, '') # In case we want to allow submissions with no file + if required_files.length != 0 + required_files_not_submitted = true + errors.push "You did not submit the required files: #{required_files}." else fd.append(element.id, element.value) + if file_not_selected - alert 'Submission aborted! You did not select any files to submit' + errors.push 'You did not select any files to submit' - abort_submission = file_too_large or file_not_selected + if errors.length > 0 + alert errors.join("\n") + + abort_submission = file_too_large or file_not_selected or unallowed_file_submitted or required_files_not_submitted settings = type: "POST"