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

« back to all changes in this revision

Viewing changes to ivle/webapp/tutorial/__init__.py

  • Committer: William Grant
  • Date: 2009-12-08 03:50:24 UTC
  • mfrom: (1294.2.143 ui-the-third)
  • Revision ID: grantw@unimelb.edu.au-20091208035024-wjx8zp54gth15ph8
Merge ui-the-third. This is another UI revamp.

The header is now thin! Thin! The yellow bar is gone. The tabs are gone.
Breadcrumbs are here. Routes is replaced (with an object publishing
mechanism). Views are less repetitive. etc.

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
 
35
35
import ivle.database
36
36
from ivle.database import Subject, Offering, Semester, Exercise, \
37
 
                          ExerciseSave, WorksheetExercise
 
37
                          ExerciseSave, WorksheetExercise, ExerciseAttempt
38
38
from ivle.database import Worksheet as DBWorksheet
39
39
import ivle.worksheet.utils
 
40
from ivle.webapp import ApplicationRoot
40
41
from ivle.webapp.base.views import BaseView
41
42
from ivle.webapp.base.xhtml import XHTMLView
42
43
from ivle.webapp.base.plugins import ViewPlugin, MediaPlugin
43
 
from ivle.webapp.media import BaseMediaFileView, media_url
44
 
from ivle.webapp.errors import NotFound, Forbidden
 
44
from ivle.webapp.media import media_url
 
45
from ivle.webapp.errors import NotFound
45
46
from ivle.worksheet.rst import rst as rstfunc
46
 
from ivle.webapp.tutorial.service import AttemptsRESTView, AttemptRESTView, \
47
 
            WorksheetExerciseRESTView, WorksheetRESTView, WorksheetsRESTView
48
47
 
 
48
from ivle.webapp.tutorial.service import (AttemptsRESTView, AttemptRESTView,
 
49
            WorksheetExerciseRESTView, WorksheetRESTView, WorksheetsRESTView)
49
50
from ivle.webapp.tutorial.exercise_service import ExercisesRESTView, \
50
51
                                                  ExerciseRESTView
 
52
from ivle.webapp.tutorial.publishing import (root_to_exercise, exercise_url,
 
53
            offering_to_worksheet, worksheet_url,
 
54
            worksheet_to_worksheetexercise, worksheetexercise_url,
 
55
            ExerciseAttempts, worksheetexercise_to_exerciseattempts,
 
56
            exerciseattempts_url, exerciseattempts_to_attempt,
 
57
            exerciseattempt_url)
 
58
from ivle.webapp.tutorial.breadcrumbs import (ExerciseBreadcrumb,
 
59
            WorksheetBreadcrumb)
 
60
from ivle.webapp.tutorial.media import (SubjectMediaFile, SubjectMediaView,
 
61
    subject_to_media)
51
62
 
