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
95
# action=svnpublish: Set the "published" flag on a file to True.
96
# path: The path to the file to be published. Can be specified
99
# action=svnunpublish: Set the "published" flag on a file to False.
100
# path: The path to the file to be unpublished. Can be specified
94
# revision: The revision number to update to. If not provided this
103
97
# action=svncommit: Commit a file(s) or directory(s) to the repository.
104
98
# path: The path to the file or directory to be committed. Can be
142
136
from ivle import (util, studpath, zip)
143
137
from ivle.fileservice_lib.exceptions import WillNotOverwrite
147
def get_login(_realm, existing_login, _may_save):
148
"""Callback function used by pysvn for authentication.
149
realm, existing_login, _may_save: The 3 arguments passed by pysvn to
151
The following has been determined empirically, not from docs:
152
existing_login will be the name of the user who owns the process on
153
the first attempt, "" on subsequent attempts. We use this fact.
155
# Only provide credentials on the _first_ attempt.
156
# If we're being asked again, then it means the credentials failed for
157
# some reason and we should just fail. (This is not desirable, but it's
158
# better than being asked an infinite number of times).
159
return (existing_login != "", str(ivle.conf.login),
160
str(ivle.conf.svn_pass), True)
162
# Make a Subversion client object
163
svnclient = pysvn.Client()
164
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)
165
145
svnclient.exception_style = 0 # Simple (string) exceptions
167
147
DEFAULT_LOGMESSAGE = "No log message supplied."
338
318
frompath = fields.getfirst('from')
339
319
topath = fields.getfirst('to')
340
movefile(req, frompath, topath)
320
svn = fields.getfirst('svn')
322
svn_movefile(req, frompath, topath)
324
movefile(req, frompath, topath)
342
326
def action_mkdir(req, fields):
343
327
"""Creates a directory with the given path.
592
576
Reads fields: 'path' (multiple)
594
578
paths = fields.getlist('path')
595
paths = map(lambda path: actionpath_to_local(req, path), paths)
579
paths = map(lambda path: actionpath_to_local(req, path).decode('utf-8'),
598
583
svnclient.add(paths, recurse=True, force=True)
605
590
Reads fields: 'path' (multiple)
607
592
paths = fields.getlist('path')
608
paths = map(lambda path: actionpath_to_local(req, path), paths)
593
paths = map(lambda path: actionpath_to_local(req, path).decode('utf-8'),
611
597
svnclient.remove(paths, force=True)
615
601
def action_svnupdate(req, fields):
616
602
"""Performs a "svn update" to each file specified.
604
Reads fields: 'path' and 'revision'
620
606
path = fields.getfirst('path')
607
revision = fields.getfirst('revision')
622
609
raise ActionError("Required field missing")
623
path = actionpath_to_local(req, path)
611
revision = pysvn.Revision( pysvn.opt_revision_kind.head )
614
revision = pysvn.Revision(pysvn.opt_revision_kind.number,
616
except ValueError, e:
617
raise ActionError("Bad revision number: '%s'"%revision,)
618
path = actionpath_to_local(req, path).decode('utf-8')
626
svnclient.update(path, recurse=True)
621
svnclient.update(path, recurse=True, revision=revision)
627
622
except pysvn.ClientError, e:
628
623
raise ActionError(str(e))
648
643
Reads fields: 'path' (multiple)
650
645
paths = fields.getlist('path')
651
paths = map(lambda path: actionpath_to_local(req, path), paths)
646
paths = map(lambda path: actionpath_to_local(req, path).decode('utf-8'),
654
650
svnclient.revert(paths, recurse=True)
655
651
except pysvn.ClientError, e:
656
652
raise ActionError(str(e))
658
def action_svnpublish(req, fields):
659
"""Sets svn property "ivle:published" on each file specified.
660
Should only be called on directories (only effective on directories
665
XXX Currently unused by the client (calls action_publish instead, which
666
has a completely different publishing model).
668
paths = fields.getlist('path')
670
paths = map(lambda path: actionpath_to_local(req, path), paths)
672
paths = [studpath.to_home_path(req.path)]
676
# Note: Property value doesn't matter
677
svnclient.propset("ivle:published", "", path, recurse=False)
678
except pysvn.ClientError, e:
679
raise ActionError("Directory could not be published")
681
def action_svnunpublish(req, fields):
682
"""Deletes svn property "ivle:published" on each file specified.
686
XXX Currently unused by the client (calls action_unpublish instead, which
687
has a completely different publishing model).
689
paths = fields.getlist('path')
690
paths = map(lambda path: actionpath_to_local(req, path), paths)
694
svnclient.propdel("ivle:published", path, recurse=False)
695
except pysvn.ClientError, e:
696
raise ActionError("Directory could not be unpublished")
698
654
def action_svncommit(req, fields):
699
655
"""Performs a "svn commit" to each file specified.
701
657
Reads fields: 'path' (multiple), 'logmsg' (optional)
703
659
paths = fields.getlist('path')
704
paths = map(lambda path: actionpath_to_local(req, str(path)), paths)
705
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')
706
667
if logmsg == '': logmsg = DEFAULT_LOGMESSAGE
720
681
raise ActionError("usage: svncheckout url local-path")
721
682
url = ivle.conf.svn_addr + "/" + urllib.quote(paths[0])
722
683
local_path = actionpath_to_local(req, str(paths[1]))
684
url = url.decode('utf-8')
685
local_path = local_path.decode('utf-8')
724
svnclient.callback_get_login = get_login
725
687
svnclient.checkout(url, local_path, recurse=True)
726
688
except pysvn.ClientError, e:
727
689
raise ActionError(str(e))
734
696
path = fields.getfirst('path')
735
697
logmsg = fields.getfirst('logmsg')
736
url = ivle.conf.svn_addr + "/" + path
698
url = (ivle.conf.svn_addr + "/" + urllib.quote(path)).decode('utf-8')
738
svnclient.callback_get_login = get_login
739
700
svnclient.mkdir(url, log_message=logmsg)
740
701
except pysvn.ClientError, e:
741
702
raise ActionError(str(e))
748
709
Reads fields: 'path'
750
711
path = fields.getfirst('path')
751
url = ivle.conf.svn_addr + "/" + path
712
url = (ivle.conf.svn_addr + "/" + urllib.quote(path)).decode('utf-8')
752
713
svnclient.exception_style = 1
755
svnclient.callback_get_login = get_login
756
716
info = svnclient.info2(url,
757
717
revision=pysvn.Revision(pysvn.opt_revision_kind.head))[0][1]
758
718
return {'svnrevision': info['rev'].number
801
762
"svnupdate" : action_svnupdate,
802
763
"svnresolved" : action_svnresolved,
803
764
"svnrevert" : action_svnrevert,
804
"svnpublish" : action_svnpublish,
805
"svnunpublish" : action_svnunpublish,
806
765
"svncommit" : action_svncommit,
807
766
"svncheckout" : action_svncheckout,
808
767
"svnrepomkdir" : action_svnrepomkdir,