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

« back to all changes in this revision

Viewing changes to ivle/database.py

  • Committer: William Grant
  • Date: 2009-03-17 04:48:07 UTC
  • mfrom: (1099.1.243 exercise-ui)
  • Revision ID: grantw@unimelb.edu.au-20090317044807-pozdt54fapazp2sp
Merge lp:~ivle-dev/ivle/exercise-ui.

Lecturers can now add and edit exercises, and worksheets can be written
in RST directly inside IVLE.

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
 
30
30
from storm.locals import create_database, Store, Int, Unicode, DateTime, \
31
31
                         Reference, ReferenceSet, Bool, Storm, Desc
32
 
from storm.exceptions import NotOneError
 
32
from storm.exceptions import NotOneError, IntegrityError
33
33
 
34
34
import ivle.conf
 
35
from ivle.worksheet.rst import rst
35
36
 
36
37
__all__ = ['get_store',
37
38
            'User',
265
266
 
266
267
    worksheets = ReferenceSet(id, 
267
268
        'Worksheet.offering_id', 
268
 
        order_by="Worksheet.seq_no"
 
269
        order_by="seq_no"
269
270
    )
270
271
 
271
272
    __init__ = _kwarg_init
424
425
    include = Unicode()
425
426
    num_rows = Int()
426
427
 
 
428
    worksheet_exercises =  ReferenceSet(id,
 
429
        'WorksheetExercise.exercise_id')
 
430
 
427
431
    worksheets = ReferenceSet(id,
428
432
        'WorksheetExercise.exercise_id',
429
433
        'WorksheetExercise.worksheet_id',
430
434
        'Worksheet.id'
431
435
    )
432
436
    
433
 
    test_suites = ReferenceSet(id, 'TestSuite.exercise_id')
 
437
    test_suites = ReferenceSet(id, 
 
438
        'TestSuite.exercise_id',
 
439
        order_by='seq_no')
434
440
 
435
441
    __init__ = _kwarg_init
436
442
 
439
445
 
440
446
    def get_permissions(self, user):
441
447
        perms = set()
 
448
        roles = set()
442
449
        if user is not None:
443
450
            if user.admin:
444
451
                perms.add('edit')
445
452
                perms.add('view')
 
453
            elif 'lecturer' in set((e.role for e in user.active_enrolments)):
 
454
                perms.add('edit')
 
455
                perms.add('view')
 
456
            
446
457
        return perms
 
458
    
 
459
    def get_description(self):
 
460
        return rst(self.description)
 
461
 
 
462
    def delete(self):
 
463
        """Deletes the exercise, providing it has no associated worksheets."""
 
464
        if (self.worksheet_exercises.count() > 0):
 
465
            raise IntegrityError()
 
466
        for suite in self.test_suites:
 
467
            suite.delete()
 
468
        Store.of(self).remove(self)
447
469
 
448
470
class Worksheet(Storm):
449
471
    __storm_table__ = "worksheet"
466
488
    # Use worksheet_exercises to get access to the *active* WorksheetExercise
467
489
    # objects binding worksheets to exercises. This is required to access the
468
490
    # "optional" field.
 
491
 
469
492
    @property
470
493
    def worksheet_exercises(self):
471
494
        return self.all_worksheet_exercises.find(active=True)
487
510
        return store.find(cls, cls.subject == unicode(subjectname),
488
511
            cls.name == unicode(worksheetname)).one()
489
512
 
490
 
    def remove_all_exercises(self, store):
 
513
    def remove_all_exercises(self):
491
514
        """
492
515
        Remove all exercises from this worksheet.
493
516
        This does not delete the exercises themselves. It just removes them
494
517
        from the worksheet.
495
518
        """
 
519
        store = Store.of(self)
 
520
        for ws_ex in self.all_worksheet_exercises:
 
521
            if ws_ex.saves.count() > 0 or ws_ex.attempts.count() > 0:
 
522
                raise IntegrityError()
496
523
        store.find(WorksheetExercise,
497
524
            WorksheetExercise.worksheet == self).remove()
498
525
            
499
526
    def get_permissions(self, user):
500
527
        return self.offering.get_permissions(user)
501
 
 
 
528
    
 
529
    def get_xml(self):
 
530
        """Returns the xml of this worksheet, converts from rst if required."""
 
531
        if self.format == u'rst':
 
532
            ws_xml = rst(self.data)
 
533
            return ws_xml
 
534
        else:
 
535
            return self.data
 
536
    
 
537
    def delete(self):
 
538
        """Deletes the worksheet, provided it has no attempts on any exercises.
 
539
        
 
540
        Returns True if delete succeeded, or False if this worksheet has
 
541
        attempts attached."""
 
542
        for ws_ex in self.all_worksheet_exercises:
 
543
            if ws_ex.saves.count() > 0 or ws_ex.attempts.count() > 0:
 
544
                raise IntegrityError()
 
545
        
 
546
        self.remove_all_exercises()
 
547
        Store.of(self).remove(self)
 
548
        
502
549
class WorksheetExercise(Storm):
503
550
    __storm_table__ = "worksheet_exercise"
504
551
    
523
570
 
524
571
    def get_permissions(self, user):
525
572
        return self.worksheet.get_permissions(user)
 
573
    
526
574
 
527
575
class ExerciseSave(Storm):
528
576
    """
587
635
    function = Unicode()
588
636
    stdin = Unicode()
589
637
    exercise = Reference(exercise_id, Exercise.id)
590
 
    test_cases = ReferenceSet(suiteid, 'TestCase.suiteid')
591
 
    variables = ReferenceSet(suiteid, 'TestSuiteVar.suiteid')
 
638
    test_cases = ReferenceSet(suiteid, 'TestCase.suiteid', order_by="seq_no")
 
639
    variables = ReferenceSet(suiteid, 'TestSuiteVar.suiteid', order_by='arg_no')
 
640
    
 
641
    def delete(self):
 
642
        """Delete this suite, without asking questions."""
 
643
        for vaariable in self.variables:
 
644
            variable.delete()
 
645
        for test_case in self.test_cases:
 
646
            test_case.delete()
 
647
        Store.of(self).remove(self)
592
648
 
593
649
class TestCase(Storm):
594
650
    """A TestCase is a member of a TestSuite.
608
664
    parts = ReferenceSet(testid, "TestCasePart.testid")
609
665
    
610
666
    __init__ = _kwarg_init
 
667
    
 
668
    def delete(self):
 
669
        for part in self.parts:
 
670
            part.delete()
 
671
        Store.of(self).remove(self)
611
672
 
612
673
class TestSuiteVar(Storm):
613
674
    """A container for the arguments of a Test Suite"""
625
686
    
626
687
    __init__ = _kwarg_init
627
688
    
 
689
    def delete(self):
 
690
        Store.of(self).remove(self)
 
691
    
628
692
class TestCasePart(Storm):
629
693
    """A container for the test elements of a Test Case"""
630
694
    __storm_table__ = "test_case_part"
641
705
    test = Reference(testid, "TestCase.testid")
642
706
    
643
707
    __init__ = _kwarg_init
 
708
    
 
709
    def delete(self):
 
710
        Store.of(self).remove(self)