23
23
# A sample / testing application for IVLE.
29
31
from storm.locals import Desc
30
33
from genshi.filters import HTMLFormFiller
34
from genshi.template import Context, TemplateLoader
33
37
from ivle.webapp.base.xhtml import XHTMLView
34
38
from ivle.webapp.base.plugins import ViewPlugin, MediaPlugin
35
39
from ivle.webapp.errors import NotFound
36
from ivle.database import Subject, Semester, Offering, Enrolment, User
41
from ivle.database import Subject, Semester, Offering, Enrolment, User,\
42
ProjectSet, Project, ProjectSubmission
37
43
from ivle import util
46
from ivle.webapp.admin.projectservice import ProjectSetRESTView,\
48
from ivle.webapp.admin.offeringservice import OfferingRESTView
40
51
class SubjectsView(XHTMLView):
41
52
'''The view of the list of subjects.'''
42
template = 'subjects.html'
53
template = 'templates/subjects.html'
45
56
def authorize(self, req):
124
135
ctx['offering'] = self.context
125
136
ctx['errors'] = errors
138
class OfferingProjectsView(XHTMLView):
139
"""View the projects for an offering."""
140
template = 'templates/offering_projects.html'
144
def __init__(self, req, subject, year, semester):
145
self.context = req.store.find(Offering,
146
Offering.subject_id == Subject.id,
147
Subject.short_name == subject,
148
Offering.semester_id == Semester.id,
149
Semester.year == year,
150
Semester.semester == semester).one()
155
def project_url(self, projectset, project):
156
return "/subjects/%s/%s/%s/+projects/%s" % (
157
self.context.subject.short_name,
158
self.context.semester.year,
159
self.context.semester.semester,
163
def new_project_url(self, projectset):
164
return "/api/subjects/" + self.context.subject.short_name + "/" +\
165
self.context.semester.year + "/" + \
166
self.context.semester.semester + "/+projectsets/" +\
167
str(projectset.id) + "/+projects/+new"
169
def populate(self, req, ctx):
170
self.plugin_styles[Plugin] = ["project.css"]
171
self.plugin_scripts[Plugin] = ["project.js"]
172
ctx['offering'] = self.context
173
ctx['projectsets'] = []
175
#Open the projectset Fragment, and render it for inclusion
176
#into the ProjectSets page
177
#XXX: This could be a lot cleaner
178
loader = genshi.template.TemplateLoader(".", auto_reload=True)
180
set_fragment = os.path.join(os.path.dirname(__file__),
181
"templates/projectset_fragment.html")
182
project_fragment = os.path.join(os.path.dirname(__file__),
183
"templates/project_fragment.html")
185
for projectset in self.context.project_sets:
186
settmpl = loader.load(set_fragment)
188
setCtx['projectset'] = projectset
189
setCtx['new_project_url'] = self.new_project_url(projectset)
190
setCtx['projects'] = []
192
for project in projectset.projects:
193
projecttmpl = loader.load(project_fragment)
194
projectCtx = Context()
195
projectCtx['project'] = project
196
projectCtx['project_url'] = self.project_url(projectset, project)
198
setCtx['projects'].append(
199
projecttmpl.generate(projectCtx))
201
ctx['projectsets'].append(settmpl.generate(setCtx))
204
class ProjectView(XHTMLView):
205
"""View the submissions for a ProjectSet"""
206
template = "templates/project.html"
210
def __init__(self, req, subject, year, semester, project):
211
self.context = req.store.find(Project,
212
Project.short_name == project,
213
Project.project_set_id == ProjectSet.id,
214
ProjectSet.offering_id == Offering.id,
215
Offering.semester_id == Semester.id,
216
Semester.year == year,
217
Semester.semester == semester,
218
Offering.subject_id == Subject.id,
219
Subject.short_name == subject).one()
220
if self.context is None:
223
def build_subversion_url(self, svnroot, submission):
224
princ = submission.assessed.principal
226
if isinstance(princ, User):
227
path = 'users/%s' % princ.login
229
path = 'groups/%s_%s_%s_%s' % (
230
princ.project_set.offering.subject.short_name,
231
princ.project_set.offering.semester.year,
232
princ.project_set.offering.semester.semester,
235
return urlparse.urljoin(
237
os.path.join(path, submission.path[1:] if
238
submission.path.startswith(os.sep) else
241
def populate(self, req, ctx):
242
self.plugin_styles[Plugin] = ["project.css"]
244
ctx['format_datetime_short'] = ivle.date.format_datetime_for_paragraph
245
ctx['build_subversion_url'] = self.build_subversion_url
246
ctx['svn_addr'] = req.config['urls']['svn_addr']
247
ctx['project'] = self.context
248
ctx['user'] = req.user
128
250
class Plugin(ViewPlugin, MediaPlugin):
130
252
('subjects/', SubjectsView),
131
253
('subjects/:subject/:year/:semester/+enrolments/+new', EnrolView),
254
('subjects/:subject/:year/:semester/+projects', OfferingProjectsView),
255
('subjects/:subject/:year/:semester/+projects/:project', ProjectView),
257
('api/subjects/:subject/:year/:semester/+projectsets/+new',
259
('api/subjects/:subject/:year/:semester/+projectsets/:projectset/+projects/+new',
261
('api/subjects/:subject/:year/:semester/+projects/:project',