~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-28 04:13:05 UTC
  • mfrom: (1801.1.2 die-cjson-die)
  • Revision ID: grantw@unimelb.edu.au-20100728041305-xwypm3cn1l1mnki1
Port from cjson to (simple)json.

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
30
31
 
31
32
from storm.locals import Desc, Store
32
33
import genshi
39
40
                                    DateTimeValidator)
40
41
from ivle.webapp.base.plugins import ViewPlugin, MediaPlugin
41
42
from ivle.webapp.base.xhtml import XHTMLView
 
43
from ivle.webapp.base.text import TextView
42
44
from ivle.webapp.errors import BadRequest
43
45
from ivle.webapp import ApplicationRoot
44
46
 
73
75
        ctx['user'] = req.user
74
76
        ctx['semesters'] = []
75
77
 
76
 
        for semester in req.store.find(Semester).order_by(Desc(Semester.year),
77
 
                                                     Desc(Semester.semester)):
 
78
        for semester in req.store.find(Semester).order_by(
 
79
            Desc(Semester.year), Desc(Semester.display_name)):
78
80
            if req.user.admin:
79
81
                # For admins, show all subjects in the system
80
82
                offerings = list(semester.offerings.find())
102
104
 
103
105
        ctx['subjects'] = req.store.find(Subject).order_by(Subject.name)
104
106
        ctx['semesters'] = req.store.find(Semester).order_by(
105
 
            Semester.year, Semester.semester)
106
 
 
107
 
 
108
 
class SubjectShortNameUniquenessValidator(formencode.FancyValidator):
109
 
    """A FormEncode validator that checks that a subject name is unused.
 
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.
110
112
 
111
113
    The subject referenced by state.existing_subject is permitted
112
114
    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.
113
118
    """
114
 
    def __init__(self, matching=None):
115
 
        self.matching = matching
 
119
 
 
120
    def __init__(self, attribute, display):
 
121
        self.attribute = attribute
 
122
        self.display = display
116
123
 
117
124
    def _to_python(self, value, state):
118
 
        if (state.store.find(
119
 
                Subject, short_name=value).one() not in
 
125
        if (state.store.find(Subject, **{self.attribute: value}).one() not in
120
126
                (None, state.existing_subject)):
121
127
            raise formencode.Invalid(
122
 
                'Short name already taken', value, state)
 
128
                '%s already taken' % self.display, value, state)
123
129
        return value
124
130
 
125
131
 
126
132
class SubjectSchema(formencode.Schema):
127
133
    short_name = formencode.All(
128
 
        SubjectShortNameUniquenessValidator(),
 
134
        SubjectUniquenessValidator('short_name', 'URL name'),
129
135
        URLNameValidator(not_empty=True))
130
136
    name = formencode.validators.UnicodeString(not_empty=True)
131
 
    code = formencode.validators.UnicodeString(not_empty=True)
 
137
    code = formencode.All(
 
138
        SubjectUniquenessValidator('code', 'Subject code'),
 
139
        formencode.validators.UnicodeString(not_empty=True))
132
140
 
133
141
 
