91
91
# action=svnupdate: Bring a file up to date with the head revision.
92
92
# path: The path to the file to be updated. Only one file may be
94
# revision: The revision number to update to. If not provided this
97
95
# action=svnpublish: Set the "published" flag on a file to True.
98
96
# path: The path to the file to be published. Can be specified
121
119
# path: The path to the directory to be checked (under the IVLE
122
120
# repository base).
124
# action=svncleanup: Recursively clean up the working copy, removing locks,
125
# resuming unfinished operations, etc.
126
# path: The path to the directory to be cleaned
128
122
# TODO: Implement the following actions:
129
123
# svnupdate (done?)
130
124
# TODO: Implement ZIP unpacking in putfiles (done?).
205
198
# Default, just send an error but then continue
206
199
raise ActionError("Unknown action")
207
return action(req, fields)
209
202
def actionpath_to_urlpath(req, path):
210
203
"""Determines the URL path (relative to the student home) upon which the
236
229
Does not mutate req.
238
r = studpath.to_home_path(actionpath_to_urlpath(req, path))
231
(_, _, r) = studpath.url_to_jailpaths(actionpath_to_urlpath(req, path))
240
233
raise ActionError("Invalid path")
427
420
for datum in data:
428
421
# Each of the uploaded files
429
422
filepath = os.path.join(path, datum.filename)
430
filepath_local = studpath.to_home_path(filepath)
423
(_, _, filepath_local) = studpath.url_to_jailpaths(filepath)
431
424
if os.path.isdir(filepath_local):
432
425
raise ActionError("A directory already exists "
433
426
+ "with that name")
445
438
# First get the entire path (within jail)
446
abspath = studpath.to_home_path(path)
439
_, _, abspath = studpath.url_to_jailpaths(path)
447
440
abspath = os.path.join(os.sep, abspath)
448
441
zip.unzip(abspath, filedata)
449
442
except (OSError, IOError):
452
445
raise ActionError("File '" + e.filename + "' already exists.")
455
filepath_local = studpath.to_home_path(filepath)
448
(_, _, filepath_local) = studpath.url_to_jailpaths(filepath)
456
449
if filepath_local is None:
457
450
raise ActionError("Invalid path")
539
532
Reads fields: 'path'
541
534
paths = fields.getlist('path')
542
user = util.split_path(req.path)[0]
535
user = studpath.url_to_local(req.path)[0]
543
536
homedir = "/home/%s" % user
545
538
paths = map(lambda path: actionpath_to_local(req, path), paths)
547
paths = [studpath.to_home_path(req.path)]
540
paths = [studpath.url_to_jailpaths(req.path)[2]]
549
542
# Set all the dirs in home dir world browsable (o+r,o+x)
550
543
#FIXME: Should really only do those in the direct path not all of the
617
610
def action_svnupdate(req, fields):
618
611
"""Performs a "svn update" to each file specified.
620
Reads fields: 'path' and 'revision'
622
615
path = fields.getfirst('path')
623
revision = fields.getfirst('revision')
625
617
raise ActionError("Required field missing")
627
revision = pysvn.Revision( pysvn.opt_revision_kind.head )
630
revision = pysvn.Revision(pysvn.opt_revision_kind.number,
632
except ValueError, e:
633
raise ActionError("Bad revision number: '%s'"%revision,)
634
618
path = actionpath_to_local(req, path)
637
svnclient.update(path, recurse=True, revision=revision)
621
svnclient.update(path, recurse=True)
638
622
except pysvn.ClientError, e:
639
623
raise ActionError(str(e))
729
713
paths = fields.getlist('path')
730
714
if len(paths) != 2:
731
715
raise ActionError("usage: svncheckout url local-path")
732
url = ivle.conf.svn_addr + "/" + urllib.quote(paths[0])
716
url = ivle.conf.svn_addr + "/" + paths[0]
733
717
local_path = actionpath_to_local(req, str(paths[1]))
735
719
svnclient.callback_get_login = get_login
754
738
def action_svnrepostat(req, fields):
755
739
"""Discovers whether a path exists in a repo under the IVLE SVN root.
757
If it does exist, returns a dict containing its metadata.
759
741
Reads fields: 'path'
761
743
path = fields.getfirst('path')
762
744
url = ivle.conf.svn_addr + "/" + path
763
svnclient.exception_style = 1
745
svnclient.exception_style = 1
766
748
svnclient.callback_get_login = get_login
767
info = svnclient.info2(url,
768
revision=pysvn.Revision(pysvn.opt_revision_kind.head))[0][1]
769
return {'svnrevision': info['rev'].number
771
info['rev'].kind == pysvn.opt_revision_kind.number
773
750
except pysvn.ClientError, e:
774
751
# Error code 170000 means ENOENT in this revision.
775
752
if e[1][0][1] == 170000:
776
753
raise util.IVLEError(404, 'The specified repository path does not exist')
778
755
raise ActionError(str(e[0]))
781
def action_svncleanup(req, fields):
782
"""Recursively clean up the working copy, removing locks, resuming
783
unfinished operations, etc.
784
path: The path to be cleaned"""
786
path = fields.getfirst('path')
788
raise ActionError("Required field missing")
789
path = actionpath_to_local(req, path)
792
svnclient.cleanup(path)
793
except pysvn.ClientError, e:
794
raise ActionError(str(e))
797
758
# Table of all action functions #
798
759
# Each function has the interface f(req, fields).
818
779
"svncheckout" : action_svncheckout,
819
780
"svnrepomkdir" : action_svnrepomkdir,
820
781
"svnrepostat" : action_svnrepostat,
821
"svncleanup" : action_svncleanup,