~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
1294.2.52 by William Grant
Port subject-related views to object traversal.
31
from storm.locals import Desc, Store
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
1294.2.52 by William Grant
Port subject-related views to object traversal.
39
from ivle.webapp import ApplicationRoot
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
1294.3.2 by William Grant
Router->Publisher
49
from ivle.webapp.admin.publishing import (root_to_subject,
1294.2.70 by William Grant
Split out ivle.webapp.admin's routes into annotated functions in ivle.webapp.traversal.
50
            subject_to_offering, offering_to_projectset, offering_to_project,
51
            subject_url, offering_url, projectset_url, project_url)
1294.2.96 by William Grant
Add a UserBreadcrumb.
52
from ivle.webapp.admin.breadcrumbs import (SubjectBreadcrumb,
1294.2.98 by William Grant
Add a ProjectBreadcrumb.
53
            OfferingBreadcrumb, UserBreadcrumb, ProjectBreadcrumb)
1165.3.2 by Nick Chadwick
Created a new view for IVLE, allowing lecturers and tutors to
54
1099.1.20 by William Grant
ivle.webapp.admin.subject: Port www/apps/subjects to new framework.
55
class SubjectsView(XHTMLView):
56
    '''The view of the list of subjects.'''
1165.3.2 by Nick Chadwick
Created a new view for IVLE, allowing lecturers and tutors to
57
    template = 'templates/subjects.html'
1116 by William Grant
Move the old tutorial views into the 'subjects' tab, so they get the right
58
    tab = 'subjects'
1099.1.20 by William Grant
ivle.webapp.admin.subject: Port www/apps/subjects to new framework.
59
1099.1.110 by William Grant
Implement an authorization system in the new framework. This breaks the REST
60
    def authorize(self, req):
1138 by William Grant
SubjectsView now tells users if they have no enrolments.
61
        return req.user is not None
1099.1.110 by William Grant
Implement an authorization system in the new framework. This breaks the REST
62
1099.1.20 by William Grant
ivle.webapp.admin.subject: Port www/apps/subjects to new framework.
63
    def populate(self, req, ctx):
1139 by William Grant
Show group administration links on SubjectsView where privileges allow it.
64
        ctx['user'] = req.user
1125 by William Grant
Rework ivle.webapp.admin.subjects#SubjectsView to split offerings nicely by
65
        ctx['semesters'] = []
66
        for semester in req.store.find(Semester).order_by(Desc(Semester.year),
67
                                                     Desc(Semester.semester)):
68
            enrolments = semester.enrolments.find(user=req.user)
69
            if enrolments.count():
70
                ctx['semesters'].append((semester, enrolments))
1099.1.20 by William Grant
ivle.webapp.admin.subject: Port www/apps/subjects to new framework.
71
1149 by William Grant
Allow tutors and lecturers to enrol people in their offerings.
72
73
class UserValidator(formencode.FancyValidator):
74
    """A FormEncode validator that turns a username into a user.
75
76
    The state must have a 'store' attribute, which is the Storm store
77
    to use."""
78
    def _to_python(self, value, state):
79
        user = User.get_by_login(state.store, value)
80
        if user:
81
            return user
82
        else:
1150 by William Grant
Refuse a +enrol if the user is already enrolled. This stops overwriting
83
            raise formencode.Invalid('User does not exist', value, state)
84
85
86
class NoEnrolmentValidator(formencode.FancyValidator):
87
    """A FormEncode validator that ensures absence of an enrolment.
88
89
    The state must have an 'offering' attribute.
90
    """
91
    def _to_python(self, value, state):
92
        if state.offering.get_enrolment(value):
93
            raise formencode.Invalid('User already enrolled', value, state)
94
        return value
1149 by William Grant
Allow tutors and lecturers to enrol people in their offerings.
95
96
97
class EnrolSchema(formencode.Schema):
1150 by William Grant
Refuse a +enrol if the user is already enrolled. This stops overwriting
98
    user = formencode.All(NoEnrolmentValidator(), UserValidator())
