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

« back to all changes in this revision

Viewing changes to ivle/database.py

  • Committer: William Grant
  • Date: 2010-02-26 06:33:35 UTC
  • Revision ID: grantw@unimelb.edu.au-20100226063335-25ka31up8cegwaiz
ivle.interpret.execute_raw now sets a clean environment, in particular with HOME set correctly.

Show diffs side-by-side

added added

removed removed

Lines of Context:
325
325
    semester = Reference(semester_id, Semester.id)
326
326
    description = Unicode()
327
327
    url = Unicode()
 
328
    show_worksheet_marks = Bool()
 
329
    worksheet_cutoff = DateTime()
328
330
    groups_student_permissions = Unicode()
329
331
 
330
332
    enrolments = ReferenceSet(id, 'Enrolment.offering_id')
393
395
                perms.add('view_project_submissions')
394
396
                perms.add('admin_groups')
395
397
                perms.add('edit_worksheets')
 
398
                perms.add('view_worksheet_marks')
396
399
                perms.add('edit')           # Can edit projects & details
397
400
                perms.add('enrol')          # Can see enrolment screen at all
398
401
                perms.add('enrol_student')  # Can enrol students
426
429
        # XXX: Respect extensions.
427
430
        return self.projects.find(Project.deadline > datetime.datetime.now())
428
431
 
 
432
    def has_worksheet_cutoff_passed(self, user):
 
433
        """Check whether the worksheet cutoff has passed.
 
434
        A user is required, in case we support extensions.
 
435
        """
 
436
        if self.worksheet_cutoff is None:
 
437
            return False
 
438
        else:
 
439
            return self.worksheet_cutoff < datetime.datetime.now()
 
440
 
429
441
    def clone_worksheets(self, source):
430
442
        """Clone all worksheets from the specified source to this offering."""
431
443
        import ivle.worksheet.utils
435
447
            newws.identifier = worksheet.identifier
436
448
            newws.name = worksheet.name
437
449
            newws.assessable = worksheet.assessable
 
450
            newws.published = worksheet.published
438
451
            newws.data = worksheet.data
439
452
            newws.format = worksheet.format
440
453
            newws.offering = self
645
658
            return
646
659
        return assessed.submissions
647
660
 
 
661
    @property
 
662
    def can_delete(self):
 
663
        """Can only delete if there are no submissions."""
 
664
        return self.submissions.count() == 0
648
665
 
 
666
    def delete(self):
 
667
        """Delete the project. Fails if can_delete is False."""
 
668
        if not self.can_delete:
 
669
            raise IntegrityError()
 
670
        for assessed in self.assesseds:
 
671
            assessed.delete()
 
672
        Store.of(self).remove(self)
649
673
 
650
674
class ProjectGroup(Storm):
651
675
    """A group of students working together on a project."""
798
822
 
799
823
        return a
800
824
 
 
825
    def delete(self):
 
826
        """Delete the assessed. Fails if there are any submissions. Deletes
 
827
        extensions."""
 
828
        if self.submissions.count() > 0:
 
829
            raise IntegrityError()
 
830
        for extension in self.extensions:
 
831
            extension.delete()
 
832
        Store.of(self).remove(self)
801
833
 
