(Arne Babenhauserheide)
2012-06-24: rename site.py to staticsite.py to avoid import conflicts with the rename site.py to staticsite.py to avoid import conflicts with the python site module. Also add FTP push support.
diff --git a/site.py b/staticsite.py rename from site.py rename to staticsite.py --- a/site.py +++ b/staticsite.py @@ -28,7 +28,7 @@ import datetime from mercurial import cmdutil, util, scmutil from mercurial import commands, dispatch from mercurial.i18n import _ -from mercurial import hg, discovery +from mercurial import hg, discovery, util, extensions _staticidentifier = ".statichgrepo" @@ -563,8 +563,13 @@ def addrepo(ui, repo, target, bookmarks) def upload(ui, repo, target, ftpstring, force): """upload the repo to the FTP server identified by the ftp string.""" - user, password = ftpstring.split("@")[0].split(":") - serverandpath = "@".join(ftpstring.split("@")[1:]) + try: + user, password = ftpstring.split("@")[0].split(":") + serverandpath = "@".join(ftpstring.split("@")[1:]) + except ValueError: + ui.warn(_("FTP-upload: No @ in FTP-Url. We try anonymous access.\n")) + user, password = "anonymous", "" + serverandpath = ftpstring # no @, so we just take the whole string server = serverandpath.split("/")[0] ftppath = "/".join(serverandpath.split("/")[1:]) timeout = 10 @@ -671,8 +676,8 @@ def staticsite(ui, repo, target=None, ** # add the hg repo to the static site # currently we need to either include all bookmarks or not, because we don’t have the remote repo when parsing the site. # TODO: I don’t know if that is the correct way to go. Maybe always push all. - bookmarks = opts["bookmarks"] - addrepo(ui, repo, target, bookmarks) + bookmark = opts["bookmark"] + addrepo(ui, repo, target, bookmark) # first: just create the site. parsesite(ui, repo, target, **opts) if opts["upload"]: @@ -691,6 +696,119 @@ cmdtable = { ('f', 'force', False, 'force recreating all commit files. Slow.'), ('s', 'screenstyle', "", 'use a custom stylesheet for display on screen'), ('p', 'printstyle', "", 'use a custom stylesheet for printing'), - ('B', 'bookmarks', False, 'include the bookmarks')], + ('B', 'bookmark', False, 'include the bookmarks')], "[options] [folder]") } + +## add ftp as scheme to be handled by this plugin. + +wrapcmds = { # cmd: generic, target, fixdoc, ppopts, opts + 'push': (False, None, False, False, [ + ('', 'staticsite', None, 'show parent svn revision instead'), + ]) +} + +## Explicitely wrap functions to change local commands in case the remote repo is an FTP repo. See mercurial.extensions for more information. +# Get the module which holds the functions to wrap +#from mercurial import discovery +# the new function: gets the original function as first argument and the originals args and kwds. +#def findcommonoutgoing(orig, *args, **opts): +# capable = getattr(args[1], 'capable', lambda x: False) +# if capable('ftp'): +# return []#orig(*args, **opts) +# else: +# return orig(*args, **opts) +# really wrap the function +#extensions.wrapfunction(discovery, 'findcommonoutgoing', findcommonoutgoing) + +# explicitely wrap commands in case the remote repo is an FTP repo. +def ftppush(orig, *args, **opts): + print args, opts + ui, repo, path = args + # only act differently, if the target is an FTP repo. + if not path.startswith("ftp"): + return orig(*args, **opts) + # first create the site at ._site + target = "._site" + ftpstring = path.replace("ftp://", "") + if not "name" in opts: + opts["name"] = None + opts["screenstyle"] = "" + opts["printstyle"] = "" + opts["upload"] = ftpstring + opts["force"] = False + staticsite(ui, repo, target, **opts) + +# really wrap the command +entry = extensions.wrapcommand(commands.table, "push", ftppush) + +# Starting an FTP repo. Not yet used, except for throwing errors for missing commands and faking the lock. + +from mercurial import repo, util +try: + from mercurial.error import RepoError +except ImportError: + from mercurial.repo import RepoError + +class FTPRepository(repo.repository): + def __init__(self, ui, path, create): + self.create = create + self.ui = ui + self.path = path + self.capabilities = set(["ftp"]) + + def lock(self): + """We cannot really lock FTP repos, yet. + + TODO: Implement as locking the repo in the static site folder.""" + class DummyLock: + def release(self): + pass + l = DummyLock() + return l + + def url(self): + return self.path + + def lookup(self, key): + return key + + def cancopy(self): + return False + + def heads(self, *args, **opts): + """ + Whenever this function is hit, we abort. The traceback is useful for + figuring out where to intercept the functionality. + """ + raise util.Abort('command heads unavailable for FTP repositories') + + def pushkey(self, namespace, key, old, new): + return False + + def listkeys(self, namespace): + return {} + + def push(self, remote, force=False, revs=None, newbranch=None): + raise util.Abort('command push unavailable for FTP repositories') + + def pull(self, remote, heads=[], force=False): + raise util.Abort('command pull unavailable for FTP repositories') + + def findoutgoing(self, remote, base=None, heads=None, force=False): + raise util.Abort('command findoutgoing unavailable for FTP repositories') + + +class RepoContainer(object): + def __init__(self): + pass + + def __repr__(self): + return '<FTPRepository>' + + def instance(self, ui, url, create): + # Should this use urlmod.url(), or is manual parsing better? + #context = {} + return FTPRepository(ui, url, create) + +hg.schemes["ftp"] = RepoContainer()