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

621 by mattgiuca
Added 2 new apps: home and subjects. Both fairly incomplete, just a basic
1
# IVLE
2
# Copyright (C) 2007-2008 The University of Melbourne
3
#
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
18
# App: subjects
19
# Author: Matt Giuca
20
# Date: 29/2/2008
21
22
# This is an IVLE application.
23
# A sample / testing application for IVLE.
24
627 by mattgiuca
subjects: Now presents a top-level subjects menu (same as tutorials).
25
import os
1165.3.61 by William Grant
Provide a Subversion command to grab each submission.
26
import os.path
627 by mattgiuca
subjects: Now presents a top-level subjects menu (same as tutorials).
27
import urllib
1165.3.61 by William Grant
Provide a Subversion command to grab each submission.
28
import urlparse
627 by mattgiuca
subjects: Now presents a top-level subjects menu (same as tutorials).
29
import cgi
30
1125 by William Grant
Rework ivle.webapp.admin.subjects#SubjectsView to split offerings nicely by
31
from storm.locals import Desc
1165.3.2 by Nick Chadwick
Created a new view for IVLE, allowing lecturers and tutors to
32
import genshi
1149 by William Grant
Allow tutors and lecturers to enrol people in their offerings.
33
from genshi.filters import HTMLFormFiller
1165.3.2 by Nick Chadwick
Created a new view for IVLE, allowing lecturers and tutors to
34
from genshi.template import Context, TemplateLoader
1149 by William Grant
Allow tutors and lecturers to enrol people in their offerings.
35
import formencode
1125 by William Grant
Rework ivle.webapp.admin.subjects#SubjectsView to split offerings nicely by
36
1099.1.34 by William Grant
Split up ivle.webapp.base.views into ivle.webapp.base.{rest,xhtml}, as it was
37
from ivle.webapp.base.xhtml import XHTMLView
1099.1.115 by William Grant
Add tabs to the new framework. Move the app icons into the apps themselves.
38
from ivle.webapp.base.plugins import ViewPlugin, MediaPlugin
1099.1.20 by William Grant
ivle.webapp.admin.subject: Port www/apps/subjects to new framework.
39
from ivle.webapp.errors import NotFound
1165.3.9 by Nick Chadwick
merge from trunk
40
1165.3.2 by Nick Chadwick
Created a new view for IVLE, allowing lecturers and tutors to
41
from ivle.database import Subject, Semester, Offering, Enrolment, User,\
1165.3.8 by Nick Chadwick
Added a total submissions and total assesseds to the project view
42
                          ProjectSet, Project, ProjectSubmission
1079 by William Grant
Merge setup-refactor branch. This completely breaks existing installations;
43
from ivle import util
1165.3.14 by William Grant
Improve ProjectView's template substantially.
44
import ivle.date
621 by mattgiuca
Added 2 new apps: home and subjects. Both fairly incomplete, just a basic
45
1165.3.2 by Nick Chadwick
Created a new view for IVLE, allowing lecturers and tutors to
46
from ivle.webapp.admin.projectservice import ProjectSetRESTView,\
47
                                             ProjectRESTView
48
from ivle.webapp.admin.offeringservice import OfferingRESTView
49
1099.1.20 by William Grant
ivle.webapp.admin.subject: Port www/apps/subjects to new framework.
50
51
class SubjectsView(XHTMLView):
52
    '''The view of the list of subjects.'''
1165.3.2 by Nick Chadwick
Created a new view for IVLE, allowing lecturers and tutors to
53
    template = 'templates/subjects.html'
1116 by William Grant
Move the old tutorial views into the 'subjects' tab, so they get the right
54
    tab = 'subjects'
1099.1.20 by William Grant
ivle.webapp.admin.subject: Port www/apps/subjects to new framework.
55
1099.1.110 by William Grant
Implement an authorization system in the new framework. This breaks the REST
56
    def authorize(self, req):
1138 by William Grant
SubjectsView now tells users if they have no enrolments.
57
        return req.user is not None
1099.1.110 by William Grant
Implement an authorization system in the new framework. This breaks the REST
58
1099.1.20 by William Grant
ivle.webapp.admin.subject: Port www/apps/subjects to new framework.
59
    def populate(self, req, ctx):
1139 by William Grant
Show group administration links on SubjectsView where privileges allow it.
60
        ctx['user'] = req.user
1125 by William Grant
Rework ivle.webapp.admin.subjects#SubjectsView to split offerings nicely by
61
        ctx['semesters'] = []
62
        for semester in req.store.find(Semester).order_by(Desc(Semester.year),
63
                                                     Desc(Semester.semester)):
