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

1294.2.71 by William Grant
Move i.w.tutorial traversal stuff into i.w.tutorial.traversal.
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
import datetime
19
20
from storm.locals import Store
21
22
from ivle.database import (Exercise, ExerciseAttempt, Offering, User,
23
                           Worksheet, WorksheetExercise)
24
25
from ivle.webapp import ApplicationRoot
1294.3.2 by William Grant
Router->Publisher
26
from ivle.webapp.publisher import ROOT
27
from ivle.webapp.publisher.decorators import forward_route, reverse_route
1294.2.71 by William Grant
Move i.w.tutorial traversal stuff into i.w.tutorial.traversal.
28
29
import ivle.worksheet
30
31
from ivle.webapp.tutorial.service import TIMESTAMP_FORMAT
32
33
# If True, getattempts or getattempt will allow browsing of inactive/disabled
34
# attempts. If False, will not allow this.
35
HISTORY_ALLOW_INACTIVE = False
36
37
@forward_route(ApplicationRoot, '+exercises', argc=1)
38
def root_to_exercise(root, exercise_name):
39
    return root.store.find(
40
        Exercise,
41
        Exercise.id == exercise_name
42
        ).one()
43
44
@reverse_route(Exercise)
45
def exercise_url(exercise):
46
    return (ROOT, ('+exercises', exercise.id))
47
48
49
@forward_route(Offering, '+worksheets', argc=1)
50
def offering_to_worksheet(offering, worksheet_name):
51
    return Store.of(offering).find(
52
        Worksheet,
53
        Worksheet.offering == offering,
54
        Worksheet.identifier == worksheet_name
55
        ).one()
56
57
@reverse_route(Worksheet)
58
def worksheet_url(worksheet):
59
    return (worksheet.offering, ('+worksheets', worksheet.identifier))
60
61
62
@forward_route(Worksheet, argc=1)
63
def worksheet_to_worksheetexercise(worksheet, exercise_name):
64
    return Store.of(worksheet).find(
65
        WorksheetExercise,
66
        WorksheetExercise.exercise_id == exercise_name,
67
        WorksheetExercise.worksheet == worksheet
68
        ).one()
69
70
@reverse_route(WorksheetExercise)
71
def worksheetexercise_url(worksheetexercise):
72
    return (worksheetexercise.worksheet,
73
            worksheetexercise.exercise.identifier)
74
75
76
class ExerciseAttempts(object):
77
    """The set of exercise attempts for a user and exercise.
78
79
    A combination of a User and WorksheetExercise, this provides access to
80
    the User's ExerciseAttempts.
81
    """
82
83
    def __init__(self, worksheet_exercise, user):
84
        self.worksheet_exercise = worksheet_exercise
85
        self.user = user
86
1544 by Matt Giuca
Added an argument 'config' to every single get_permissions method throughout the program. All calls to get_permissions pass a config. This is to allow per-site policy configurations on permissions.
87
    def get_permissions(self, user, config):
88
        return self.user.get_permissions(user, config)
1294.2.71 by William Grant
Move i.w.tutorial traversal stuff into i.w.tutorial.traversal.
89
90
91
@forward_route(WorksheetExercise, '+attempts', argc=1)
92
def worksheetexercise_to_exerciseattempts(worksheet_exercise, login):
93
    user = User.get_by_login(Store.of(worksheet_exercise), login)
94
    if user is None:
95
        return None
96
    return ExerciseAttempts(worksheet_exercise, user)
97
98
@reverse_route(ExerciseAttempts)
99
def exerciseattempts_url(exerciseattempts):
100
    return (exerciseattempts.worksheet_exercise,
101
            ('+attempts', exerciseattempts.user.login))
102
103
104
@forward_route(ExerciseAttempts, argc=1)
105
def exerciseattempts_to_attempt(exercise_attempts, date):
106
    try:
107
        date = datetime.datetime.strptime(date, TIMESTAMP_FORMAT)
108
    except ValueError:
109
        return None
110
111
    # XXX Hack around Google Code issue #87
112
    # Query from the given date +1 secnod.
113
    # Date is in seconds (eg. 3:47:12), while the data is in finer time
114
    # (eg. 3:47:12.3625). The query "date <= 3:47:12" will fail because
115
    # 3:47:12.3625 is greater. Hence we do the query from +1 second,
116
    # "date <= 3:47:13", and it finds the correct submission, UNLESS there
117
    # are multiple submissions inside the same second.
118
    date += datetime.timedelta(seconds=1)
119
120
    return ivle.worksheet.utils.get_exercise_attempt(
121
                Store.of(exercise_attempts.user),
122
                exercise_attempts.user, exercise_attempts.worksheet_exercise,
123
                as_of=date, allow_inactive=HISTORY_ALLOW_INACTIVE)
124
125
@reverse_route(ExerciseAttempt)
126
def exerciseattempt_url(exerciseattempt):
127
    return (ExerciseAttempts(exerciseattempt.worksheet_exercise,
128
                             exerciseattempt.user),
129
            exerciseattempt.date.strftime(TIMESTAMP_FORMAT)
130
            )