231
231
"""Find a user in a store by login name."""
232
232
return store.find(cls, cls.login == unicode(login)).one()
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)
612
610
return "<%s '%s' in %r>" % (type(self).__name__, self.short_name,
613
611
self.project_set.offering)
615
def can_submit(self, principal, user):
613
def can_submit(self, principal, user, late=False):
615
@param late: If True, does not take the deadline into account.
616
617
return (self in principal.get_projects() and
617
not self.has_deadline_passed(user))
618
(late or not self.has_deadline_passed(user)))
619
def submit(self, principal, path, revision, who):
620
def submit(self, principal, path, revision, who, late=False):
620
621
"""Submit a Subversion path and revision to a project.
622
623
@param principal: The owner of the Subversion repository, and the
624
625
@param path: A path within that repository to submit.
625
626
@param revision: The revision of that path to submit.
626
627
@param who: The user who is actually making the submission.
628
@param late: If True, will not raise a DeadlinePassed exception even
629
after the deadline. (Default False.)
629
if not self.can_submit(principal, who):
632
if not self.can_submit(principal, who, late=late):
630
633
raise DeadlinePassed()
632
635
a = Assessed.get(Store.of(self), principal, self)
735
738
Semester.id == Offering.semester_id,
736
739
(not active_only) or (Semester.state == u'current'))
738
def get_svn_url(self, config, req):
741
def get_svn_url(self, config):
739
742
"""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:])
743
url = config['urls']['svn_addr']
743
744
path = 'groups/%s_%s_%s_%s' % (
744
745
self.project_set.offering.subject.short_name,
745
746
self.project_set.offering.semester.year,
864
865
id = Int(name="extensionid", primary=True)
865
866
assessed_id = Int(name="assessedid")
866
867
assessed = Reference(assessed_id, Assessed.id)
867
deadline = DateTime()
868
869
approver_id = Int(name="approver")
869
870
approver = Reference(approver_id, User.id)
870
871
notes = Unicode()
912
913
return "/files/%s/%s/%s?r=%d" % (user.login,
913
914
self.assessed.checkout_location, submitpath, self.revision)
915
def get_svn_url(self, req):
916
def get_svn_url(self, config):
916
917
"""Get subversion URL for this submission"""
917
918
princ = self.assessed.principal
918
base = princ.get_svn_url(req.config, req)
919
base = princ.get_svn_url(config)
919
920
if self.path.startswith(os.sep):
920
921
return os.path.join(base,
921
922
urllib.quote(self.path[1:].encode('utf-8')))
923
924
return os.path.join(base, urllib.quote(self.path.encode('utf-8')))
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)
926
def get_svn_export_command(self, req):
927
"""Returns a Unix shell command to export a submission"""
928
svn_url = self.get_svn_url(req.config)
929
username = (req.user.login if req.user.login.isalnum() else
930
"'%s'"%req.user.login)
931
export_dir = self.assessed.principal.short_name
932
return "svn export --username %s -r%d '%s' %s"%(req.user.login,
933
self.revision, svn_url, export_dir)
930
936
def test_and_normalise_path(path):
945
951
raise SubmissionError("Path must not contain '\\n', '[' or ']'")
946
952
return os.path.normpath(path)
956
"""True if the project was submitted late."""
957
return self.days_late > 0
961
"""The number of days the project was submitted late (rounded up), or
963
# XXX: Need to respect extensions.
965
(self.date_submitted - self.assessed.project.deadline).days + 1)
948
967
# WORKSHEETS AND EXERCISES #
950
969
class Exercise(Storm):