802
834
class ProjectExtension(Storm):
803
835
    """An extension granted to a user or group on a particular project.
815
847
    approver = Reference(approver_id, User.id)
816
848
    notes = Unicode()
817
849
 
 
850
    def delete(self):
 
851
        """Delete the extension."""
 
852
        Store.of(self).remove(self)
 
853
 
818
854
class SubmissionError(Exception):
819
855
    """Denotes a validation error during submission."""
820
856
    pass
885
921
    id = Unicode(primary=True, name="identifier")
886
922
    name = Unicode()
887
923
    description = Unicode()
 
924
    _description_xhtml_cache = Unicode(name='description_xhtml_cache')
888
925
    partial = Unicode()
889
926
    solution = Unicode()
890
927
    include = Unicode()
933
970
 
934
971
        return perms
935
972
 
936
 
    def get_description(self):
937
 
        """Return the description interpreted as reStructuredText."""
938
 
        return rst(self.description)
 
973
    def _cache_description_xhtml(self, invalidate=False):
 
974
        # Don't regenerate an existing cache unless forced.
 
975
        if self._description_xhtml_cache is not None and not invalidate:
 
976
            return
 
977
 
 
978
        if self.description:
 
979
            self._description_xhtml_cache = rst(self.description)
 
980
        else:
 
981
            self._description_xhtml_cache = None
 
982
 
 
983
    @property
 
984
    def description_xhtml(self):
 
985
        """The XHTML exercise description, converted from reStructuredText."""
 
986
        self._cache_description_xhtml()
 
987
        return self._description_xhtml_cache
 
988
 
 
989
    def set_description(self, description):
 
990
        self.description = description
 
991
        self._cache_description_xhtml(invalidate=True)
939
992
 
940
993
    def delete(self):
941
994
        """Deletes the exercise, providing it has no associated worksheets."""
958
1011
    identifier = Unicode()
959
1012
    name = Unicode()
960
1013
    assessable = Bool()
 
1014
    published = Bool()
961
1015
    data = Unicode()
 
1016
    _data_xhtml_cache = Unicode(name='data_xhtml_cache')
962
1017
    seq_no = Int()
963
1018
    format = Unicode()
964
1019
 
995
1050
            WorksheetExercise.worksheet == self).remove()
996
1051
 
997
1052
    def get_permissions(self, user, config):
998
 
        # Almost the same permissions as for the offering itself
999
 
        perms = self.offering.get_permissions(user, config)
1000
 
        # However, "edit" permission is derived from the "edit_worksheets"
1001
 
        # permission of the offering
1002
 
        if 'edit_worksheets' in perms:
 
1053
        offering_perms = self.offering.get_permissions(user, config)
 
1054
 
 
1055
        perms = set()
 
1056
 
 
1057
        # Anybody who can view an offering can view a published
 
1058
        # worksheet.
 
1059
        if 'view' in offering_perms and self.published:
 
1060
            perms.add('view')
 
1061
 
 
1062
        # Any worksheet editors can both view and edit.
 
1063
        if 'edit_worksheets' in offering_perms:
 
1064
            perms.add('view')
1003
1065
            perms.add('edit')
1004
 
        else:
1005
 
            perms.discard('edit')
 
1066
 
1006
1067
        return perms
1007
1068
 
1008
 
    def get_xml(self):
1009
 
        """Returns the xml of this worksheet, converts from rst if required."""
1010
 
        if self.format == u'rst':
1011
 
            ws_xml = rst(self.data)
1012
 
            return ws_xml
 
1069
    def _cache_data_xhtml(self, invalidate=False):
 
1070
        # Don't regenerate an existing cache unless forced.
 
1071
        if self._data_xhtml_cache is not None and not invalidate:
 
1072
            return
 
1073
 
 
1074
        if self.format == u'rst':
 
1075
            self._data_xhtml_cache = rst(self.data)
 
1076
        else:
 
1077
            self._data_xhtml_cache = None
 
1078
 
 
1079
    @property
 
1080
    def data_xhtml(self):
 
1081
        """The XHTML of this worksheet, converted from rST if required."""
 
1082
        # Update the rST -> XHTML cache, if required.
 
1083
        self._cache_data_xhtml()
 
1084
 
 
1085
        if self.format == u'rst':
 
1086
            return self._data_xhtml_cache
1013
1087
        else:
1014
1088
            return self.data
1015
1089
 
 
1090
    def set_data(self, data):
 
1091
        self.data = data
 
1092
        self._cache_data_xhtml(invalidate=True)
 
1093
 
1016
1094
    def delete(self):
1017
1095
        """Deletes the worksheet, provided it has no attempts on any exercises.
1018
1096
 
1080
1158
 
1081
1159
    def __repr__(self):
1082
1160
        return "<%s %s by %s at %s>" % (type(self).__name__,
1083
 
            self.exercise.name, self.user.login, self.date.strftime("%c"))
 
1161
            self.worksheet_exercise.exercise.name, self.user.login,
 
1162
            self.date.strftime("%c"))
1084
1163
 
1085
1164
class ExerciseAttempt(ExerciseSave):
1086
1165
    """An attempt at solving an exercise.