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

« back to all changes in this revision

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

  • Committer: William Grant
  • Date: 2009-04-07 03:48:23 UTC
  • mfrom: (1165.1.46 submissions)
  • Revision ID: grantw@unimelb.edu.au-20090407034823-snd6wa5p6otzq073
Allow students to submit projects from personal or group repositories.

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
 
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
26
 
from ivle.webapp.publisher import ROOT
27
 
from ivle.webapp.publisher.decorators import forward_route, reverse_route
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
 
 
87
 
    def get_permissions(self, user, config):
88
 
        return self.user.get_permissions(user, config)
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
 
            )