64
            enrolments = semester.enrolments.find(user=req.user)
65
            if enrolments.count():
66
                ctx['semesters'].append((semester, enrolments))
1099.1.20 by William Grant
ivle.webapp.admin.subject: Port www/apps/subjects to new framework.
67
1149 by William Grant
Allow tutors and lecturers to enrol people in their offerings.
68
69
class UserValidator(formencode.FancyValidator):
70
    """A FormEncode validator that turns a username into a user.
71
72
    The state must have a 'store' attribute, which is the Storm store
73
    to use."""
74
    def _to_python(self, value, state):
75
        user = User.get_by_login(state.store, value)
76
        if user:
77
            return user
78
        else:
1150 by William Grant
Refuse a +enrol if the user is already enrolled. This stops overwriting
79
            raise formencode.Invalid('User does not exist', value, state)
80
81
82
class NoEnrolmentValidator(formencode.FancyValidator):
83
    """A FormEncode validator that ensures absence of an enrolment.
84
85
    The state must have an 'offering' attribute.
86
    """
87
    def _to_python(self, value, state):
88
        if state.offering.get_enrolment(value):
89
            raise formencode.Invalid('User already enrolled', value, state)
90
        return value
1149 by William Grant
Allow tutors and lecturers to enrol people in their offerings.
91
92
93
class EnrolSchema(formencode.Schema):
1150 by William Grant
Refuse a +enrol if the user is already enrolled. This stops overwriting
94
    user = formencode.All(NoEnrolmentValidator(), UserValidator())
1149 by William Grant
Allow tutors and lecturers to enrol people in their offerings.
95
96
97
class EnrolView(XHTMLView):
98
    """A form to enrol a user in an offering."""
1165.3.2 by Nick Chadwick
Created a new view for IVLE, allowing lecturers and tutors to
99
    template = 'templates/enrol.html'
1149 by William Grant
Allow tutors and lecturers to enrol people in their offerings.
100
    tab = 'subjects'
101
    permission = 'edit'
102
103
    def __init__(self, req, subject, year, semester):
104
        """Find the given offering by subject, year and semester."""
105
        self.context = req.store.find(Offering,
106
            Offering.subject_id == Subject.id,
107
            Subject.short_name == subject,
108
            Offering.semester_id == Semester.id,
109
            Semester.year == year,
110
            Semester.semester == semester).one()
111
112
        if not self.context:
113
            raise NotFound()
114
115
    def filter(self, stream, ctx):
116
        return stream | HTMLFormFiller(data=ctx['data'])
117
118
    def populate(self, req, ctx):
119
        if req.method == 'POST':
120
            data = dict(req.get_fieldstorage())
121
            try:
122
                validator = EnrolSchema()
1150 by William Grant
Refuse a +enrol if the user is already enrolled. This stops overwriting
123
                req.offering = self.context # XXX: Getting into state.
1149 by William Grant
Allow tutors and lecturers to enrol people in their offerings.
124
                data = validator.to_python(data, state=req)
125
                self.context.enrol(data['user'])
126
                req.store.commit()
127
                req.throw_redirect(req.uri)
128
            except formencode.Invalid, e:
129
                errors = e.unpack_errors()
130
        else:
131
            data = {}
132
            errors = {}
133
134
        ctx['data'] = data or {}
135
        ctx['offering'] = self.context
136
        ctx['errors'] = errors
137
1165.3.19 by William Grant
Rename SubjectProjectSetView to OfferingProjectsView.
138
class OfferingProjectsView(XHTMLView):
139
    """View the projects for an offering."""
140
    template = 'templates/offering_projects.html'
1165.2.3 by Nick Chadwick
Added a new Admin view, which allows for the administration of projects
141
    permission = 'edit'
1165.3.18 by William Grant
Put the project listing and view in the Subjects tab.
142
    tab = 'subjects'
1165.2.3 by Nick Chadwick
Added a new Admin view, which allows for the administration of projects
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()
1165.3.2 by Nick Chadwick
Created a new view for IVLE, allowing lecturers and tutors to
154
155
    def project_url(self, projectset, project):
1165.3.15 by William Grant
Remove the ProjectSet from Project URLs.
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
                    )
1165.3.2 by Nick Chadwick
Created a new view for IVLE, allowing lecturers and tutors to
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"
1165.2.3 by Nick Chadwick
Added a new Admin view, which allows for the administration of projects
168
    
169
    def populate(self, req, ctx):
170
        self.plugin_styles[Plugin] = ["project.css"]
1165.3.2 by Nick Chadwick
Created a new view for IVLE, allowing lecturers and tutors to
171
        self.plugin_scripts[Plugin] = ["project.js"]
