~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:52:48 UTC
  • mfrom: (1791.2.10 mediahandlers)
  • Revision ID: coles.david@gmail.com-20100728105248-zvbn9g72v1nsskvd
A series of HTML5 based media handlers using the <audio> and <video> tags.  
This replaces the previous page that just showed a download link (which is 
already available on the menu).

Also solves issue where media files were downloaded by the client twice (once 
in an AJAX request intended only for text).

Known issues:
    * Bug #588285: External BHO will not be able to play media due to not
      having IVLE cookie.
    * Bug #610745: Does not correctly preview revisions
    * Bug #610780: Ogg media does not work in Chromium

Show diffs side-by-side

added added

removed removed

Lines of Context:
150
150
            Offering.semester_id == Semester.id,
151
151
            Offering.subject_id == Subject.id).order_by(
152
152
                Desc(Semester.year),
153
 
                Desc(Semester.semester),
 
153
                Desc(Semester.display_name),
154
154
                Desc(Subject.code)
155
155
            )
156
156
 
231
231
        """Find a user in a store by login name."""
232
232
        return store.find(cls, cls.login == unicode(login)).one()
233
233
 
234
 
    def get_svn_url(self, config, req):
 
234
    def get_svn_url(self, config):
235
235
        """Get the subversion repository URL for this user or group."""
236
 
        login = req.user.login
237
 
        url = urlparse.urlsplit(config['urls']['svn_addr'])
238
 
        url = urlparse.urlunsplit(url[:1] + (login+'@'+url[1],) + url[2:])
 
236
        url = config['urls']['svn_addr']
239
237
        path = 'users/%s' % self.login
240
238
        return urlparse.urljoin(url, path)
241
239
 
300
298
        """
301
299
        return self.offerings.find(Offering.semester_id == Semester.id,
302
300
                               Semester.year == unicode(year),
303
 
                               Semester.semester == unicode(semester)).one()
 
301
                               Semester.url_name == unicode(semester)).one()
304
302
 
305
303
class Semester(Storm):
306
304
    """A semester in which subjects can be run."""
309
307
 
310
308
    id = Int(primary=True, name="semesterid")
311
309
    year = Unicode()
312
 
    semester = Unicode()
 
310
    code = Unicode()
 
311
    url_name = Unicode()
 
312
    display_name = Unicode()
313
313
    state = Unicode()
314
314
 
315
315
    offerings = ReferenceSet(id, 'Offering.semester_id')
321
321
    __init__ = _kwarg_init
322
322
 
323
323
    def __repr__(self):
324
 
        return "<%s %s/%s>" % (type(self).__name__, self.year, self.semester)
 
324
        return "<%s %s/%s>" % (type(self).__name__, self.year, self.code)
325
325
 
326
326
class Offering(Storm):
327
327
    """An offering of a subject in a particular semester."""
612
612
        return "<%s '%s' in %r>" % (type(self).__name__, self.short_name,
613
613
                                  self.project_set.offering)
614
614
 
615
 
    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
        """
616
619
        return (self in principal.get_projects() and
617
 
                not self.has_deadline_passed(user))
 
620
                (late or not self.has_deadline_passed(user)))
618
621
 
619
 
    def submit(self, principal, path, revision, who):
 
622
    def submit(self, principal, path, revision, who, late=False):
620
623
        """Submit a Subversion path and revision to a project.
621
624
 
622
625
        @param principal: The owner of the Subversion repository, and the
624
627
        @param path: A path within that repository to submit.
625
628
        @param revision: The revision of that path to submit.
626
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.)
627
632
        """
628
633
 
629
 
        if not self.can_submit(principal, who):
 
634
        if not self.can_submit(principal, who, late=late):
630
635
            raise DeadlinePassed()
631
636
 
632
637
        a = Assessed.get(Store.of(self), principal, self)
735
740
            Semester.id == Offering.semester_id,
736
741
            (not active_only) or (Semester.state == u'current'))
737
742
 
738
 
    def get_svn_url(self, config, req):
 
743
    def get_svn_url(self, config):
739
744
        """Get the subversion repository URL for this user or group."""
740
 
        login = req.user.login
741
 
        url = urlparse.urlsplit(config['urls']['svn_addr'])
742
 
        url = urlparse.urlunsplit(url[:1] + (login+'@'+url[1],) + url[2:])
 
745
        url = config['urls']['svn_addr']
743
746
        path = 'groups/%s_%s_%s_%s' % (
744
747
                self.project_set.offering.subject.short_name,
745
748
                self.project_set.offering.semester.year,
746
 
                self.project_set.offering.semester.semester,
 
749
                self.project_set.offering.semester.url_name,
747
750
                self.name
748
751
                )
749
752
        return urlparse.urljoin(url, path)
864
867
    id = Int(name="extensionid", primary=True)
865
868
    assessed_id = Int(name="assessedid")
866
869
    assessed = Reference(assessed_id, Assessed.id)
867
 
    deadline = DateTime()
 
870
    days = Int()
868
871
    approver_id = Int(name="approver")
869
872
    approver = Reference(approver_id, User.id)
870
873
    notes = Unicode()
912
915
        return "/files/%s/%s/%s?r=%d" % (user.login,
913
916
            self.assessed.checkout_location, submitpath, self.revision)
914
917
 
915
 
    def get_svn_url(self, req):
 
918
    def get_svn_url(self, config):
916
919
        """Get subversion URL for this submission"""
917
920
        princ = self.assessed.principal
918
 
        base = princ.get_svn_url(req.config, req)
 
921
        base = princ.get_svn_url(config)
919
922
        if self.path.startswith(os.sep):
920
923
            return os.path.join(base,
921
924
                    urllib.quote(self.path[1:].encode('utf-8')))
922
925
        else:
923
926
            return os.path.join(base, urllib.quote(self.path.encode('utf-8')))
924
927
 
925
 
    def get_svn_checkout_command(self, req):
926
 
        svn_url = self.get_svn_url(req)
927
 
        return "svn export -r%d '%s'"%(self.revision, svn_url)
 
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)
928
940
 
929
941
    @staticmethod
930
942
    def test_and_normalise_path(path):
945
957
            raise SubmissionError("Path must not contain '\\n', '[' or ']'")
946
958
        return os.path.normpath(path)
947
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
 
948
973
# WORKSHEETS AND EXERCISES #
949
974
 
950
975
class Exercise(Storm):