~azzar1/unity/add-show-desktop-key

« back to all changes in this revision

Viewing changes to ivle/webapp/admin/subject.py

  • Committer: William Grant
  • Date: 2009-05-14 02:30:46 UTC
  • mfrom: (1165.3.86 submissions-admin)
  • Revision ID: grantw@unimelb.edu.au-20090514023046-ujf6ay6rf6iioz9s
Merge submissions-admin.

Offering staff can now administer projects and view their projects'
submissions. A tool is also provided to create archives of each submission.

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
# A sample / testing application for IVLE.
24
24
 
25
25
import os
 
26
import os.path
26
27
import urllib
 
28
import urlparse
27
29
import cgi
28
30
 
29
31
from storm.locals import Desc
 
32
import genshi
30
33
from genshi.filters import HTMLFormFiller
 
34
from genshi.template import Context, TemplateLoader
31
35
import formencode
32
36
 
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
 
40
 
 
41
from ivle.database import Subject, Semester, Offering, Enrolment, User,\
 
42
                          ProjectSet, Project, ProjectSubmission
 
43
from ivle import util
 
44
import ivle.date
 
45
 
 
46
from ivle.webapp.admin.projectservice import ProjectSetRESTView,\
 
47
                                             ProjectRESTView
 
48
from ivle.webapp.admin.offeringservice import OfferingRESTView
37
49
 
38
50
 
39
51
class SubjectsView(XHTMLView):
40
52
    '''The view of the list of subjects.'''
41
 
    template = 'subjects.html'
 
53
    template = 'templates/subjects.html'
42
54
    tab = 'subjects'
43
55
 
44
56
    def authorize(self, req):
84
96
 
85
97
class EnrolView(XHTMLView):
86
98
    """A form to enrol a user in an offering."""
87
 
    template = 'enrol.html'
 
99
    template = 'templates/enrol.html'
88
100
    tab = 'subjects'
89
101
    permission = 'edit'
90
102
 
123
135
        ctx['offering'] = self.context
124
136
        ctx['errors'] = errors
125
137
 
 
138
class OfferingProjectsView(XHTMLView):
 
139
    """View the projects for an offering."""
 
140
    template = 'templates/offering_projects.html'
 
141
    permission = 'edit'
 
142
    tab = 'subjects'
 
143
    
 
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()
 
151
 
 
152
        if not self.context:
 
153
            raise NotFound()
 
154
 
 
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,
 
160
                    project.short_name
 
161
                    )
 
162
 
 
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"
 
168
    
 
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'] = []
 
174
 
 
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)
 
179
 
 
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")
 
184
 
 
185
        for projectset in self.context.project_sets:
 
186
            settmpl = loader.load(set_fragment)
 
187
            setCtx = Context()
 
188
            setCtx['projectset'] = projectset
 
189
            setCtx['new_project_url'] = self.new_project_url(projectset)
 
190
            setCtx['projects'] = []
 
191
 
 
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)
 
197
 
 
198
                setCtx['projects'].append(
 
199
                        projecttmpl.generate(projectCtx))
 
200
 
 
201
            ctx['projectsets'].append(settmpl.generate(setCtx))
 
202
 
 
203
 
 
204
class ProjectView(XHTMLView):
 
205
    """View the submissions for a ProjectSet"""
 
206
    template = "templates/project.html"
 
207
    permission = "edit"
 
208
    tab = 'subjects'
 
209
 
 
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:
 
221
            raise NotFound()
 
222
 
 
223
    def build_subversion_url(self, svnroot, submission):
 
224
        princ = submission.assessed.principal
 
225
 
 
226
        if isinstance(princ, User):
 
227
            path = 'users/%s' % princ.login
 
228
        else:
 
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,
 
233
                    princ.name
 
234
                    )
 
235
        return urlparse.urljoin(
 
236
                    svnroot,
 
237
                    os.path.join(path, submission.path[1:] if
 
238
                                       submission.path.startswith(os.sep) else
 
239
                                       submission.path))
 
240
 
 
241
    def populate(self, req, ctx):
 
242
        self.plugin_styles[Plugin] = ["project.css"]
 
243
 
 
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
126
249
 
127
250
class Plugin(ViewPlugin, MediaPlugin):
128
251
    urls = [
129
252
        ('subjects/', SubjectsView),
130
253
        ('subjects/:subject/:year/:semester/+enrolments/+new', EnrolView),
 
254
        ('subjects/:subject/:year/:semester/+projects', OfferingProjectsView),
 
255
        ('subjects/:subject/:year/:semester/+projects/:project', ProjectView),
 
256
        #API Views
 
257
        ('api/subjects/:subject/:year/:semester/+projectsets/+new',
 
258
            OfferingRESTView),
 
259
        ('api/subjects/:subject/:year/:semester/+projectsets/:projectset/+projects/+new',
 
260
            ProjectSetRESTView),
 
261
        ('api/subjects/:subject/:year/:semester/+projects/:project', 
 
262
            ProjectRESTView),
 
263
 
131
264
    ]
132
265
 
133
266
    tabs = [