diff options
author | cinap_lenrek <cinap_lenrek@localhost> | 2011-05-03 11:25:13 +0000 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@localhost> | 2011-05-03 11:25:13 +0000 |
commit | 458120dd40db6b4df55a4e96b650e16798ef06a0 (patch) | |
tree | 8f82685be24fef97e715c6f5ca4c68d34d5074ee /sys/lib/python/mercurial/statichttprepo.py | |
parent | 3a742c699f6806c1145aea5149bf15de15a0afd7 (diff) |
add hg and python
Diffstat (limited to 'sys/lib/python/mercurial/statichttprepo.py')
-rw-r--r-- | sys/lib/python/mercurial/statichttprepo.py | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/sys/lib/python/mercurial/statichttprepo.py b/sys/lib/python/mercurial/statichttprepo.py new file mode 100644 index 000000000..0913d2fbb --- /dev/null +++ b/sys/lib/python/mercurial/statichttprepo.py @@ -0,0 +1,134 @@ +# statichttprepo.py - simple http repository class for mercurial +# +# This provides read-only repo access to repositories exported via static http +# +# Copyright 2005-2007 Matt Mackall <mpm@selenic.com> +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2, incorporated herein by reference. + +from i18n import _ +import changelog, byterange, url, error +import localrepo, manifest, util, store +import urllib, urllib2, errno + +class httprangereader(object): + def __init__(self, url, opener): + # we assume opener has HTTPRangeHandler + self.url = url + self.pos = 0 + self.opener = opener + def seek(self, pos): + self.pos = pos + def read(self, bytes=None): + req = urllib2.Request(self.url) + end = '' + if bytes: + end = self.pos + bytes - 1 + req.add_header('Range', 'bytes=%d-%s' % (self.pos, end)) + + try: + f = self.opener.open(req) + data = f.read() + if hasattr(f, 'getcode'): + # python 2.6+ + code = f.getcode() + elif hasattr(f, 'code'): + # undocumented attribute, seems to be set in 2.4 and 2.5 + code = f.code + else: + # Don't know how to check, hope for the best. + code = 206 + except urllib2.HTTPError, inst: + num = inst.code == 404 and errno.ENOENT or None + raise IOError(num, inst) + except urllib2.URLError, inst: + raise IOError(None, inst.reason[1]) + + if code == 200: + # HTTPRangeHandler does nothing if remote does not support + # Range headers and returns the full entity. Let's slice it. + if bytes: + data = data[self.pos:self.pos + bytes] + else: + data = data[self.pos:] + elif bytes: + data = data[:bytes] + self.pos += len(data) + return data + +def build_opener(ui, authinfo): + # urllib cannot handle URLs with embedded user or passwd + urlopener = url.opener(ui, authinfo) + urlopener.add_handler(byterange.HTTPRangeHandler()) + + def opener(base): + """return a function that opens files over http""" + p = base + def o(path, mode="r"): + f = "/".join((p, urllib.quote(path))) + return httprangereader(f, urlopener) + return o + + return opener + +class statichttprepository(localrepo.localrepository): + def __init__(self, ui, path): + self._url = path + self.ui = ui + + self.path, authinfo = url.getauthinfo(path.rstrip('/') + "/.hg") + + opener = build_opener(ui, authinfo) + self.opener = opener(self.path) + + # find requirements + try: + requirements = self.opener("requires").read().splitlines() + except IOError, inst: + if inst.errno != errno.ENOENT: + raise + # check if it is a non-empty old-style repository + try: + self.opener("00changelog.i").read(1) + except IOError, inst: + if inst.errno != errno.ENOENT: + raise + # we do not care about empty old-style repositories here + msg = _("'%s' does not appear to be an hg repository") % path + raise error.RepoError(msg) + requirements = [] + + # check them + for r in requirements: + if r not in self.supported: + raise error.RepoError(_("requirement '%s' not supported") % r) + + # setup store + def pjoin(a, b): + return a + '/' + b + self.store = store.store(requirements, self.path, opener, pjoin) + self.spath = self.store.path + self.sopener = self.store.opener + self.sjoin = self.store.join + + self.manifest = manifest.manifest(self.sopener) + self.changelog = changelog.changelog(self.sopener) + self._tags = None + self.nodetagscache = None + self.encodepats = None + self.decodepats = None + + def url(self): + return self._url + + def local(self): + return False + + def lock(self, wait=True): + raise util.Abort(_('cannot lock static-http repository')) + +def instance(ui, path, create): + if create: + raise util.Abort(_('cannot create new static-http repository')) + return statichttprepository(ui, path[7:]) |