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

« back to all changes in this revision

Viewing changes to ivle/database.py

  • Committer: David Coles
  • Date: 2010-07-28 10:45:53 UTC
  • mfrom: (1829 trunk)
  • mto: This revision was merged to the branch mainline in revision 1830.
  • Revision ID: coles.david@gmail.com-20100728104553-5z3nxt0l6kyfqfh5
MergeĀ fromĀ trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
import datetime
28
28
import os
29
29
import urlparse
 
30
import urllib
30
31
 
31
32
from storm.locals import create_database, Store, Int, Unicode, DateTime, \
32
33
                         Reference, ReferenceSet, Bool, Storm, Desc
149
150
            Offering.semester_id == Semester.id,
150
151
            Offering.subject_id == Subject.id).order_by(
151
152
                Desc(Semester.year),
152
 
                Desc(Semester.semester),
 
153
                Desc(Semester.display_name),
153
154
                Desc(Subject.code)
154
155
            )
155
156
 
230
231
        """Find a user in a store by login name."""
231
232
        return store.find(cls, cls.login == unicode(login)).one()
232
233
 
233
 
    def get_svn_url(self, config, req):
 
234
    def get_svn_url(self, config):
234
235
        """Get the subversion repository URL for this user or group."""
235
 
        login = req.user.login
236
 
        url = urlparse.urlsplit(config['urls']['svn_addr'])
237
 
        url = urlparse.urlunsplit(url[:1] + (login+'@'+url[1],) + url[2:])
 
236
        url = config['urls']['svn_addr']
238
237
        path = 'users/%s' % self.login
239
238
        return urlparse.urljoin(url, path)
240
239
 
299
298
        """
300
299
        return self.offerings.find(Offering.semester_id == Semester.id,
301
300
                               Semester.year == unicode(year),
302
 
                               Semester.semester == unicode(semester)).one()
 
301
                               Semester.url_name == unicode(semester)).one()
303
302
 
304
303
class Semester(Storm):
305
304
    """A semester in which subjects can be run."""
308
307
 
309
308
    id = Int(primary=True, name="semesterid")
310
309
    year = Unicode()
311
 
    semester = Unicode()
 
310
    code = Unicode()
 
311
    url_name = Unicode()
 
312
    display_name = Unicode()
312
313
    state = Unicode()
313
314
 
314
315
    offerings = ReferenceSet(id, 'Offering.semester_id')
320
321
    __init__ = _kwarg_init
321
322
 
322
323
    def __repr__(self):
323
 
        return "<%s %s/%s>" % (type(self).__name__, self.year, self.semester)
 
324
        return "<%s %s/%s>" % (type(self).__name__, self.year, self.code)
324
325
 
325
326
class Offering(Storm):
326
327
    """An offering of a subject in a particular semester."""
611
612
        return "<%s '%s' in %r>" % (type(self).__name__, self.short_name,
612
613
                                  self.project_set.offering)
613
614
 
614
 
    def can_submit(self, principal, user):
 
615
    def can_submit(self, principal, user, late=False):
 
616
        """
 
617
        @param late: If True, does not take the deadline into account.
 
618
        """
615
619
        return (self in principal.get_projects() and
616
 
                not self.has_deadline_passed(user))
 
620
                (late or not self.has_deadline_passed(user)))
617
621
 
618
 
    def submit(self, principal, path, revision, who):
 
622
    def submit(self, principal, path, revision, who, late=False):
619
623
        """Submit a Subversion path and revision to a project.
620
624
 
621
625
        @param principal: The owner of the Subversion repository, and the
623
627
        @param path: A path within that repository to submit.
624
628
        @param revision: The revision of that path to submit.
625
629
        @param who: The user who is actually making the submission.
 
630
        @param late: If True, will not raise a DeadlinePassed exception even
 
631
            after the deadline. (Default False.)
626
632
        """
627
633
 
628
 
        if not self.can_submit(principal, who):
 
634
        if not self.can_submit(principal, who, late=late):
629
635
            raise DeadlinePassed()
630
636
 
631
637
        a = Assessed.get(Store.of(self), principal, self)
734
740
            Semester.id == Offering.semester_id,
735
741
            (not active_only) or (Semester.state == u'current'))
736
742
 
737
 
    def get_svn_url(self, config, req):
 
743
    def get_svn_url(self, config):
738
744
        """Get the subversion repository URL for this user or group."""
739
 
        login = req.user.login
740
 
        url = urlparse.urlsplit(config['urls']['svn_addr'])
741
 
        url = urlparse.urlunsplit(url[:1] + (login+'@'+url[1],) + url[2:])
 
745
        url = config['urls']['svn_addr']
742
746
        path = 'groups/%s_%s_%s_%s' % (
743
747
                self.project_set.offering.subject.short_name,
744
748
                self.project_set.offering.semester.year,
745
 
                self.project_set.offering.semester.semester,
 
749
                self.project_set.offering.semester.url_name,
746
750
                self.name
747
751
                )
748
752
        return urlparse.urljoin(url, path)
863
867
    id = Int(name="extensionid", primary=True)
864
868
    assessed_id = Int(name="assessedid")
865
869
    assessed = Reference(assessed_id, Assessed.id)
866
 
    deadline = DateTime()
 
870
    days = Int()
867
871
    approver_id = Int(name="approver")
868
872
    approver = Reference(approver_id, User.id)
869
873
    notes = Unicode()
911
915
        return "/files/%s/%s/%s?r=%d" % (user.login,
912
916
            self.assessed.checkout_location, submitpath, self.revision)
913
917
 
 
918
    def get_svn_url(self, config):
 
919
        """Get subversion URL for this submission"""
 
920
        princ = self.assessed.principal
 
921
        base = princ.get_svn_url(config)
 
922
        if self.path.startswith(os.sep):
 
923
            return os.path.join(base,
 
924
                    urllib.quote(self.path[1:].encode('utf-8')))
 
925
        else:
 
926
            return os.path.join(base, urllib.quote(self.path.encode('utf-8')))
 
927
 
 
928
    def get_svn_export_command(self, req):
 
929
        """Returns a Unix shell command to export a submission"""
 
930
        svn_url = self.get_svn_url(req.config)
 
931
        _, ext = os.path.splitext(svn_url)
 
932
        username = (req.user.login if req.user.login.isalnum() else
 
933
                "'%s'"%req.user.login)
 
934
        # Export to a file or directory relative to the current directory,
 
935
        # with the student's login name, appended with the submitted file's
 
936
        # extension, if any
 
937
        export_path = self.assessed.principal.short_name + ext
 
938
        return "svn export --username %s -r%d '%s' %s"%(req.user.login,
 
939
                self.revision, svn_url, export_path)
 
940
 
914
941
    @staticmethod
915
942
    def test_and_normalise_path(path):
916
943
        """Test that path is valid, and normalise it. This prevents possible
930
957
            raise SubmissionError("Path must not contain '\\n', '[' or ']'")
931
958
        return os.path.normpath(path)
932
959
 
 
960
    @property
 
961
    def late(self):
 
962
        """True if the project was submitted late."""
 
963
        return self.days_late > 0
 
964
 
 
965
    @property
 
966
    def days_late(self):
 
967
        """The number of days the project was submitted late (rounded up), or
 
968
        0 if on-time."""
 
969
        # XXX: Need to respect extensions.
 
970
        return max(0,
 
971
            (self.date_submitted - self.assessed.project.deadline).days + 1)
 
972
 
933
973
# WORKSHEETS AND EXERCISES #
934
974
 
935
975
class Exercise(Storm):