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

1165.1.8 by William Grant
Start a submission UI in ivle.webapp.submit.
1
# IVLE
2
# Copyright (C) 2007-2009 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
# Author: Will Grant
19
20
"""Project submissions user interface."""
21
1165.1.13 by William Grant
Add an initial project selection UI to SubmitView.
22
import os.path
1165.1.17 by William Grant
Disable project radio buttons if they are closed.
23
import datetime
1165.1.13 by William Grant
Add an initial project selection UI to SubmitView.
24
1165.1.22 by William Grant
Detect the permitted offering for the given submission URL and restrict to that.
25
from storm.locals import Store
26
1165.1.8 by William Grant
Start a submission UI in ivle.webapp.submit.
27
from ivle.database import (User, ProjectGroup, Offering, Subject, Semester,
1165.1.22 by William Grant
Detect the permitted offering for the given submission URL and restrict to that.
28
                           ProjectSet, Project, Enrolment)
1165.1.20 by William Grant
Add a POST handler to SubmitView, which does the actual submission.
29
from ivle.webapp.errors import NotFound, BadRequest
1165.1.8 by William Grant
Start a submission UI in ivle.webapp.submit.
30
from ivle.webapp.base.xhtml import XHTMLView
31
from ivle.webapp.base.plugins import ViewPlugin
32
1165.1.16 by William Grant
Show the deadline for each project when submitting.
33
import ivle.date
34
1165.1.8 by William Grant
Start a submission UI in ivle.webapp.submit.
35
36
class SubmitView(XHTMLView):
37
    """A view to submit a Subversion repository path for a project."""
38
    template = 'submit.html'
39
    tab = 'files'
40
    permission = 'submit_project'
41
1165.1.9 by William Grant
Split SubmitView.__init__ into new subclasses, {User,Group}SubmitView.
42
    def __init__(self, req, name, path):
1165.1.8 by William Grant
Start a submission UI in ivle.webapp.submit.
43
        # We need to work out which entity owns the repository, so we look
44
        # at the first two path segments. The first tells us the type.
1165.1.9 by William Grant
Split SubmitView.__init__ into new subclasses, {User,Group}SubmitView.
45
        self.context = self.get_repository_owner(req.store, name)
1165.1.13 by William Grant
Add an initial project selection UI to SubmitView.
46
        self.path = os.path.normpath(path)
1165.1.8 by William Grant
Start a submission UI in ivle.webapp.submit.
47
48
        if self.context is None:
49
            raise NotFound()
50
1165.1.28 by William Grant
Don't crash when the principal cannot be determined.
51
        self.offering = self.get_offering()
52
1165.1.9 by William Grant
Split SubmitView.__init__ into new subclasses, {User,Group}SubmitView.
53
    def get_repository_owner(self, store, name):
54
        """Return the owner of the repository given the name and a Store."""
55
        raise NotImplementedError()
56
1165.1.22 by William Grant
Detect the permitted offering for the given submission URL and restrict to that.
57
    def get_offering(self):
58
        """Return the offering that this path can be submitted to."""
59
        raise NotImplementedError()
60
1165.1.8 by William Grant
Start a submission UI in ivle.webapp.submit.
61
    def populate(self, req, ctx):
1165.1.20 by William Grant
Add a POST handler to SubmitView, which does the actual submission.
62
        if req.method == 'POST':
63
            data = dict(req.get_fieldstorage())
1165.1.25 by William Grant
Take the revision to submit from the query string.
64
            if 'revision' not in data:
1165.1.41 by William Grant
Give more human-readable 400 messages for submission.
65
                raise BadRequest('No revision selected.')
1165.1.25 by William Grant
Take the revision to submit from the query string.
66
67
            try:
68
                revision = int(data['revision'])
69
            except ValueError:
1165.1.41 by William Grant
Give more human-readable 400 messages for submission.
70
                raise BadRequest('Revision must be an integer.')
1165.1.25 by William Grant
Take the revision to submit from the query string.
71
1165.1.20 by William Grant
Add a POST handler to SubmitView, which does the actual submission.
72
            if 'project' not in data:
1165.1.41 by William Grant
Give more human-readable 400 messages for submission.
73
                raise BadRequest('No project selected.')
1165.1.20 by William Grant
Add a POST handler to SubmitView, which does the actual submission.
74
75
            try:
76
                projectid = int(data['project'])
