Commit 11ffc6bb by Arjun Singh

Allowing filesubmissions to specify which files are allowed and require that…

Allowing filesubmissions to specify which files are allowed and require that certain files are present.
parent b29e547d
...@@ -29,6 +29,7 @@ Each input type takes the xml tree as 'element', the previous answer as 'value', ...@@ -29,6 +29,7 @@ Each input type takes the xml tree as 'element', the previous answer as 'value',
import logging import logging
import re import re
import shlex # for splitting quoted strings import shlex # for splitting quoted strings
import json
from lxml import etree from lxml import etree
import xml.sax.saxutils as saxutils import xml.sax.saxutils as saxutils
...@@ -336,6 +337,11 @@ def filesubmission(element, value, status, render_template, msg=''): ...@@ -336,6 +337,11 @@ def filesubmission(element, value, status, render_template, msg=''):
Upload a single file (e.g. for programming assignments) Upload a single file (e.g. for programming assignments)
''' '''
eid = element.get('id') 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 # Check if problem has been queued
queue_len = 0 queue_len = 0
...@@ -345,7 +351,8 @@ def filesubmission(element, value, status, render_template, msg=''): ...@@ -345,7 +351,8 @@ def filesubmission(element, value, status, render_template, msg=''):
msg = 'Submitted to grader. (Queue length: %s)' % queue_len msg = 'Submitted to grader. (Queue length: %s)' % queue_len
context = { 'id': eid, 'state': status, 'msg': msg, 'value': value, 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) html = render_template("filesubmission.html", context)
return etree.XML(html) return etree.XML(html)
......
<section id="filesubmission_${id}" class="filesubmission"> <section id="filesubmission_${id}" class="filesubmission">
<input type="file" name="input_${id}" id="input_${id}" value="${value}" multiple="multiple" /><br /> <input type="file" name="input_${id}" id="input_${id}" value="${value}" multiple="multiple" data-required_files="${required_files}" data-allowed_files="${allowed_files}"/><br />
% if state == 'unsubmitted': % if state == 'unsubmitted':
<span class="unanswered" style="display:inline-block;" id="status_${id}"></span> <span class="unanswered" style="display:inline-block;" id="status_${id}"></span>
% elif state == 'correct': % elif state == 'correct':
......
...@@ -160,24 +160,42 @@ class @Problem ...@@ -160,24 +160,42 @@ class @Problem
max_filesize = 4*1000*1000 # 4 MB max_filesize = 4*1000*1000 # 4 MB
file_too_large = false file_too_large = false
file_not_selected = false file_not_selected = false
required_files_not_submitted = false
unallowed_file_submitted = false
errors = []
@inputs.each (index, element) -> @inputs.each (index, element) ->
if element.type is 'file' if element.type is 'file'
required_files = $(element).data("required_files")
allowed_files = $(element).data("allowed_files")
for file in element.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 if file.size > max_filesize
file_too_large = true 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) fd.append(element.id, file)
if element.files.length == 0 if element.files.length == 0
file_not_selected = true file_not_selected = true
fd.append(element.id, '') # In case we want to allow submissions with no file 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 else
fd.append(element.id, element.value) fd.append(element.id, element.value)
if file_not_selected 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'
if errors.length > 0
alert errors.join("\n")
abort_submission = file_too_large or file_not_selected abort_submission = file_too_large or file_not_selected or unallowed_file_submitted or required_files_not_submitted
settings = settings =
type: "POST" type: "POST"
......
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