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