46
44
from ivle.webapp.admin.projectservice import ProjectSetRESTView,\
48
46
from ivle.webapp.admin.offeringservice import OfferingRESTView
49
from ivle.webapp.admin.publishing import (root_to_subject,
50
subject_to_offering, offering_to_projectset, offering_to_project,
51
subject_url, offering_url, projectset_url, project_url)
52
from ivle.webapp.admin.breadcrumbs import (SubjectBreadcrumb,
53
OfferingBreadcrumb, UserBreadcrumb, ProjectBreadcrumb)
55
49
class SubjectsView(XHTMLView):
56
50
'''The view of the list of subjects.'''
188
205
permission = "edit"
191
def build_subversion_url(self, svnroot, submission):
192
princ = submission.assessed.principal
194
if isinstance(princ, User):
195
path = 'users/%s' % princ.login
197
path = 'groups/%s_%s_%s_%s' % (
198
princ.project_set.offering.subject.short_name,
199
princ.project_set.offering.semester.year,
200
princ.project_set.offering.semester.semester,
203
return urlparse.urljoin(
205
os.path.join(path, submission.path[1:] if
206
submission.path.startswith(os.sep) else
208
def __init__(self, req, subject, year, semester, 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:
209
221
def populate(self, req, ctx):
210
self.plugin_styles[Plugin] = ["project.css"]
212
222
ctx['format_datetime_short'] = ivle.date.format_datetime_for_paragraph
213
ctx['build_subversion_url'] = self.build_subversion_url
214
ctx['svn_addr'] = req.config['urls']['svn_addr']
215
224
ctx['project'] = self.context
216
ctx['user'] = req.user
225
ctx['assesseds'] = self.context.assesseds
218
class OfferingEnrolmentSet(object):
219
def __init__(self, offering):
220
self.offering = offering
227
ctx['submissions'] = []
228
for assessed in self.context.assesseds:
229
if assessed.submissions.count() > 0:
230
ctx['submissions'].append(
231
assessed.submissions.order_by(
232
ProjectSubmission.date_submitted)[-1])
233
ctx['assigned'] = self.context.project_set.get_assigned()
222
235
class Plugin(ViewPlugin, MediaPlugin):
223
forward_routes = (root_to_subject, subject_to_offering,
224
offering_to_project, offering_to_projectset)
225
reverse_routes = (subject_url, offering_url, projectset_url, project_url)
227
views = [(ApplicationRoot, ('subjects', '+index'), SubjectsView),
228
(Offering, ('+enrolments', '+new'), EnrolView),
229
(Offering, ('+projects', '+index'), OfferingProjectsView),
230
(Project, '+index', ProjectView),
232
(Offering, ('+projectsets', '+new'), OfferingRESTView, 'api'),
233
(ProjectSet, ('+projects', '+new'), ProjectSetRESTView, 'api'),
234
(Project, '+index', ProjectRESTView, 'api'),
237
breadcrumbs = {Subject: SubjectBreadcrumb,
238
Offering: OfferingBreadcrumb,
239
User: UserBreadcrumb,
240
Project: ProjectBreadcrumb,
237
('subjects/', SubjectsView),
238
('subjects/:subject/:year/:semester/+enrolments/+new', EnrolView),
239
('subjects/:subject/:year/:semester/+projects', OfferingProjectsView),
240
('subjects/:subject/:year/:semester/+projects/:project', ProjectView),
242
('api/subjects/:subject/:year/:semester/+projectsets/+new',
244
('api/subjects/:subject/:year/:semester/+projectsets/:projectset/+projects/+new',
246
('api/subjects/:subject/:year/:semester/+projects/:project',
244
252
('subjects', 'Subjects',