29
29
from storm.locals import Desc
31
30
from genshi.filters import HTMLFormFiller
32
from genshi.template import Context, TemplateLoader
35
33
from ivle.webapp.base.xhtml import XHTMLView
36
34
from ivle.webapp.base.plugins import ViewPlugin, MediaPlugin
37
35
from ivle.webapp.errors import NotFound
39
from ivle.database import Subject, Semester, Offering, Enrolment, User,\
40
ProjectSet, Project, ProjectSubmission
44
from ivle.webapp.admin.projectservice import ProjectSetRESTView,\
46
from ivle.webapp.admin.offeringservice import OfferingRESTView
36
from ivle.database import Subject, Semester, Offering, Enrolment, User
49
39
class SubjectsView(XHTMLView):
50
40
'''The view of the list of subjects.'''
51
template = 'templates/subjects.html'
41
template = 'subjects.html'
54
44
def authorize(self, req):
133
123
ctx['offering'] = self.context
134
124
ctx['errors'] = errors
136
class OfferingProjectsView(XHTMLView):
137
"""View the projects for an offering."""
138
template = 'templates/offering_projects.html'
142
def __init__(self, req, subject, year, semester):
143
self.context = req.store.find(Offering,
144
Offering.subject_id == Subject.id,
145
Subject.short_name == subject,
146
Offering.semester_id == Semester.id,
147
Semester.year == year,
148
Semester.semester == semester).one()
153
def project_url(self, projectset, project):
154
return "/subjects/%s/%s/%s/+projects/%s" % (
155
self.context.subject.short_name,
156
self.context.semester.year,
157
self.context.semester.semester,
161
def new_project_url(self, projectset):
162
return "/api/subjects/" + self.context.subject.short_name + "/" +\
163
self.context.semester.year + "/" + \
164
self.context.semester.semester + "/+projectsets/" +\
165
str(projectset.id) + "/+projects/+new"
167
def populate(self, req, ctx):
168
self.plugin_styles[Plugin] = ["project.css"]
169
self.plugin_scripts[Plugin] = ["project.js"]
170
ctx['offering'] = self.context
171
ctx['subject'] = self.context.subject.short_name
172
ctx['year'] = self.context.semester.year
173
ctx['semester'] = self.context.semester.semester
175
ctx['projectsets'] = []
177
#Open the projectset Fragment, and render it for inclusion
178
#into the ProjectSets page
179
#XXX: This could be a lot cleaner
180
loader = genshi.template.TemplateLoader(".", auto_reload=True)
182
set_fragment = os.path.join(os.path.dirname(__file__),
183
"templates/projectset_fragment.html")
184
project_fragment = os.path.join(os.path.dirname(__file__),
185
"templates/project_fragment.html")
187
for projectset in self.context.project_sets:
188
settmpl = loader.load(set_fragment)
190
setCtx['group_size'] = projectset.max_students_per_group
191
setCtx['projectset_id'] = projectset.id
192
setCtx['new_project_url'] = self.new_project_url(projectset)
193
setCtx['projects'] = []
195
for project in projectset.projects:
196
projecttmpl = loader.load(project_fragment)
197
projectCtx = Context()
198
projectCtx['project'] = project
199
projectCtx['project_url'] = self.project_url(projectset, project)
201
setCtx['projects'].append(
202
projecttmpl.generate(projectCtx))
204
ctx['projectsets'].append(settmpl.generate(setCtx))
207
class ProjectView(XHTMLView):
208
"""View the submissions for a ProjectSet"""
209
template = "templates/project.html"
213
def __init__(self, req, subject, year, semester, project):
214
self.context = req.store.find(Project,
215
Project.short_name == project,
216
Project.project_set_id == ProjectSet.id,
217
ProjectSet.offering_id == Offering.id,
218
Offering.semester_id == Semester.id,
219
Semester.year == year,
220
Semester.semester == semester,
221
Offering.subject_id == Subject.id,
222
Subject.short_name == subject).one()
223
if self.context is None:
226
def populate(self, req, ctx):
227
ctx['format_datetime_short'] = ivle.date.format_datetime_for_paragraph
229
ctx['project'] = self.context
230
ctx['assesseds'] = self.context.assesseds
232
ctx['submissions'] = []
233
for assessed in self.context.assesseds:
234
if assessed.submissions.count() > 0:
235
ctx['submissions'].append(
236
assessed.submissions.order_by(ProjectSubmission.date_submitted)[-1])
239
127
class Plugin(ViewPlugin, MediaPlugin):
241
129
('subjects/', SubjectsView),
242
130
('subjects/:subject/:year/:semester/+enrolments/+new', EnrolView),
243
('subjects/:subject/:year/:semester/+projects', OfferingProjectsView),
244
('subjects/:subject/:year/:semester/+projects/:project', ProjectView),
246
('api/subjects/:subject/:year/:semester/+projectsets/+new',
248
('api/subjects/:subject/:year/:semester/+projectsets/:projectset/+projects/+new',
250
('api/subjects/:subject/:year/:semester/+projects/:project',