~azzar1/unity/add-show-desktop-key

294 by mattgiuca
Added application: tutorialservice. Will be used as the Ajax backend for
1
# IVLE - Informatics Virtual Learning Environment
2
# Copyright (C) 2007-2008 The University of Melbourne
3
#
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
18
# Module: TutorialService
19
# Author: Matt Giuca
20
# Date:   25/1/2008
21
22
# Provides the AJAX backend for the tutorial application.
300 by mattgiuca
conf/apps: Added TutorialService as a registered app.
23
# This allows several actions to be performed on the code the student has
24
# typed into one of the problem boxes.
25
26
# Calling syntax
301 by mattgiuca
tutorialservice: Now parses and executes the students code using the test
27
# Path must be empty.
300 by mattgiuca
conf/apps: Added TutorialService as a registered app.
28
# The arguments determine what is to be done on this file.
29
301 by mattgiuca
tutorialservice: Now parses and executes the students code using the test
30
# "problem" - The path to a problem file (including the .xml extension),
31
#    relative to the subjects base directory.
300 by mattgiuca
conf/apps: Added TutorialService as a registered app.
32
# "code" - Full text of the student's code being submitted.
33
# "action". May be "test". (More to come).
34
35
# Returns a JSON response string indicating the results.
36
301 by mattgiuca
tutorialservice: Now parses and executes the students code using the test
37
import os
38
300 by mattgiuca
conf/apps: Added TutorialService as a registered app.
39
import cjson
40
301 by mattgiuca
tutorialservice: Now parses and executes the students code using the test
41
import test
42
import conf
43
300 by mattgiuca
conf/apps: Added TutorialService as a registered app.
44
def handle(req):
45
    """Handler for Ajax backend TutorialService app."""
46
    # Set request attributes
47
    req.write_html_head_foot = False     # No HTML
48
301 by mattgiuca
tutorialservice: Now parses and executes the students code using the test
49
    if req.path != "":
50
        req.throw_error(req.HTTP_BAD_REQUEST)
300 by mattgiuca
conf/apps: Added TutorialService as a registered app.
51
    # Get all the arguments, if POST.
52
    # Ignore arguments if not POST, since we aren't allowed to cause
53
    # side-effects on the server.
54
    fields = req.get_fieldstorage()
55
    act = fields.getfirst('action')
301 by mattgiuca
tutorialservice: Now parses and executes the students code using the test
56
    problem = fields.getfirst('problem')
300 by mattgiuca
conf/apps: Added TutorialService as a registered app.
57
    code = fields.getfirst('code')
58
301 by mattgiuca
tutorialservice: Now parses and executes the students code using the test
59
    if problem == None or code == None or act == None:
300 by mattgiuca
conf/apps: Added TutorialService as a registered app.
60
        req.throw_error(req.HTTP_BAD_REQUEST)
61
    act = act.value
301 by mattgiuca
tutorialservice: Now parses and executes the students code using the test
62
    problem = problem.value
300 by mattgiuca
conf/apps: Added TutorialService as a registered app.
63
    code = code.value
64
65
    if act == "test":
301 by mattgiuca
tutorialservice: Now parses and executes the students code using the test
66
        handle_test(req, problem, code, fields)
300 by mattgiuca
conf/apps: Added TutorialService as a registered app.
67
    else:
68
        req.throw_error(req.HTTP_BAD_REQUEST)
69
301 by mattgiuca
tutorialservice: Now parses and executes the students code using the test
70
def handle_test(req, problem, code, fields):
300 by mattgiuca
conf/apps: Added TutorialService as a registered app.
71
    """Handles a test action."""
301 by mattgiuca
tutorialservice: Now parses and executes the students code using the test
72
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):
77
        problemfile = None
78
    else:
79
        problemfile = os.path.join(conf.subjects_base, problem)
80
81
    try:
82
        problemfile = open(problemfile)
83
    except (TypeError, IOError):    # TypeError if problemfile == None
84
        req.throw_error(req.HTTP_NOT_FOUND)
85
86
    # Parse the file into a problem object using the test suite
87
    problem_obj = test.parse_tutorial_file(problemfile)
88
    problemfile.close()
89
    # Run the test cases. Get the result back as a JSONable object.
90
    # Return it.
91
    test_results = problem_obj.run_tests(code)
92
    req.write(cjson.encode(test_results))