1149 by William Grant
Allow tutors and lecturers to enrol people in their offerings.
99
100
101
class EnrolView(XHTMLView):
102
    """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
103
    template = 'templates/enrol.html'
1149 by William Grant
Allow tutors and lecturers to enrol people in their offerings.
104
    tab = 'subjects'
105
    permission = 'edit'
106
107
    def filter(self, stream, ctx):
108
        return stream | HTMLFormFiller(data=ctx['data'])
109
110
    def populate(self, req, ctx):
111
        if req.method == 'POST':
112
            data = dict(req.get_fieldstorage())
113
            try:
114
                validator = EnrolSchema()
1150 by William Grant
Refuse a +enrol if the user is already enrolled. This stops overwriting
115
                req.offering = self.context # XXX: Getting into state.
1149 by William Grant
Allow tutors and lecturers to enrol people in their offerings.
116
                data = validator.to_python(data, state=req)
117
                self.context.enrol(data['user'])
118
                req.store.commit()
119
                req.throw_redirect(req.uri)
120
            except formencode.Invalid, e:
121
                errors = e.unpack_errors()
122
        else:
123
            data = {}
124
            errors = {}
125
126
        ctx['data'] = data or {}
127
        ctx['offering'] = self.context
128
        ctx['errors'] = errors
129
1165.3.19 by William Grant
Rename SubjectProjectSetView to OfferingProjectsView.
130
class OfferingProjectsView(XHTMLView):
131
    """View the projects for an offering."""
132
    template = 'templates/offering_projects.html'
1165.2.3 by Nick Chadwick
Added a new Admin view, which allows for the administration of projects
133
    permission = 'edit'
1165.3.18 by William Grant
Put the project listing and view in the Subjects tab.
134
    tab = 'subjects'
1165.3.2 by Nick Chadwick
Created a new view for IVLE, allowing lecturers and tutors to
135
136
    def project_url(self, projectset, project):
1165.3.15 by William Grant
Remove the ProjectSet from Project URLs.
137
        return "/subjects/%s/%s/%s/+projects/%s" % (
138
                    self.context.subject.short_name,
139
                    self.context.semester.year,
140
                    self.context.semester.semester,
141
                    project.short_name
142
                    )
1165.3.2 by Nick Chadwick
Created a new view for IVLE, allowing lecturers and tutors to
143
144
    def new_project_url(self, projectset):
145
        return "/api/subjects/" + self.context.subject.short_name + "/" +\
146
                self.context.semester.year + "/" + \
147
                self.context.semester.semester + "/+projectsets/" +\
148
                str(projectset.id) + "/+projects/+new"
1165.2.3 by Nick Chadwick
Added a new Admin view, which allows for the administration of projects
149
    
150
    def populate(self, req, ctx):
151
        self.plugin_styles[Plugin] = ["project.css"]
1165.3.2 by Nick Chadwick
Created a new view for IVLE, allowing lecturers and tutors to
152
        self.plugin_scripts[Plugin] = ["project.js"]
1165.2.3 by Nick Chadwick
Added a new Admin view, which allows for the administration of projects
153
        ctx['offering'] = self.context
1165.3.2 by Nick Chadwick
Created a new view for IVLE, allowing lecturers and tutors to
154
        ctx['projectsets'] = []
155
156
        #Open the projectset Fragment, and render it for inclusion
157
        #into the ProjectSets page
158
        #XXX: This could be a lot cleaner
159
        loader = genshi.template.TemplateLoader(".", auto_reload=True)
160
161
        set_fragment = os.path.join(os.path.dirname(__file__),
162
                "templates/projectset_fragment.html")
163
        project_fragment = os.path.join(os.path.dirname(__file__),
164
                "templates/project_fragment.html")
165
166
        for projectset in self.context.project_sets:
167
            settmpl = loader.load(set_fragment)
168
            setCtx = Context()
1165.3.30 by William Grant
Clean out the projectset fragment context.
169
            setCtx['projectset'] = projectset
1165.3.2 by Nick Chadwick
Created a new view for IVLE, allowing lecturers and tutors to
170
            setCtx['new_project_url'] = self.new_project_url(projectset)
171
            setCtx['projects'] = []
172
173
            for project in projectset.projects:
174
                projecttmpl = loader.load(project_fragment)
175
                projectCtx = Context()
176
                projectCtx['project'] = project
177
                projectCtx['project_url'] = self.project_url(projectset, project)
178
179
                setCtx['projects'].append(
180
                        projecttmpl.generate(projectCtx))
181
182
            ctx['projectsets'].append(settmpl.generate(setCtx))
183
184
185
class ProjectView(XHTMLView):
1165.2.3 by Nick Chadwick
Added a new Admin view, which allows for the administration of projects
186
    """View the submissions for a ProjectSet"""
1165.3.2 by Nick Chadwick
Created a new view for IVLE, allowing lecturers and tutors to
187
    template = "templates/project.html"
188
    permission = "edit"
1165.3.18 by William Grant
Put the project listing and view in the Subjects tab.
189
    tab = 'subjects'
1165.3.2 by Nick Chadwick
Created a new view for IVLE, allowing lecturers and tutors to
190
1165.3.61 by William Grant
Provide a Subversion command to grab each submission.
191
    def build_subversion_url(self, svnroot, submission):
192
        princ = submission.assessed.principal
193
194
        if isinstance(princ, User):
195
            path = 'users/%s' % princ.login
196
        else:
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,
201
                    princ.name
202
                    )
203
        return urlparse.urljoin(
204
                    svnroot,
205
                    os.path.join(path, submission.path[1:] if
206
                                       submission.path.startswith(os.sep) else
207
                                       submission.path))
208
1165.3.2 by Nick Chadwick
Created a new view for IVLE, allowing lecturers and tutors to
209
    def populate(self, req, ctx):
1165.3.66 by William Grant
Prettify the submissions table.
210
        self.plugin_styles[Plugin] = ["project.css"]
211
1165.3.14 by William Grant
Improve ProjectView's template substantially.
212
        ctx['format_datetime_short'] = ivle.date.format_datetime_for_paragraph
1165.3.61 by William Grant
Provide a Subversion command to grab each submission.
213
        ctx['build_subversion_url'] = self.build_subversion_url
214
        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
215
        ctx['project'] = self.context
1165.3.61 by William Grant
Provide a Subversion command to grab each submission.
216
        ctx['user'] = req.user
1165.3.2 by Nick Chadwick
Created a new view for IVLE, allowing lecturers and tutors to
217
1294.2.52 by William Grant
Port subject-related views to object traversal.
218
class OfferingEnrolmentSet(object):
219
    def __init__(self, offering):
220
        self.offering = offering
221
1099.1.115 by William Grant
Add tabs to the new framework. Move the app icons into the apps themselves.
222
class Plugin(ViewPlugin, MediaPlugin):
1294.2.70 by William Grant
Split out ivle.webapp.admin's routes into annotated functions in ivle.webapp.traversal.
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)
1294.2.52 by William Grant
Port subject-related views to object traversal.
226
227
    views = [(ApplicationRoot, ('subjects', '+index'), SubjectsView),
228
             (Offering, ('+enrolments', '+new'), EnrolView),
229
             (Offering, ('+projects', '+index'), OfferingProjectsView),
230
             (Project, '+index', ProjectView),
231
232
             (Offering, ('+projectsets', '+new'), OfferingRESTView, 'api'),
233
             (ProjectSet, ('+projects', '+new'), ProjectSetRESTView, 'api'),
234
             (Project, '+index', ProjectRESTView, 'api'),
235
             ]
1099.1.115 by William Grant
Add tabs to the new framework. Move the app icons into the apps themselves.
236
1294.2.94 by William Grant
Add a SubjectBreadcrumb.
237
    breadcrumbs = {Subject: SubjectBreadcrumb,
238
                   Offering: OfferingBreadcrumb,
1294.2.96 by William Grant
Add a UserBreadcrumb.
239
                   User: UserBreadcrumb,
1294.2.98 by William Grant
Add a ProjectBreadcrumb.
240
                   Project: ProjectBreadcrumb,
1294.2.89 by William Grant
Add an Offering breadcrumb.
241
                   }
242
1099.1.115 by William Grant
Add tabs to the new framework. Move the app icons into the apps themselves.
243
    tabs = [
1118 by matt.giuca
Rewrote tooltips for the four tabs visible by default.
244
        ('subjects', 'Subjects',
245
         'View subject content and complete worksheets',
246
         'subjects.png', 'subjects', 5)
1099.1.115 by William Grant
Add tabs to the new framework. Move the app icons into the apps themselves.
247
    ]
248
249
    media = 'subject-media'