1165.2.3 by Nick Chadwick
Added a new Admin view, which allows for the administration of projects
172
        ctx['offering'] = self.context
1165.3.2 by Nick Chadwick
Created a new view for IVLE, allowing lecturers and tutors to
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()
1165.3.30 by William Grant
Clean out the projectset fragment context.
188
            setCtx['projectset'] = projectset
1165.3.2 by Nick Chadwick
Created a new view for IVLE, allowing lecturers and tutors to
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):
1165.2.3 by Nick Chadwick
Added a new Admin view, which allows for the administration of projects
205
    """View the submissions for a ProjectSet"""
1165.3.2 by Nick Chadwick
Created a new view for IVLE, allowing lecturers and tutors to
206
    template = "templates/project.html"
207
    permission = "edit"
1165.3.18 by William Grant
Put the project listing and view in the Subjects tab.
208
    tab = 'subjects'
1165.3.2 by Nick Chadwick
Created a new view for IVLE, allowing lecturers and tutors to
209
1165.3.15 by William Grant
Remove the ProjectSet from Project URLs.
210
    def __init__(self, req, subject, year, semester, project):
1165.3.2 by Nick Chadwick
Created a new view for IVLE, allowing lecturers and tutors to
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
1165.3.61 by William Grant
Provide a Subversion command to grab each submission.
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
1165.3.2 by Nick Chadwick
Created a new view for IVLE, allowing lecturers and tutors to
241
    def populate(self, req, ctx):
1165.3.66 by William Grant
Prettify the submissions table.
242
        self.plugin_styles[Plugin] = ["project.css"]
243
1165.3.14 by William Grant
Improve ProjectView's template substantially.
244
        ctx['format_datetime_short'] = ivle.date.format_datetime_for_paragraph
1165.3.61 by William Grant
Provide a Subversion command to grab each submission.
245
        ctx['build_subversion_url'] = self.build_subversion_url
246
        ctx['svn_addr'] = req.config['urls']['svn_addr']
1165.3.2 by Nick Chadwick
Created a new view for IVLE, allowing lecturers and tutors to
247
        ctx['project'] = self.context
1165.3.61 by William Grant
Provide a Subversion command to grab each submission.
248
        ctx['user'] = req.user
1165.3.2 by Nick Chadwick
Created a new view for IVLE, allowing lecturers and tutors to
249
1099.1.115 by William Grant
Add tabs to the new framework. Move the app icons into the apps themselves.
250
class Plugin(ViewPlugin, MediaPlugin):
1099.1.20 by William Grant
ivle.webapp.admin.subject: Port www/apps/subjects to new framework.
251
    urls = [
252
        ('subjects/', SubjectsView),
1149 by William Grant
Allow tutors and lecturers to enrol people in their offerings.
253
        ('subjects/:subject/:year/:semester/+enrolments/+new', EnrolView),
1165.3.19 by William Grant
Rename SubjectProjectSetView to OfferingProjectsView.
254
        ('subjects/:subject/:year/:semester/+projects', OfferingProjectsView),
1165.3.15 by William Grant
Remove the ProjectSet from Project URLs.
255
        ('subjects/:subject/:year/:semester/+projects/:project', ProjectView),
1165.2.3 by Nick Chadwick
Added a new Admin view, which allows for the administration of projects
256
        #API Views
1165.3.2 by Nick Chadwick
Created a new view for IVLE, allowing lecturers and tutors to
257
        ('api/subjects/:subject/:year/:semester/+projectsets/+new',
258
            OfferingRESTView),
259
        ('api/subjects/:subject/:year/:semester/+projectsets/:projectset/+projects/+new',
260
            ProjectSetRESTView),
1165.3.15 by William Grant
Remove the ProjectSet from Project URLs.
261
        ('api/subjects/:subject/:year/:semester/+projects/:project', 
1165.3.2 by Nick Chadwick
Created a new view for IVLE, allowing lecturers and tutors to
262
            ProjectRESTView),
263
1099.1.20 by William Grant
ivle.webapp.admin.subject: Port www/apps/subjects to new framework.
264
    ]
1099.1.115 by William Grant
Add tabs to the new framework. Move the app icons into the apps themselves.
265
266
    tabs = [
1118 by matt.giuca
Rewrote tooltips for the four tabs visible by default.
267
        ('subjects', 'Subjects',
268
         'View subject content and complete worksheets',
269
         'subjects.png', 'subjects', 5)
1099.1.115 by William Grant
Add tabs to the new framework. Move the app icons into the apps themselves.
270
    ]
271
272
    media = 'subject-media'