29
29
from storm.locals import Desc
30
from genshi.filters import HTMLFormFiller
31
33
from ivle.webapp.base.xhtml import XHTMLView
32
34
from ivle.webapp.base.plugins import ViewPlugin, MediaPlugin
33
35
from ivle.webapp.errors import NotFound
34
from ivle.database import Subject, Semester
36
from ivle.database import Subject, Semester, Offering, Enrolment, User
35
37
from ivle import util
52
54
if enrolments.count():
53
55
ctx['semesters'].append((semester, enrolments))
58
class UserValidator(formencode.FancyValidator):
59
"""A FormEncode validator that turns a username into a user.
61
The state must have a 'store' attribute, which is the Storm store
63
def _to_python(self, value, state):
64
user = User.get_by_login(state.store, value)
68
raise formencode.Invalid('That user does not exist', value, state)
71
class EnrolSchema(formencode.Schema):
72
user = UserValidator()
75
class EnrolView(XHTMLView):
76
"""A form to enrol a user in an offering."""
77
template = 'enrol.html'
81
def __init__(self, req, subject, year, semester):
82
"""Find the given offering by subject, year and semester."""
83
self.context = req.store.find(Offering,
84
Offering.subject_id == Subject.id,
85
Subject.short_name == subject,
86
Offering.semester_id == Semester.id,
87
Semester.year == year,
88
Semester.semester == semester).one()
93
def filter(self, stream, ctx):
94
return stream | HTMLFormFiller(data=ctx['data'])
96
def populate(self, req, ctx):
97
if req.method == 'POST':
98
data = dict(req.get_fieldstorage())
100
validator = EnrolSchema()
101
data = validator.to_python(data, state=req)
102
self.context.enrol(data['user'])
104
req.throw_redirect(req.uri)
105
except formencode.Invalid, e:
106
errors = e.unpack_errors()
111
ctx['data'] = data or {}
112
ctx['offering'] = self.context
113
ctx['errors'] = errors
55
116
class Plugin(ViewPlugin, MediaPlugin):
57
118
('subjects/', SubjectsView),
119
('subjects/:subject/:year/:semester/+enrolments/+new', EnrolView),