52
63
class Worksheet:
53
64
    """This class represents a worksheet and a particular students progress
72
83
    template = 'templates/subjectmenu.html'
73
84
    tab = 'subjects' # XXX
74
85
    permission = 'view'
75
 
 
76
 
    def __init__(self, req, subject, year, semester):
77
 
        """Find the given offering by subject, year and semester."""
78
 
        self.context = req.store.find(Offering,
79
 
            Offering.subject_id == Subject.id,
80
 
            Subject.short_name == subject,
81
 
            Offering.semester_id == Semester.id,
82
 
            Semester.year == year,
83
 
            Semester.semester == semester).one()
84
 
        
85
 
        if not self.context:
86
 
            raise NotFound()
87
 
 
 
86
    breadcrumb_text = 'Worksheets'
88
87
 
89
88
    def populate(self, req, ctx):
90
89
        """Create the context for the given offering."""
146
145
    tab = 'subjects'
147
146
    permission = 'view'
148
147
 
149
 
    def __init__(self, req, subject, year, semester, worksheet):
150
 
        self.context = req.store.find(DBWorksheet,
151
 
            DBWorksheet.offering_id == Offering.id,
152
 
            Offering.subject_id == Subject.id,
153
 
            Subject.short_name == subject,
154
 
            Offering.semester_id == Semester.id,
155
 
            Semester.year == year,
156
 
            Semester.semester == semester,
157
 
            DBWorksheet.identifier == worksheet).one()
158
 
        
159
 
        if self.context is None:
160
 
            raise NotFound(str(worksheet) + " was not found.")
161
 
        
162
 
        self.year = year
163
 
        self.semester = semester
164
 
 
165
148
    def populate(self, req, ctx):
166
149
        self.plugin_scripts[Plugin] = ['tutorial.js']
167
150
        self.plugin_styles[Plugin] = ['tutorial.css', 'worksheet.css']
171
154
 
172
155
        ctx['subject'] = self.context.offering.subject
173
156
        ctx['worksheet'] = self.context
174
 
        ctx['semester'] = self.semester
175
 
        ctx['year'] = self.year
 
157
        ctx['semester'] = self.context.offering.semester.semester
 
158
        ctx['year'] = self.context.offering.semester.year
176
159
 
177
160
        ctx['worksheetstream'] = genshi.Stream(list(genshi.XML(self.context.get_xml())))
178
161
        ctx['user'] = req.user
181
164
 
182
165
        ctx['worksheetstream'] = add_exercises(ctx['worksheetstream'], ctx, req)
183
166
 
184
 
class SubjectMediaView(BaseMediaFileView):
185
 
    '''The view of subject media files.
186
 
 
187
 
    URIs pointing here will just be served directly, from the subject's
188
 
    media directory.
189
 
    '''
190
 
    permission = 'view'
191
 
 
192
 
    def __init__(self, req, subject, path):
193
 
        self.context = req.store.find(Subject, short_name=subject).one()
194
 
        self.path = os.path.normpath(path)
195
 
 
196
 
    def _make_filename(self, req):
197
 
        # If the subject doesn't exist, self.subject will be None. Die.
198
 
        if not self.context:
199
 
            raise NotFound()
200
 
 
201
 
        subjectdir = os.path.join(req.config['paths']['data'],
202
 
                                  'content/subjects',
203
 
                                  self.context.short_name, 'media')
204
 
        return os.path.join(subjectdir, self.path)
205
 
 
206
167
def get_worksheets(subjectfile):
207
168
    '''Given a subject stream, get all the worksheets and put them in ctx'''
208
169
    worksheets = []
385
346
    template = "templates/worksheet_edit.html"
386
347
    tab = "subjects"
387
348
 
388
 
    def __init__(self, req, **kwargs):
389
 
    
390
 
        subject = kwargs['subject']
391
 
        year = kwargs['year']
392
 
        semester = kwargs['semester']
393
 
        worksheet = kwargs['worksheet']
394
 
        self.context = req.store.find(DBWorksheet,
395
 
            DBWorksheet.identifier == worksheet,
396
 
            DBWorksheet.offering_id == Offering.id,
397
 
            Offering.semester_id == Semester.id,
398
 
            Semester.year == year,
399
 
            Semester.semester == semester,
400
 
            Offering.subject_id == Subject.id,
401
 
            Subject.short_name == subject
402
 
        ).one()
403
 
        
404
 
        if self.context is None:
405
 
            raise NotFound()
406
 
        
407
 
        self.subject = subject
408
 
        self.year = year
409
 
        self.semester = semester
410
 
        self.worksheet = worksheet
411
 
        
412
 
            
413
349
    def populate(self, req, ctx):
414
350
        self.plugin_styles[Plugin] = ["tutorial_admin.css"]
415
351
        self.plugin_scripts[Plugin] = ['tutorial_admin.js']
416
 
        
 
352
 
417
353
        ctx['worksheet'] = self.context
418
 
        ctx['worksheetname'] = self.worksheet
 
354
        ctx['worksheetname'] = self.context.identifier
419
355
        ctx['subject'] = self.context.offering.subject
420
 
        ctx['year'] = self.year
421
 
        ctx['semester'] = self.semester
 
356
        ctx['year'] = self.context.offering.semester.year
 
357
        ctx['semester'] = self.context.offering.semester.semester
422
358
        #XXX: Get the list of formats from somewhere else
423
359
        ctx['formats'] = ['xml', 'rst']
424
360
 
428
364
    permission = "edit"
429
365
    template = "templates/worksheet_add.html"
430
366
 
431
 
    def __init__(self, req, subject, year, semester):
432
 
        self.context = req.store.find(Offering,
433
 
            Offering.semester_id == Semester.id,
434
 
            Semester.year == year,
435
 
            Semester.semester == semester,
436
 
            Offering.subject_id == Subject.id,
437
 
            Subject.short_name == subject
438
 
        ).one()
439
 
        
440
 
        self.subject = subject
441
 
        self.year = year
442
 
        self.semester = semester
443
 
        
444
 
        if self.context is None:
445
 
            raise NotFound()
446
 
            
447
367
    def populate(self, req, ctx):
448
368
        self.plugin_styles[Plugin] = ["tutorial_admin.css"]
449
369
        self.plugin_scripts[Plugin] = ['tutorial_admin.js']
450
370
        
451
371
        ctx['subject'] = self.context.subject
452
 
        ctx['year'] = self.year
453
 
        ctx['semester'] = self.semester
 
372
        ctx['year'] = self.context.semester.year
 
373
        ctx['semester'] = self.context.semester.semester
454
374
        
455
375
        #XXX: Get the list of formats from somewhere else
456
376
        ctx['formats'] = ['xml', 'rst']
460
380
    
461
381
    permission = 'edit'
462
382
    template = 'templates/worksheets_edit.html'
463
 
    
464
 
    def __init__(self, req, subject, year, semester):
465
 
        self.context = req.store.find(Offering,
466
 
            Offering.semester_id == Semester.id,
467
 
            Semester.year == year,
468
 
            Semester.semester == semester,
469
 
            Offering.subject_id == Subject.id,
470
 
            Subject.short_name == subject
471
 
        ).one()
472
 
        
473
 
        self.subject = subject
474
 
        self.year = year
475
 
        self.semester = semester
476
 
        
477
 
        if self.context is None:
478
 
            raise NotFound()
479
 
    
 
383
 
480
384
    def populate(self, req, ctx):
481
385
        self.plugin_styles[Plugin] = ['tutorial_admin.css']
482
386
        self.plugin_scripts[Plugin] = ['tutorial_admin.js']
483
387
        
484
388
        ctx['subject'] = self.context.subject
485
 
        ctx['year'] = self.year
486
 
        ctx['semester'] = self.semester
 
389
        ctx['year'] = self.context.semester.year
 
390
        ctx['semester'] = self.context.semester.semester
487
391
        
488
392
        ctx['worksheets'] = self.context.worksheets
489
393
        
496
400
    permission = 'edit'
497
401
    template = 'templates/exercise_edit.html'
498
402
    
499
 
    def __init__(self, req, exercise):
500
 
        self.context = req.store.find(Exercise, 
501
 
            Exercise.id == exercise).one()
502
 
 
503
 
        if self.context is None:
504
 
            raise NotFound()
505
 
    
506
403
    def populate(self, req, ctx):
507
404
        self.plugin_styles[Plugin] = ['exercise_admin.css']
508
405
        self.plugin_scripts[Plugin] = ['exercise_admin.js']
524
421
    permission = 'edit'
525
422
    template = 'templates/exercise_delete.html'
526
423
    
527
 
    def __init__(self, req, exercise):
528
 
        self.context = req.store.find(Exercise,
529
 
            Exercise.id == exercise).one()
530
 
        
531
 
        if self.context is None:
532
 
            raise NotFound()
533
 
 
534
424
    def populate(self, req, ctx):
535
425
 
536
426
        # If post, delete the exercise, or display a message explaining that
587
477
        ctx['exercises'] = req.store.find(Exercise).order_by(Exercise.id)
588
478
        ctx['mediapath'] = media_url(req, Plugin, 'images/')
589
479
 
 
480
 
590
481
class Plugin(ViewPlugin, MediaPlugin):
591
 
    urls = [
592
 
        # Worksheet View Urls
593
 
        ('subjects/:subject/+worksheets/+media/*(path)', SubjectMediaView),
594
 
        ('subjects/:subject/:year/:semester/+worksheets', OfferingView),
595
 
        ('subjects/:subject/:year/:semester/+worksheets/+new', WorksheetAddView),
596
 
        ('subjects/:subject/:year/:semester/+worksheets/+edit', WorksheetsEditView),
597
 
        ('subjects/:subject/:year/:semester/+worksheets/:worksheet', WorksheetView),
598
 
        ('subjects/:subject/:year/:semester/+worksheets/:worksheet/+edit', WorksheetEditView),
599
 
        
600
 
        # Worksheet Api Urls
601
 
        ('api/subjects/:subject/:year/:semester/+worksheets', WorksheetsRESTView),
602
 
        ('api/subjects/:subject/:year/:semester/+worksheets/:worksheet/*exercise/'
603
 
            '+attempts/:username', AttemptsRESTView),
604
 
        ('api/subjects/:subject/:year/:semester/+worksheets/:worksheet/*exercise/'
605
 
                '+attempts/:username/:date', AttemptRESTView),
606
 
        ('api/subjects/:subject/:year/:semester/+worksheets/:worksheet', WorksheetRESTView),
607
 
        ('api/subjects/:subject/:year/:semester/+worksheets/:worksheet/*exercise', WorksheetExerciseRESTView),
608
 
 
609
 
        # Exercise View Urls
610
 
        ('+exercises', ExercisesView),
611
 
        ('+exercises/+add', ExerciseAddView),
612
 
        ('+exercises/:exercise/+edit', ExerciseEditView),
613
 
        ('+exercises/:exercise/+delete', ExerciseDeleteView),
614
 
        
615
 
        # Exercise Api Urls
616
 
        ('api/+exercises', ExercisesRESTView),
617
 
        ('api/+exercises/*exercise', ExerciseRESTView),
618
 
    ]
 
482
    forward_routes = (root_to_exercise, offering_to_worksheet,
 
483
        worksheet_to_worksheetexercise, worksheetexercise_to_exerciseattempts,
 
484
        exerciseattempts_to_attempt, subject_to_media)
 
485
 
 
486
    reverse_routes = (exercise_url, worksheet_url, worksheetexercise_url,
 
487
        exerciseattempts_url, exerciseattempt_url)
 
488
 
 
489
    breadcrumbs = {Exercise: ExerciseBreadcrumb,
 
490
                   DBWorksheet: WorksheetBreadcrumb
 
491
                  }
 
492
 
 
493
    views = [(Offering, ('+worksheets', '+index'), OfferingView),
 
494
             (Offering, ('+worksheets', '+new'), WorksheetAddView),
 
495
             (Offering, ('+worksheets', '+edit'), WorksheetsEditView),
 
496
             (DBWorksheet, '+index', WorksheetView),
 
497
             (DBWorksheet, '+edit', WorksheetEditView),
 
498
             (ApplicationRoot, ('+exercises', '+index'), ExercisesView),
 
499
             (ApplicationRoot, ('+exercises', '+add'), ExerciseAddView),
 
500
             (Exercise, '+edit', ExerciseEditView),
 
501
             (Exercise, '+delete', ExerciseDeleteView),
 
502
             (SubjectMediaFile, '+index', SubjectMediaView),
 
503
 
 
504
             (Offering, ('+worksheets', '+index'), WorksheetsRESTView, 'api'),
 
505
             (DBWorksheet, '+index', WorksheetRESTView, 'api'),
 
506
             (WorksheetExercise, '+index', WorksheetExerciseRESTView, 'api'),
 
507
             (ExerciseAttempts, '+index', AttemptsRESTView, 'api'),
 
508
             (ExerciseAttempt, '+index', AttemptRESTView, 'api'),
 
509
             (ApplicationRoot, ('+exercises', '+index'), ExercisesRESTView,
 
510
              'api'),
 
511
             (Exercise, '+index', ExerciseRESTView, 'api'),
 
512
             ]
619
513
 
620
514
    media = 'media'
621
515
    help = {'Tutorial': 'help.html'}