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
36
from ivle.database import Subject, Semester, Offering, Enrolment, User
41
37
from ivle import util
43
from ivle.webapp.admin.projectservice import ProjectSetRESTView,\
45
from ivle.webapp.admin.offeringservice import OfferingRESTView
48
40
class SubjectsView(XHTMLView):
49
41
'''The view of the list of subjects.'''
50
template = 'templates/subjects.html'
42
template = 'subjects.html'
53
45
def authorize(self, req):
132
124
ctx['offering'] = self.context
133
125
ctx['errors'] = errors
135
class SubjectProjectSetView(XHTMLView):
136
"""View the ProjectSets for a subject."""
137
template = 'templates/subject_projects.html'
140
def __init__(self, req, subject, year, semester):
141
self.context = req.store.find(Offering,
142
Offering.subject_id == Subject.id,
143
Subject.short_name == subject,
144
Offering.semester_id == Semester.id,
145
Semester.year == year,
146
Semester.semester == semester).one()
151
def project_url(self, projectset, project):
152
return "/subjects/" + self.context.subject.short_name + "/" +\
153
self.context.semester.year + "/" + \
154
self.context.semester.semester + "/+projectsets/" +\
155
str(projectset.id) + "/+projects/" + project.short_name
157
def new_project_url(self, projectset):
158
return "/api/subjects/" + self.context.subject.short_name + "/" +\
159
self.context.semester.year + "/" + \
160
self.context.semester.semester + "/+projectsets/" +\
161
str(projectset.id) + "/+projects/+new"
163
def populate(self, req, ctx):
164
self.plugin_styles[Plugin] = ["project.css"]
165
self.plugin_scripts[Plugin] = ["project.js"]
166
ctx['offering'] = self.context
167
ctx['subject'] = self.context.subject.short_name
168
ctx['year'] = self.context.semester.year
169
ctx['semester'] = self.context.semester.semester
171
ctx['projectsets'] = []
173
#Open the projectset Fragment, and render it for inclusion
174
#into the ProjectSets page
175
#XXX: This could be a lot cleaner
176
loader = genshi.template.TemplateLoader(".", auto_reload=True)
178
set_fragment = os.path.join(os.path.dirname(__file__),
179
"templates/projectset_fragment.html")
180
project_fragment = os.path.join(os.path.dirname(__file__),
181
"templates/project_fragment.html")
183
for projectset in self.context.project_sets:
184
settmpl = loader.load(set_fragment)
186
setCtx['group_size'] = projectset.max_students_per_group
187
setCtx['projectset_id'] = projectset.id
188
setCtx['new_project_url'] = self.new_project_url(projectset)
189
setCtx['projects'] = []
191
for project in projectset.projects:
192
projecttmpl = loader.load(project_fragment)
193
projectCtx = Context()
194
projectCtx['project'] = project
195
projectCtx['project_url'] = self.project_url(projectset, project)
197
setCtx['projects'].append(
198
projecttmpl.generate(projectCtx))
200
ctx['projectsets'].append(settmpl.generate(setCtx))
203
class ProjectView(XHTMLView):
204
"""View the submissions for a ProjectSet"""
205
template = "templates/project.html"
208
def __init__(self, req, subject, year, semester, projectset, project):
209
self.context = req.store.find(Project,
210
Project.short_name == project,
211
Project.project_set_id == ProjectSet.id,
212
ProjectSet.offering_id == Offering.id,
213
Offering.semester_id == Semester.id,
214
Semester.year == year,
215
Semester.semester == semester,
216
Offering.subject_id == Subject.id,
217
Subject.short_name == subject).one()
218
if self.context is None:
221
def populate(self, req, ctx):
222
ctx['project'] = self.context
223
ctx['assesseds'] = self.context.assesseds
225
ctx['submissions'] = []
226
for assessed in self.context.assesseds:
227
if assessed.submissions.count() > 0:
228
ctx['submissions'].append(
229
assessed.submissions.order_by(ProjectSubmission.date_submitted)[:-1])
232
128
class Plugin(ViewPlugin, MediaPlugin):
234
130
('subjects/', SubjectsView),
235
131
('subjects/:subject/:year/:semester/+enrolments/+new', EnrolView),
236
('subjects/:subject/:year/:semester/+projects', SubjectProjectSetView),
237
('subjects/:subject/:year/:semester/+projectsets/:projectset/+projects/:project', ProjectView),
239
('api/subjects/:subject/:year/:semester/+projectsets/+new',
241
('api/subjects/:subject/:year/:semester/+projectsets/:projectset/+projects/+new',
243
('api/subjects/:subject/:year/:semester/+projectsets/:projectset/+projects/:project',