~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: 2010-07-03 08:18:50 UTC
  • Revision ID: grantw@unimelb.edu.au-20100703081850-ygl8vp5nyznf3dnk
Trailing slashes in URLs can now be detected by views accepting subpaths.

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
import urllib
28
28
import urlparse
29
29
import cgi
30
 
import datetime
31
30
 
32
31
from storm.locals import Desc, Store
33
32
import genshi
40
39
                                    DateTimeValidator)
41
40
from ivle.webapp.base.plugins import ViewPlugin, MediaPlugin
42
41
from ivle.webapp.base.xhtml import XHTMLView
43
 
from ivle.webapp.base.text import TextView
44
42
from ivle.webapp.errors import BadRequest
45
43
from ivle.webapp import ApplicationRoot
46
44
 
75
73
        ctx['user'] = req.user
76
74
        ctx['semesters'] = []
77
75
 
78
 
        for semester in req.store.find(Semester).order_by(
79
 
            Desc(Semester.year), Desc(Semester.display_name)):
 
76
        for semester in req.store.find(Semester).order_by(Desc(Semester.year),
 
77
                                                     Desc(Semester.semester)):
80
78
            if req.user.admin:
81
79
                # For admins, show all subjects in the system
82
80
                offerings = list(semester.offerings.find())
104
102
 
105
103
        ctx['subjects'] = req.store.find(Subject).order_by(Subject.name)
106
104
        ctx['semesters'] = req.store.find(Semester).order_by(
107
 
            Semester.year, Semester.display_name)
108
 
 
109
 
 
110
 
class SubjectUniquenessValidator(formencode.FancyValidator):
111
 
    """A FormEncode validator that checks that a subject attribute is unique.
 
105
            Semester.year, Semester.semester)
 
106
 
 
107
 
 
108
class SubjectShortNameUniquenessValidator(formencode.FancyValidator):
 
109
    """A FormEncode validator that checks that a subject name is unused.
112
110
 
113
111
    The subject referenced by state.existing_subject is permitted
114
112
    to hold that name. If any other object holds it, the input is rejected.
115
 
 
116
 
    :param attribute: the name of the attribute to check.
117
 
    :param display: a string to identify the field in case of error.
118
113
    """
119
 
 
120
 
    def __init__(self, attribute, display):
121
 
        self.attribute = attribute
122
 
        self.display = display
 
114
    def __init__(self, matching=None):
 
115
        self.matching = matching
123
116
 
124
117
    def _to_python(self, value, state):
125
 
        if (state.store.find(Subject, **{self.attribute: value}).one() not in
 
118
        if (state.store.find(
 
119
                Subject, short_name=value).one() not in
126
120
                (None, state.existing_subject)):
127
121
            raise formencode.Invalid(
128
 
                '%s already taken' % self.display, value, state)
 
122
                'Short name already taken', value, state)
129
123
        return value
130
124
 
131
125
 
132
126
class SubjectSchema(formencode.Schema):
133
127
    short_name = formencode.All(
134
 
        SubjectUniquenessValidator('short_name', 'URL name'),
 
128
        SubjectShortNameUniquenessValidator(),
135
129
        URLNameValidator(not_empty=True))
136
130
    name = formencode.validators.UnicodeString(not_empty=True)
137
 
    code = formencode.All(
138
 
        SubjectUniquenessValidator('code', 'Subject code'),
139
 
        formencode.validators.UnicodeString(not_empty=True))
 
131
    code = formencode.validators.UnicodeString(not_empty=True)
140
132
 
141
133
 
142
134
class SubjectFormView(BaseFormView):
200
192
    """
201
193
    def _to_python(self, value, state):
202
194
        if (state.store.find(
203
 
                Semester, year=value['year'], url_name=value['url_name']
 
195
                Semester, year=value['year'], semester=value['semester']
204
196
                ).one() not in (None, state.existing_semester)):
205
197
            raise formencode.Invalid(
206
198
                'Semester already exists', value, state)
209
201
 
210
202
class SemesterSchema(formencode.Schema):
211
203
    year = URLNameValidator()
212
 
    code = formencode.validators.UnicodeString()
213
 
    url_name = URLNameValidator()
214
 
    display_name = formencode.validators.UnicodeString()
 
204
    semester = URLNameValidator()
215
205
    state = formencode.All(
216
206
        formencode.validators.OneOf(["past", "current", "future"]),
217
207
        formencode.validators.UnicodeString())
246
236
    def save_object(self, req, data):
247
237
        new_semester = Semester()
248
238
        new_semester.year = data['year']
249
 
        new_semester.code = data['code']
250
 
        new_semester.url_name = data['url_name']
251
 
        new_semester.display_name = data['display_name']
 
239
        new_semester.semester = data['semester']
252
240
        new_semester.state = data['state']
253
241
 
254
242
        req.store.add(new_semester)
265
253
    def get_default_data(self, req):
266
254
        return {
267
255
            'year': self.context.year,
268
 
            'code': self.context.code,
269
 
            'url_name': self.context.url_name,
270
 
            'display_name': self.context.display_name,
 
256
            'semester': self.context.semester,
271
257
            'state': self.context.state,
272
258
            }
