#!/usr/bin/python
# Filename:      hg-mirror
# Purpose:       create a full mirror over hgwebdir
# Authors:       grml-team (grml.org), (c) Michael Gebetsroither <gebi@grml.org>
# Bug-Reports:   see http://grml.org/bugs/
# License:       This file is licensed under the GPL v2.
# Latest change: Mit Feb 21 13:50:04 CET 2007 [mika]
################################################################################

import os
import sys
import optparse
import re

from hgutil.hg.util import walkreposWeb
from hgutil.hg.simple import syncRepos
from hgutil.exception import CmdException
from hgutil.util import DirChanger


def syncRepositories(source, ignore, strip, tryflag=False):
    imatch = re.compile(ignore)
    smatch = re.compile("^" + strip.strip("/") + "/.*")
    repen = []
    try:
        walkreposWeb(repen, source)
    except IOError, e:
        print e
        print 'Error: Could not receive repository listing'
        sys.exit(1)

    repen = filter(lambda x: not smatch.match(x), repen)
    srepen = map(lambda x: smatch.sub("", x), repen)
    error = True
    for i,j in zip(repen, srepen):
        if not i.find('/../') == -1:
            print 'Error: unallowed escaption ../ in path:', i
            continue
        if imatch.search(j) != None:
            continue
        url = source + '/' + i
        repos = j.strip('/')
        tmp = repos.rsplit('/', 1)
        dir = DirChanger()
        if len(tmp) == 2:
            if not tryflag:
                dir.up(tmp[0], create=True)
            repos = tmp[1]
        try:
            def notifier(url):
                print "Info: added", url
            try:
                if tryflag:
                    notifier(url)
                else:
                    syncRepos(url, repos, notifier)
            except CmdException, e:
                print 'Error:', e
                error = False
        finally:
            dir.down()
    return error

if __name__ == '__main__':
    parser = optparse.OptionParser(usage="usage: %prog [options] <source>")
    parser.add_option("-i", "--ignore", dest="ignore", default="""(?!)""", metavar="regexp",
            help="Filter list of repository names")
    parser.add_option("-s", "--strip", dest="strip", default="""(?!)""", metavar="regexp",
            help="Strip prefix from repos path")
    parser.add_option("--try", action="store_true", dest="tryflag", default=False,
            help="Do not sync repositories, only print what would be done")
    (opts, args) = parser.parse_args()
    source = args[0]
    ret = syncRepositories(source, ignore=opts.ignore, strip=opts.strip, tryflag=opts.tryflag)
    if not ret:
        sys.exit(1)

# vim: foldmethod=marker
