35
35
require_permission)
36
36
from ivle.webapp.errors import NotFound
38
# If True, getattempts or getattempt will allow browsing of inactive/disabled
39
# attempts. If False, will not allow this.
40
HISTORY_ALLOW_INACTIVE = False
42
39
TIMESTAMP_FORMAT = '%Y-%m-%d %H:%M:%S'
45
class ExerciseAttempts(object):
46
"""The set of exercise attempts for a user and exercise.
48
A combination of a User and WorksheetExercise, this provides access to
49
the User's ExerciseAttempts.
52
def __init__(self, worksheet_exercise, user):
53
self.worksheet_exercise = worksheet_exercise
56
def get_permissions(self, user):
57
return self.user.get_permissions(user)
60
def exerciseattempts_to_attempt(exercise_attempts, date):
62
date = datetime.datetime.strptime(date, TIMESTAMP_FORMAT)
66
# XXX Hack around Google Code issue #87
67
# Query from the given date +1 secnod.
68
# Date is in seconds (eg. 3:47:12), while the data is in finer time
69
# (eg. 3:47:12.3625). The query "date <= 3:47:12" will fail because
70
# 3:47:12.3625 is greater. Hence we do the query from +1 second,
71
# "date <= 3:47:13", and it finds the correct submission, UNLESS there
72
# are multiple submissions inside the same second.
73
date += datetime.timedelta(seconds=1)
75
return ivle.worksheet.utils.get_exercise_attempt(
76
Store.of(exercise_attempts.user),
77
exercise_attempts.user, exercise_attempts.worksheet_exercise,
78
as_of=date, allow_inactive=HISTORY_ALLOW_INACTIVE)
81
def worksheet_exercise_to_user_attempts(worksheet_exercise, login):
82
user = User.get_by_login(Store.of(worksheet_exercise), login)
85
return ExerciseAttempts(worksheet_exercise, user)
88
def worksheet_to_worksheet_exercise(worksheet, exercise_name):
89
return Store.of(worksheet).find(
91
WorksheetExercise.exercise_id == exercise_name,
92
WorksheetExercise.worksheet == worksheet
96
41
class AttemptsRESTView(JSONRESTView):
97
42
'''REST view of a user's attempts at an exercise.'''