134
142
class SubjectFormView(BaseFormView):
192
200
    """
193
201
    def _to_python(self, value, state):
194
202
        if (state.store.find(
195
 
                Semester, year=value['year'], semester=value['semester']
 
203
                Semester, year=value['year'], url_name=value['url_name']
196
204
                ).one() not in (None, state.existing_semester)):
197
205
            raise formencode.Invalid(
198
206
                'Semester already exists', value, state)
201
209
 
202
210
class SemesterSchema(formencode.Schema):
203
211
    year = URLNameValidator()
204
 
    semester = URLNameValidator()
 
212
    code = formencode.validators.UnicodeString()
 
213
    url_name = URLNameValidator()
 
214
    display_name = formencode.validators.UnicodeString()
205
215
    state = formencode.All(
206
216
        formencode.validators.OneOf(["past", "current", "future"]),
207
217
        formencode.validators.UnicodeString())
236
246
    def save_object(self, req, data):
237
247
        new_semester = Semester()
238
248
        new_semester.year = data['year']
239
 
        new_semester.semester = data['semester']
 
249
        new_semester.code = data['code']
 
250
        new_semester.url_name = data['url_name']
 
251
        new_semester.display_name = data['display_name']
240
252
        new_semester.state = data['state']
241
253
 
242
254
        req.store.add(new_semester)
253
265
    def get_default_data(self, req):
254
266
        return {
255
267
            'year': self.context.year,
256
 
            'semester': self.context.semester,
 
268
            'code': self.context.code,
 
269
            'url_name': self.context.url_name,
 
270
            'display_name': self.context.display_name,
257
271
            'state': self.context.state,
258
272
            }
259
273
 
260
274
    def save_object(self, req, data):
261
275
        self.context.year = data['year']
262
 
        self.context.semester = data['semester']
 
276
        self.context.code = data['code']
 
277
        self.context.url_name = data['url_name']
 
278
        self.context.display_name = data['display_name']
263
279
        self.context.state = data['state']
264
280
 
265
281
        return self.context
308
324
 
309
325
        ctx['worksheets'], problems_total, problems_done = (
310
326
            ivle.worksheet.utils.create_list_of_fake_worksheets_and_stats(
311
 
                req.config, req.store, req.user, self.context))
 
327
                req.config, req.store, req.user, self.context,
 
328
                as_of=self.context.worksheet_cutoff))
312
329
 
313
330
        ctx['exercises_total'] = problems_total
314
331
        ctx['exercises_done'] = problems_done
355
372
            year = semester = None
356
373
 
357
374
        semester = state.store.find(
358
 
            Semester, year=year, semester=semester).one()
 
375
            Semester, year=year, url_name=semester).one()
359
376
        if semester:
360
377
            return semester
361
378
        else:
385
402
    description = formencode.validators.UnicodeString(
386
403
        if_missing=None, not_empty=False)
387
404
    url = formencode.validators.URL(if_missing=None, not_empty=False)
 
405
    worksheet_cutoff = DateTimeValidator(if_missing=None, not_empty=False)
388
406
    show_worksheet_marks = formencode.validators.StringBoolean(
389
407
        if_missing=False)
390
408
 
414
432
        super(OfferingEdit, self).populate(req, ctx)
415
433
        ctx['subjects'] = req.store.find(Subject).order_by(Subject.name)
416
434
        ctx['semesters'] = req.store.find(Semester).order_by(
417
 
            Semester.year, Semester.semester)
 
435
            Semester.year, Semester.display_name)
418
436
        ctx['force_subject'] = None
419
437
 
420
438
    def populate_state(self, state):
424
442
        return {
425
443
            'subject': self.context.subject.short_name,
426
444
            'semester': self.context.semester.year + '/' +
427
 
                        self.context.semester.semester,
 
445
                        self.context.semester.url_name,
428
446
            'url': self.context.url,
429
447
            'description': self.context.description,
 
448
            'worksheet_cutoff': self.context.worksheet_cutoff,
430
449
            'show_worksheet_marks': self.context.show_worksheet_marks,
431
450
            }
432
451
 
436
455
            self.context.semester = data['semester']
437
456
        self.context.description = data['description']
438
457
        self.context.url = unicode(data['url']) if data['url'] else None
 
458
        self.context.worksheet_cutoff = data['worksheet_cutoff']
439
459
        self.context.show_worksheet_marks = data['show_worksheet_marks']
440
460
        return self.context
441
461
 
456
476
        super(OfferingNew, self).populate(req, ctx)
457
477
        ctx['subjects'] = req.store.find(Subject).order_by(Subject.name)
458
478
        ctx['semesters'] = req.store.find(Semester).order_by(
459
 
            Semester.year, Semester.semester)
 
479
            Semester.year, Semester.display_name)
460
480
        ctx['force_subject'] = None
461
481
 
462
482
    def populate_state(self, state):
471
491
        new_offering.semester = data['semester']
472
492
        new_offering.description = data['description']
473
493
        new_offering.url = unicode(data['url']) if data['url'] else None
 
494
        new_offering.worksheet_cutoff = data['worksheet_cutoff']
474
495
        new_offering.show_worksheet_marks = data['show_worksheet_marks']
475
496
 
476
497
        req.store.add(new_offering)
507
528
        super(OfferingCloneWorksheets, self).populate(req, ctx)
508
529
        ctx['subjects'] = req.store.find(Subject).order_by(Subject.name)
509
530
        ctx['semesters'] = req.store.find(Semester).order_by(
510
 
            Semester.year, Semester.semester)
 
531
            Semester.year, Semester.display_name)
511
532
 
512
533
    def get_default_data(self, req):
513
534
        return {}
730
751
    permission = "view_project_submissions"
731
752
    tab = 'subjects'
732
753
 
733
 
    def build_subversion_url(self, svnroot, submission):
734
 
        princ = submission.assessed.principal
735
 
 
736
 
        if isinstance(princ, User):
737
 
            path = 'users/%s' % princ.login
738
 
        else:
739
 
            path = 'groups/%s_%s_%s_%s' % (
740
 
                    princ.project_set.offering.subject.short_name,
741
 
                    princ.project_set.offering.semester.year,
742
 
                    princ.project_set.offering.semester.semester,
743
 
                    princ.name
744
 
                    )
745
 
        return urlparse.urljoin(
746
 
                    svnroot,
747
 
                    os.path.join(path, submission.path[1:] if
748
 
                                       submission.path.startswith(os.sep) else
749
 
                                       submission.path))
750
 
 
751
754
    def populate(self, req, ctx):
752
755
        self.plugin_styles[Plugin] = ["project.css"]
753
756
 
757
760
        ctx['EnrolView'] = EnrolView
758
761
        ctx['format_datetime'] = ivle.date.make_date_nice
759
762
        ctx['format_datetime_short'] = ivle.date.format_datetime_for_paragraph
760
 
        ctx['build_subversion_url'] = self.build_subversion_url
761
 
        ctx['svn_addr'] = req.config['urls']['svn_addr']
762
763
        ctx['project'] = self.context
763
764
        ctx['user'] = req.user
764
765
        ctx['ProjectEdit'] = ProjectEdit
765
766
        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
766
785
 
767
786
class ProjectUniquenessValidator(formencode.FancyValidator):
768
787
    """A FormEncode validator that checks that a project short_name is unique
963
982
             (Project, '+index', ProjectView),
964
983
             (Project, '+edit', ProjectEdit),
965
984
             (Project, '+delete', ProjectDelete),
 
985
             (Project, ('+export', 'project-export.sh'),
 
986
                ProjectBashExportView),
966
987
             ]
967
988
 
968
989
    breadcrumbs = {Subject: SubjectBreadcrumb,