94
94
# revision: The revision number to update to. If not provided this
95
95
# defaults to HEAD.
97
# action=svnpublish: Set the "published" flag on a file to True.
98
# path: The path to the file to be published. Can be specified
101
# action=svnunpublish: Set the "published" flag on a file to False.
102
# path: The path to the file to be unpublished. Can be specified
105
97
# action=svncommit: Commit a file(s) or directory(s) to the repository.
106
98
# path: The path to the file or directory to be committed. Can be
107
99
# specified multiple times. Directories are committed
144
136
from ivle import (util, studpath, zip)
145
137
from ivle.fileservice_lib.exceptions import WillNotOverwrite
149
def get_login(_realm, existing_login, _may_save):
150
"""Callback function used by pysvn for authentication.
151
realm, existing_login, _may_save: The 3 arguments passed by pysvn to
153
The following has been determined empirically, not from docs:
154
existing_login will be the name of the user who owns the process on
155
the first attempt, "" on subsequent attempts. We use this fact.
157
# Only provide credentials on the _first_ attempt.
158
# If we're being asked again, then it means the credentials failed for
159
# some reason and we should just fail. (This is not desirable, but it's
160
# better than being asked an infinite number of times).
161
return (existing_login != "", str(ivle.conf.login),
162
str(ivle.conf.svn_pass), True)
164
# Make a Subversion client object
165
svnclient = pysvn.Client()
166
svnclient.callback_get_login = get_login
141
# Make a Subversion client object (which will log in with this user's
142
# credentials, upon request)
143
svnclient = ivle.svn.create_auth_svn_client(username=ivle.conf.login,
144
password=ivle.conf.svn_pass)
167
145
svnclient.exception_style = 0 # Simple (string) exceptions
169
147
DEFAULT_LOGMESSAGE = "No log message supplied."
340
318
frompath = fields.getfirst('from')
341
319
topath = fields.getfirst('to')
342
movefile(req, frompath, topath)
320
svn = fields.getfirst('svn')
322
svn_movefile(req, frompath, topath)
324
movefile(req, frompath, topath)
344
326
def action_mkdir(req, fields):
345
327
"""Creates a directory with the given path.
594
576
Reads fields: 'path' (multiple)
596
578
paths = fields.getlist('path')
597
paths = map(lambda path: actionpath_to_local(req, path), paths)
579
paths = map(lambda path: actionpath_to_local(req, path).decode('utf-8'),
600
583
svnclient.add(paths, recurse=True, force=True)
607
590
Reads fields: 'path' (multiple)
609
592
paths = fields.getlist('path')
610
paths = map(lambda path: actionpath_to_local(req, path), paths)
593
paths = map(lambda path: actionpath_to_local(req, path).decode('utf-8'),
613
597
svnclient.remove(paths, force=True)
659
643
Reads fields: 'path' (multiple)
661
645
paths = fields.getlist('path')
662
paths = map(lambda path: actionpath_to_local(req, path), paths)
646
paths = map(lambda path: actionpath_to_local(req, path).decode('utf-8'),
665
650
svnclient.revert(paths, recurse=True)
666
651
except pysvn.ClientError, e:
667
652
raise ActionError(str(e))
669
def action_svnpublish(req, fields):
670
"""Sets svn property "ivle:published" on each file specified.
671
Should only be called on directories (only effective on directories
676
XXX Currently unused by the client (calls action_publish instead, which
677
has a completely different publishing model).
679
paths = fields.getlist('path')
681
paths = map(lambda path: actionpath_to_local(req, path), paths)
683
paths = [studpath.to_home_path(req.path)]
687
# Note: Property value doesn't matter
688
svnclient.propset("ivle:published", "", path, recurse=False)
689
except pysvn.ClientError, e:
690
raise ActionError("Directory could not be published")
692
def action_svnunpublish(req, fields):
693
"""Deletes svn property "ivle:published" on each file specified.
697
XXX Currently unused by the client (calls action_unpublish instead, which
698
has a completely different publishing model).
700
paths = fields.getlist('path')
701
paths = map(lambda path: actionpath_to_local(req, path), paths)
705
svnclient.propdel("ivle:published", path, recurse=False)
706
except pysvn.ClientError, e:
707
raise ActionError("Directory could not be unpublished")
709
654
def action_svncommit(req, fields):
710
655
"""Performs a "svn commit" to each file specified.
712
657
Reads fields: 'path' (multiple), 'logmsg' (optional)
714
659
paths = fields.getlist('path')
715
paths = map(lambda path: actionpath_to_local(req, str(path)), paths)
716
logmsg = str(fields.getfirst('logmsg', DEFAULT_LOGMESSAGE))
661
paths = map(lambda path:actionpath_to_local(req,path).decode('utf-8'),
664
paths = [studpath.to_home_path(req.path).decode('utf-8')]
665
logmsg = str(fields.getfirst('logmsg',
666
DEFAULT_LOGMESSAGE)).decode('utf-8')
717
667
if logmsg == '': logmsg = DEFAULT_LOGMESSAGE
731
681
raise ActionError("usage: svncheckout url local-path")
732
682
url = ivle.conf.svn_addr + "/" + urllib.quote(paths[0])
733
683
local_path = actionpath_to_local(req, str(paths[1]))
684
url = url.decode('utf-8')
685
local_path = local_path.decode('utf-8')
735
svnclient.callback_get_login = get_login
736
687
svnclient.checkout(url, local_path, recurse=True)
737
688
except pysvn.ClientError, e:
738
689
raise ActionError(str(e))
745
696
path = fields.getfirst('path')
746
697
logmsg = fields.getfirst('logmsg')
747
url = ivle.conf.svn_addr + "/" + path
698
url = (ivle.conf.svn_addr + "/" + urllib.quote(path)).decode('utf-8')
749
svnclient.callback_get_login = get_login
750
700
svnclient.mkdir(url, log_message=logmsg)
751
701
except pysvn.ClientError, e:
752
702
raise ActionError(str(e))
759
709
Reads fields: 'path'
761
711
path = fields.getfirst('path')
762
url = ivle.conf.svn_addr + "/" + path
712
url = (ivle.conf.svn_addr + "/" + urllib.quote(path)).decode('utf-8')
763
713
svnclient.exception_style = 1
766
svnclient.callback_get_login = get_login
767
716
info = svnclient.info2(url,
768
717
revision=pysvn.Revision(pysvn.opt_revision_kind.head))[0][1]
769
718
return {'svnrevision': info['rev'].number
812
762
"svnupdate" : action_svnupdate,
813
763
"svnresolved" : action_svnresolved,
814
764
"svnrevert" : action_svnrevert,
815
"svnpublish" : action_svnpublish,
816
"svnunpublish" : action_svnunpublish,
817
765
"svncommit" : action_svncommit,
818
766
"svncheckout" : action_svncheckout,
819
767
"svnrepomkdir" : action_svnrepomkdir,