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
95
97
# action=svnpublish: Set the "published" flag on a file to True.
96
98
# path: The path to the file to be published. Can be specified
119
121
# path: The path to the directory to be checked (under the IVLE
120
122
# 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
122
128
# TODO: Implement the following actions:
123
129
# svnupdate (done?)
124
130
# TODO: Implement ZIP unpacking in putfiles (done?).
138
144
from ivle import (util, studpath, zip)
139
145
from ivle.fileservice_lib.exceptions import WillNotOverwrite
143
def get_login(_realm, existing_login, _may_save):
144
"""Callback function used by pysvn for authentication.
145
realm, existing_login, _may_save: The 3 arguments passed by pysvn to
147
The following has been determined empirically, not from docs:
148
existing_login will be the name of the user who owns the process on
149
the first attempt, "" on subsequent attempts. We use this fact.
151
# Only provide credentials on the _first_ attempt.
152
# If we're being asked again, then it means the credentials failed for
153
# some reason and we should just fail. (This is not desirable, but it's
154
# better than being asked an infinite number of times).
155
return (existing_login != "", str(ivle.conf.login),
156
str(ivle.conf.svn_pass), True)
158
# Make a Subversion client object
159
svnclient = pysvn.Client()
160
svnclient.callback_get_login = get_login
149
# Make a Subversion client object (which will log in with this user's
150
# credentials, upon request)
151
svnclient = ivle.svn.create_auth_svn_client(username=ivle.conf.login,
152
password=ivle.conf.svn_pass)
161
153
svnclient.exception_style = 0 # Simple (string) exceptions
163
155
DEFAULT_LOGMESSAGE = "No log message supplied."
611
603
def action_svnupdate(req, fields):
612
604
"""Performs a "svn update" to each file specified.
606
Reads fields: 'path' and 'revision'
616
608
path = fields.getfirst('path')
609
revision = fields.getfirst('revision')
618
611
raise ActionError("Required field missing")
613
revision = pysvn.Revision( pysvn.opt_revision_kind.head )
616
revision = pysvn.Revision(pysvn.opt_revision_kind.number,
618
except ValueError, e:
619
raise ActionError("Bad revision number: '%s'"%revision,)
619
620
path = actionpath_to_local(req, path)
622
svnclient.update(path, recurse=True)
623
svnclient.update(path, recurse=True, revision=revision)
623
624
except pysvn.ClientError, e:
624
625
raise ActionError(str(e))
717
718
url = ivle.conf.svn_addr + "/" + urllib.quote(paths[0])
718
719
local_path = actionpath_to_local(req, str(paths[1]))
720
svnclient.callback_get_login = get_login
721
721
svnclient.checkout(url, local_path, recurse=True)
722
722
except pysvn.ClientError, e:
723
723
raise ActionError(str(e))
730
730
path = fields.getfirst('path')
731
731
logmsg = fields.getfirst('logmsg')
732
url = ivle.conf.svn_addr + "/" + path
732
url = ivle.conf.svn_addr + "/" + urllib.quote(path)
734
svnclient.callback_get_login = get_login
735
734
svnclient.mkdir(url, log_message=logmsg)
736
735
except pysvn.ClientError, e:
737
736
raise ActionError(str(e))
744
743
Reads fields: 'path'
746
745
path = fields.getfirst('path')
747
url = ivle.conf.svn_addr + "/" + path
746
url = ivle.conf.svn_addr + "/" + urllib.quote(path)
748
747
svnclient.exception_style = 1
751
svnclient.callback_get_login = get_login
752
750
info = svnclient.info2(url,
753
751
revision=pysvn.Revision(pysvn.opt_revision_kind.head))[0][1]
754
752
return {'svnrevision': info['rev'].number
761
759
raise util.IVLEError(404, 'The specified repository path does not exist')
763
761
raise ActionError(str(e[0]))
764
def action_svncleanup(req, fields):
765
"""Recursively clean up the working copy, removing locks, resuming
766
unfinished operations, etc.
767
path: The path to be cleaned"""
769
path = fields.getfirst('path')
771
raise ActionError("Required field missing")
772
path = actionpath_to_local(req, path)
775
svnclient.cleanup(path)
776
except pysvn.ClientError, e:
777
raise ActionError(str(e))
766
780
# Table of all action functions #
767
781
# Each function has the interface f(req, fields).
787
801
"svncheckout" : action_svncheckout,
788
802
"svnrepomkdir" : action_svnrepomkdir,
789
803
"svnrepostat" : action_svnrepostat,
804
"svncleanup" : action_svncleanup,