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

« back to all changes in this revision

Viewing changes to ivle/webapp/tutorial/service.py

  • Committer: mattgiuca
  • Date: 2008-01-11 00:49:06 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:172
util: Added buildurl function.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# IVLE - Informatics Virtual Learning Environment
2
 
# Copyright (C) 2007-2009 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
 
# Author: Matt Giuca, Nick Chadwick
19
 
 
20
 
'''AJAX backend for the tutorial application.'''
21
 
 
22
 
import os
23
 
import datetime
24
 
 
25
 
import ivle.util
26
 
import ivle.console
27
 
import ivle.database
28
 
import ivle.worksheet
29
 
import ivle.conf
30
 
import ivle.webapp.tutorial.test
31
 
 
32
 
from ivle.webapp.base.rest import (JSONRESTView, named_operation,
33
 
                                   require_permission)
34
 
from ivle.webapp.errors import NotFound
35
 
 
36
 
# If True, getattempts or getattempt will allow browsing of inactive/disabled
37
 
# attempts. If False, will not allow this.
38
 
HISTORY_ALLOW_INACTIVE = False
39
 
 
40
 
TIMESTAMP_FORMAT = '%Y-%m-%d %H:%M:%S'
41
 
 
42
 
 
43
 
class AttemptsRESTView(JSONRESTView):
44
 
    '''REST view of a user's attempts at an exercise.'''
45
 
    def __init__(self, req, subject, worksheet, exercise, username):
46
 
        # TODO: Find exercise within worksheet.
47
 
        self.user = ivle.database.User.get_by_login(req.store, username)
48
 
        if self.user is None:
49
 
            raise NotFound()
50
 
        self.exercise = exercise
51
 
        self.context = self.user # XXX: Not quite right.
52
 
 
53
 
    @require_permission('edit')
54
 
    def GET(self, req):
55
 
        """Handles a GET Attempts action."""
56
 
        exercise = ivle.database.Exercise.get_by_name(req.store, 
57
 
                                                        self.exercise)
58
 
 
59
 
        attempts = ivle.worksheet.get_exercise_attempts(req.store, self.user,
60
 
                            exercise, allow_inactive=HISTORY_ALLOW_INACTIVE)
61
 
        # attempts is a list of ExerciseAttempt objects. Convert to dictionaries
62
 
        time_fmt = lambda dt: datetime.datetime.strftime(dt, TIMESTAMP_FORMAT)
63
 
        attempts = [{'date': time_fmt(a.date), 'complete': a.complete}
64
 
                for a in attempts]
65
 
 
66
 
        return attempts
67
 
 
68
 
 
69
 
    @require_permission('edit')
70
 
    def PUT(self, req, data):
71
 
        """ Tests the given submission """
72
 
        exercisefile = ivle.util.open_exercise_file(self.exercise)
73
 
        if exercisefile is None:
74
 
            raise NotFound()
75
 
 
76
 
        # Start a console to run the tests on
77
 
        jail_path = os.path.join(ivle.conf.jail_base, req.user.login)
78
 
        working_dir = os.path.join("/home", req.user.login)
79
 
        cons = ivle.console.Console(req.user.unixid, jail_path, working_dir)
80
 
 
81
 
        # Parse the file into a exercise object using the test suite
82
 
        exercise_obj = ivle.webapp.tutorial.test.parse_exercise_file(
83
 
                                                            exercisefile, cons)
84
 
        exercisefile.close()
85
 
 
86
 
        # Run the test cases. Get the result back as a JSONable object.
87
 
        # Return it.
88
 
        test_results = exercise_obj.run_tests(data['code'])
89
 
 
90
 
        # Close the console
91
 
        cons.close()
92
 
 
93
 
        # Get the Exercise from the database
94
 
        exercise = ivle.database.Exercise.get_by_name(req.store, self.exercise)
95
 
 
96
 
        attempt = ivle.database.ExerciseAttempt(user=req.user,
97
 
                                                exercise=exercise,
98
 
                                                date=datetime.datetime.now(),
99
 
                                                complete=test_results['passed'],
100
 
                                                # XXX
101
 
                                                text=unicode(data['code']))
102
 
 
103
 
        req.store.add(attempt)
104
 
 
105
 
        # Query the DB to get an updated score on whether or not this problem
106
 
        # has EVER been completed (may be different from "passed", if it has
107
 
        # been completed before), and the total number of attempts.
108
 
        completed, attempts = ivle.worksheet.get_exercise_status(req.store,
109
 
            req.user, exercise)
110
 
        test_results["completed"] = completed
111
 
        test_results["attempts"] = attempts
112
 
 
113
 
        return test_results
114
 
 
115
 
 
116
 
class AttemptRESTView(JSONRESTView):
117
 
    '''REST view of an exercise attempt.'''
118
 
 
119
 
    def __init__(self, req, subject, worksheet, exercise, username, date):
120
 
        # TODO: Find exercise within worksheet.
121
 
        user = ivle.database.User.get_by_login(req.store, username)
122
 
        if user is None:
123
 
            raise NotFound()
124
 
 
125
 
        try:
126
 
            date = datetime.datetime.strptime(date, TIMESTAMP_FORMAT)
127
 
        except ValueError:
128
 
            raise NotFound()
129
 
 
130
 
        exercise = ivle.database.Exercise.get_by_name(req.store, exercise)
131
 
        attempt = ivle.worksheet.get_exercise_attempt(req.store, user,
132
 
            exercise, as_of=date, allow_inactive=HISTORY_ALLOW_INACTIVE)
133
 
 
134
 
        if attempt is None:
135
 
            raise NotFound()
136
 
 
137
 
        self.context = attempt
138
 
 
139
 
    @require_permission('view')
140
 
    def GET(self, req):
141
 
        return {'code': self.context.text}
142
 
 
143
 
 
144
 
class ExerciseRESTView(JSONRESTView):
145
 
    '''REST view of an exercise.'''
146
 
 
147
 
    def get_permissions(self, user):
148
 
        # XXX: Do it properly.
149
 
        if user is not None:
150
 
            return set(['save'])
151
 
        else:
152
 
            return set()
153
 
 
154
 
    @named_operation('save')
155
 
    def save(self, req, text):
156
 
        # Need to open JUST so we know this is a real exercise.
157
 
        # (This avoids users submitting code for bogus exercises).
158
 
        exercisefile = ivle.util.open_exercise_file(self.exercise)
159
 
        if exercisefile is None:
160
 
            raise NotFound()
161
 
        exercisefile.close()
162
 
 
163
 
        exercise = ivle.database.Exercise.get_by_name(req.store, self.exercise)
164
 
        ivle.worksheet.save_exercise(req.store, req.user, exercise,
165
 
                                     unicode(text), datetime.datetime.now())
166
 
        return {"result": "ok"}