77
            except ValueError:
1165.1.41 by William Grant
Give more human-readable 400 messages for submission.
78
                raise BadRequest('Project must be an integer.')
1165.1.20 by William Grant
Add a POST handler to SubmitView, which does the actual submission.
79
80
            project = req.store.find(Project, Project.id == projectid).one()
81
1165.1.24 by William Grant
400 if a non-matching project is POSTed.
82
            # This view's offering will be the sole offering for which the
83
            # path is permissible. We need to check that.
84
            if project.project_set.offering is not self.offering:
85
                raise BadRequest('Path is not permissible for this offering')
86
1165.1.20 by William Grant
Add a POST handler to SubmitView, which does the actual submission.
87
            if project is None:
88
                raise BadRequest('Specified project does not exist')
89
1165.1.42 by William Grant
Record who submitted each submission.
90
            project.submit(self.context, self.path, revision, req.user)
1165.1.20 by William Grant
Add a POST handler to SubmitView, which does the actual submission.
91
1165.1.27 by William Grant
Make the submit view significantly more readable.
92
        ctx['req'] = req
1165.1.13 by William Grant
Add an initial project selection UI to SubmitView.
93
        ctx['principal'] = self.context
1165.1.24 by William Grant
400 if a non-matching project is POSTed.
94
        ctx['offering'] = self.offering
1165.1.13 by William Grant
Add an initial project selection UI to SubmitView.
95
        ctx['path'] = self.path
1165.1.17 by William Grant
Disable project radio buttons if they are closed.
96
        ctx['now'] = datetime.datetime.now()
1165.1.16 by William Grant
Show the deadline for each project when submitting.
97
        ctx['format_datetime'] = ivle.date.format_datetime_for_paragraph
1165.1.8 by William Grant
Start a submission UI in ivle.webapp.submit.
98
1165.1.9 by William Grant
Split SubmitView.__init__ into new subclasses, {User,Group}SubmitView.
99
100
class UserSubmitView(SubmitView):
101
    def get_repository_owner(self, store, name):
102
        '''Resolve the user name into a user.'''
103
        return User.get_by_login(store, name)
104
1165.1.22 by William Grant
Detect the permitted offering for the given submission URL and restrict to that.
105
    def get_offering(self):
106
        return Store.of(self.context).find(Offering,
107
            Offering.id == Enrolment.offering_id,
108
            Enrolment.user_id == self.context.id,
109
            Offering.semester_id == Semester.id,
110
            Semester.state == u'current',
111
            Offering.subject_id == Subject.id,
112
            Subject.short_name == self.path.split('/')[0],
113
            ).one()
114
1165.1.9 by William Grant
Split SubmitView.__init__ into new subclasses, {User,Group}SubmitView.
115
116
class GroupSubmitView(SubmitView):
117
    def get_repository_owner(self, store, name):
118
        '''Resolve the subject_year_semester_group name into a group.'''
119
        namebits = name.split('_', 3)
120
        if len(namebits) != 4:
121
            return None
122
123
        # Find the project group with the given name in any project set in the
124
        # offering of the given subject in the semester with the given year
125
        # and semester.
126
        return store.find(ProjectGroup,
127
            ProjectGroup.name == namebits[3],
128
            ProjectGroup.project_set_id == ProjectSet.id,
129
            ProjectSet.offering_id == Offering.id,
130
            Offering.subject_id == Subject.id,
131
            Subject.short_name == namebits[0],
132
            Offering.semester_id == Semester.id,
133
            Semester.year == namebits[1],
134
            Semester.semester == namebits[2]).one()
135
1165.1.22 by William Grant
Detect the permitted offering for the given submission URL and restrict to that.
136
    def get_offering(self):
137
        return self.context.project_set.offering
138
1165.1.9 by William Grant
Split SubmitView.__init__ into new subclasses, {User,Group}SubmitView.
139
1165.1.8 by William Grant
Start a submission UI in ivle.webapp.submit.
140
class Plugin(ViewPlugin):
141
    urls = [
1165.1.9 by William Grant
Split SubmitView.__init__ into new subclasses, {User,Group}SubmitView.
142
        ('+submit/users/:name/*path', UserSubmitView),
143
        ('+submit/groups/:name/*path', GroupSubmitView),
1165.1.8 by William Grant
Start a submission UI in ivle.webapp.submit.
144
    ]