31
31
from xml.dom import minidom
34
from storm.locals import Store
35
36
import ivle.database
36
37
from ivle.database import Subject, Offering, Semester, Exercise, \
37
ExerciseSave, WorksheetExercise
38
ExerciseSave, WorksheetExercise, ExerciseAttempt
38
39
from ivle.database import Worksheet as DBWorksheet
39
40
import ivle.worksheet.utils
41
from ivle.webapp import ApplicationRoot
40
42
from ivle.webapp.base.views import BaseView
41
43
from ivle.webapp.base.xhtml import XHTMLView
42
44
from ivle.webapp.base.plugins import ViewPlugin, MediaPlugin
43
#from ivle.webapp.media import BaseMediaFileView, media_url
45
from ivle.webapp.media import media_url#, BaseMediaFileView
44
46
from ivle.webapp.errors import NotFound, Forbidden
45
47
from ivle.worksheet.rst import rst as rstfunc
46
from ivle.webapp.tutorial.service import AttemptsRESTView, AttemptRESTView, \
47
WorksheetExerciseRESTView, WorksheetRESTView, WorksheetsRESTView
48
from ivle.webapp.tutorial.service import (AttemptsRESTView, AttemptRESTView,
49
WorksheetExerciseRESTView, WorksheetRESTView, WorksheetsRESTView,
50
ExerciseAttempts, worksheet_to_worksheet_exercise,
51
worksheet_exercise_to_user_attempts, exerciseattempts_to_attempt,
49
54
from ivle.webapp.tutorial.exercise_service import ExercisesRESTView, \
147
139
permission = 'view'
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()
159
if self.context is None:
160
raise NotFound(str(worksheet) + " was not found.")
163
self.semester = semester
165
141
def populate(self, req, ctx):
166
142
self.plugin_scripts[Plugin] = ['tutorial.js']
167
143
self.plugin_styles[Plugin] = ['tutorial.css', 'worksheet.css']
385
361
template = "templates/worksheet_edit.html"
388
def __init__(self, req, **kwargs):
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
404
if self.context is None:
407
self.subject = subject
409
self.semester = semester
410
self.worksheet = worksheet
413
364
def populate(self, req, ctx):
414
365
self.plugin_styles[Plugin] = ["tutorial_admin.css"]
415
366
self.plugin_scripts[Plugin] = ['tutorial_admin.js']
417
368
ctx['worksheet'] = self.context
418
ctx['worksheetname'] = self.worksheet
369
ctx['worksheetname'] = self.context.identifier
419
370
ctx['subject'] = self.context.offering.subject
420
ctx['year'] = self.year
421
ctx['semester'] = self.semester
371
ctx['year'] = self.context.offering.semester.year
372
ctx['semester'] = self.context.offering.semester.semester
422
373
#XXX: Get the list of formats from somewhere else
423
374
ctx['formats'] = ['xml', 'rst']
428
379
permission = "edit"
429
380
template = "templates/worksheet_add.html"
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
440
self.subject = subject
442
self.semester = semester
444
if self.context is None:
447
382
def populate(self, req, ctx):
448
383
self.plugin_styles[Plugin] = ["tutorial_admin.css"]
449
384
self.plugin_scripts[Plugin] = ['tutorial_admin.js']
451
386
ctx['subject'] = self.context.subject
452
ctx['year'] = self.year
453
ctx['semester'] = self.semester
387
ctx['year'] = self.context.semester.year
388
ctx['semester'] = self.context.semester.semester
455
390
#XXX: Get the list of formats from somewhere else
456
391
ctx['formats'] = ['xml', 'rst']
461
396
permission = 'edit'
462
397
template = 'templates/worksheets_edit.html'
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
473
self.subject = subject
475
self.semester = semester
477
if self.context is None:
480
399
def populate(self, req, ctx):
481
400
self.plugin_styles[Plugin] = ['tutorial_admin.css']
482
401
self.plugin_scripts[Plugin] = ['tutorial_admin.js']
484
403
ctx['subject'] = self.context.subject
485
ctx['year'] = self.year
486
ctx['semester'] = self.semester
404
ctx['year'] = self.context.semester.year
405
ctx['semester'] = self.context.semester.semester
488
407
ctx['worksheets'] = self.context.worksheets
587
492
ctx['exercises'] = req.store.find(Exercise).order_by(Exercise.id)
588
493
ctx['mediapath'] = media_url(req, Plugin, 'images/')
496
def offering_to_worksheet(offering, worksheet_name):
497
return Store.of(offering).find(
499
DBWorksheet.offering == offering,
500
DBWorksheet.identifier == worksheet_name
504
def root_to_exercise(root, exercise_name):
505
return root.store.find(
507
Exercise.id == exercise_name
590
511
class Plugin(ViewPlugin, MediaPlugin):
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),
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),
610
('+exercises', ExercisesView),
611
('+exercises/+add', ExerciseAddView),
612
('+exercises/:exercise/+edit', ExerciseEditView),
613
('+exercises/:exercise/+delete', ExerciseDeleteView),
616
('api/+exercises', ExercisesRESTView),
617
('api/+exercises/*exercise', ExerciseRESTView),
512
forward_routes = [(Offering, '+worksheets', offering_to_worksheet, 1),
513
(DBWorksheet, None, worksheet_to_worksheet_exercise, 1),
514
(WorksheetExercise, '+attempts',
515
worksheet_exercise_to_user_attempts, 1),
516
(ExerciseAttempts, None, exerciseattempts_to_attempt, 1),
517
(ApplicationRoot, '+exercises', root_to_exercise, 1),
520
views = [(Offering, ('+worksheets', '+index'), OfferingView),
521
(Offering, ('+worksheets', '+new'), WorksheetAddView),
522
(Offering, ('+worksheets', '+edit'), WorksheetsEditView),
523
(DBWorksheet, '+index', WorksheetView),
524
(DBWorksheet, '+edit', WorksheetEditView),
525
(ApplicationRoot, ('+exercises', '+index'), ExercisesView),
526
(ApplicationRoot, ('+exercises', '+add'), ExerciseAddView),
527
(Exercise, '+edit', ExerciseEditView),
528
(Exercise, '+delete', ExerciseDeleteView),
530
(Offering, ('+worksheets', '+index'), WorksheetsRESTView, 'api'),
531
(DBWorksheet, '+index', WorksheetRESTView, 'api'),
532
(WorksheetExercise, '+index', WorksheetExerciseRESTView, 'api'),
533
(ExerciseAttempts, '+index', AttemptsRESTView, 'api'),
534
(ExerciseAttempt, '+index', AttemptRESTView, 'api'),
535
(ApplicationRoot, ('+exercises', '+index'), ExercisesRESTView,
537
(Exercise, '+index', ExerciseRESTView, 'api'),
621
541
help = {'Tutorial': 'help.html'}