273
259
 
274
260
    def save_object(self, req, data):
275
261
        self.context.year = data['year']
276
 
        self.context.code = data['code']
277
 
        self.context.url_name = data['url_name']
278
 
        self.context.display_name = data['display_name']
 
262
        self.context.semester = data['semester']
279
263
        self.context.state = data['state']
280
264
 
281
265
        return self.context
372
356
            year = semester = None
373
357
 
374
358
        semester = state.store.find(
375
 
            Semester, year=year, url_name=semester).one()
 
359
            Semester, year=year, semester=semester).one()
376
360
        if semester:
377
361
            return semester
378
362
        else:
432
416
        super(OfferingEdit, self).populate(req, ctx)
433
417
        ctx['subjects'] = req.store.find(Subject).order_by(Subject.name)
434
418
        ctx['semesters'] = req.store.find(Semester).order_by(
435
 
            Semester.year, Semester.display_name)
 
419
            Semester.year, Semester.semester)
436
420
        ctx['force_subject'] = None
437
421
 
438
422
    def populate_state(self, state):
442
426
        return {
443
427
            'subject': self.context.subject.short_name,
444
428
            'semester': self.context.semester.year + '/' +
445
 
                        self.context.semester.url_name,
 
429
                        self.context.semester.semester,
446
430
            'url': self.context.url,
447
431
            'description': self.context.description,
448
432
            'worksheet_cutoff': self.context.worksheet_cutoff,
476
460
        super(OfferingNew, self).populate(req, ctx)
477
461
        ctx['subjects'] = req.store.find(Subject).order_by(Subject.name)
478
462
        ctx['semesters'] = req.store.find(Semester).order_by(
479
 
            Semester.year, Semester.display_name)
 
463
            Semester.year, Semester.semester)
480
464
        ctx['force_subject'] = None
481
465
 
482
466
    def populate_state(self, state):
528
512
        super(OfferingCloneWorksheets, self).populate(req, ctx)
529
513
        ctx['subjects'] = req.store.find(Subject).order_by(Subject.name)
530
514
        ctx['semesters'] = req.store.find(Semester).order_by(
531
 
            Semester.year, Semester.display_name)
 
515
            Semester.year, Semester.semester)
532
516
 
533
517
    def get_default_data(self, req):
534
518
        return {}
751
735
    permission = "view_project_submissions"
752
736
    tab = 'subjects'
753
737
 
 
738
    def build_subversion_url(self, req, submission):
 
739
        princ = submission.assessed.principal
 
740
 
 
741
        return os.path.join(princ.get_svn_url(req.config, req),
 
742
                            submission.path[1:] if
 
743
                                submission.path.startswith(os.sep) else
 
744
                                submission.path)
 
745
 
754
746
    def populate(self, req, ctx):
755
747
        self.plugin_styles[Plugin] = ["project.css"]
756
748
 
760
752
        ctx['EnrolView'] = EnrolView
761
753
        ctx['format_datetime'] = ivle.date.make_date_nice
762
754
        ctx['format_datetime_short'] = ivle.date.format_datetime_for_paragraph
 
755
        ctx['build_subversion_url'] = self.build_subversion_url
763
756
        ctx['project'] = self.context
764
757
        ctx['user'] = req.user
765
758
        ctx['ProjectEdit'] = ProjectEdit
766
759
        ctx['ProjectDelete'] = ProjectDelete
767
 
        ctx['ProjectExport'] = ProjectBashExportView
768
 
 
769
 
class ProjectBashExportView(TextView):
770
 
    """Produce a Bash script for exporting projects"""
771
 
    template = "templates/project-export.sh"
772
 
    content_type = "text/x-sh"
773
 
    permission = "view_project_submissions"
774
 
 
775
 
    def populate(self, req, ctx):
776
 
        ctx['req'] = req
777
 
        ctx['permissions'] = self.context.get_permissions(req.user,req.config)
778
 
        ctx['format_datetime'] = ivle.date.make_date_nice
779
 
        ctx['format_datetime_short'] = ivle.date.format_datetime_for_paragraph
780
 
        ctx['project'] = self.context
781
 
        ctx['user'] = req.user
782
 
        ctx['now'] = datetime.datetime.now()
783
 
        ctx['format_datetime'] = ivle.date.make_date_nice
784
 
        ctx['format_datetime_short'] = ivle.date.format_datetime_for_paragraph
785
760
 
786
761
class ProjectUniquenessValidator(formencode.FancyValidator):
787
762
    """A FormEncode validator that checks that a project short_name is unique
982
957
             (Project, '+index', ProjectView),
983
958
             (Project, '+edit', ProjectEdit),
984
959
             (Project, '+delete', ProjectDelete),
985
 
             (Project, ('+export', 'project-export.sh'),
986
 
                ProjectBashExportView),
987
960
             ]
988
961
 
989
962
    breadcrumbs = {Subject: SubjectBreadcrumb,