24
24
# typed into one of the problem boxes.
27
# The "path" to this app is the path to a problem file (including the .xml
28
# extension), relative to the subjects base directory.
29
28
# The arguments determine what is to be done on this file.
30
# "problem" - The path to a problem file (including the .xml extension),
31
# relative to the subjects base directory.
31
32
# "code" - Full text of the student's code being submitted.
32
33
# "action". May be "test". (More to come).
34
35
# Returns a JSON response string indicating the results.
39
45
"""Handler for Ajax backend TutorialService app."""
40
46
# Set request attributes
41
47
req.write_html_head_foot = False # No HTML
50
req.throw_error(req.HTTP_BAD_REQUEST)
43
51
# Get all the arguments, if POST.
44
52
# Ignore arguments if not POST, since we aren't allowed to cause
45
53
# side-effects on the server.
46
54
fields = req.get_fieldstorage()
47
55
act = fields.getfirst('action')
56
problem = fields.getfirst('problem')
48
57
code = fields.getfirst('code')
50
if code == None or act == None:
59
if problem == None or code == None or act == None:
51
60
req.throw_error(req.HTTP_BAD_REQUEST)
62
problem = problem.value
56
handle_test(req, code, fields)
66
handle_test(req, problem, code, fields)
58
68
req.throw_error(req.HTTP_BAD_REQUEST)
60
def handle_test(req, code, fields):
70
def handle_test(req, problem, code, fields):
61
71
"""Handles a test action."""
62
# TEMP: Just echo the code back in JSON form
63
req.write(cjson.encode({"code": code}))
73
# First normalise the path
74
problem = os.path.normpath(problem)
75
# Now if it begins with ".." or separator, then it's illegal
76
if problem.startswith("..") or problem.startswith(os.sep):
79
problemfile = os.path.join(conf.subjects_base, problem)
82
problemfile = open(problemfile)
83
except (TypeError, IOError): # TypeError if problemfile == None
84
req.throw_error(req.HTTP_NOT_FOUND)
86
# Parse the file into a problem object using the test suite
87
problem_obj = test.parse_tutorial_file(problemfile)
89
# Run the test cases. Get the result back as a JSONable object.
91
test_results = problem_obj.run_tests(code)
92
req.write(cjson.encode(test_results))