##// END OF EJS Templates
statichttprepo: use in-place difference for shorter line
Martin Geisler -
r14519:28682c7e default
parent child Browse files
Show More
@@ -1,141 +1,141 b''
1 # statichttprepo.py - simple http repository class for mercurial
1 # statichttprepo.py - simple http repository class for mercurial
2 #
2 #
3 # This provides read-only repo access to repositories exported via static http
3 # This provides read-only repo access to repositories exported via static http
4 #
4 #
5 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
5 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
6 #
6 #
7 # This software may be used and distributed according to the terms of the
7 # This software may be used and distributed according to the terms of the
8 # GNU General Public License version 2 or any later version.
8 # GNU General Public License version 2 or any later version.
9
9
10 from i18n import _
10 from i18n import _
11 import changelog, byterange, url, error
11 import changelog, byterange, url, error
12 import localrepo, manifest, util, scmutil, store
12 import localrepo, manifest, util, scmutil, store
13 import urllib, urllib2, errno
13 import urllib, urllib2, errno
14
14
15 class httprangereader(object):
15 class httprangereader(object):
16 def __init__(self, url, opener):
16 def __init__(self, url, opener):
17 # we assume opener has HTTPRangeHandler
17 # we assume opener has HTTPRangeHandler
18 self.url = url
18 self.url = url
19 self.pos = 0
19 self.pos = 0
20 self.opener = opener
20 self.opener = opener
21 self.name = url
21 self.name = url
22 def seek(self, pos):
22 def seek(self, pos):
23 self.pos = pos
23 self.pos = pos
24 def read(self, bytes=None):
24 def read(self, bytes=None):
25 req = urllib2.Request(self.url)
25 req = urllib2.Request(self.url)
26 end = ''
26 end = ''
27 if bytes:
27 if bytes:
28 end = self.pos + bytes - 1
28 end = self.pos + bytes - 1
29 req.add_header('Range', 'bytes=%d-%s' % (self.pos, end))
29 req.add_header('Range', 'bytes=%d-%s' % (self.pos, end))
30
30
31 try:
31 try:
32 f = self.opener.open(req)
32 f = self.opener.open(req)
33 data = f.read()
33 data = f.read()
34 if hasattr(f, 'getcode'):
34 if hasattr(f, 'getcode'):
35 # python 2.6+
35 # python 2.6+
36 code = f.getcode()
36 code = f.getcode()
37 elif hasattr(f, 'code'):
37 elif hasattr(f, 'code'):
38 # undocumented attribute, seems to be set in 2.4 and 2.5
38 # undocumented attribute, seems to be set in 2.4 and 2.5
39 code = f.code
39 code = f.code
40 else:
40 else:
41 # Don't know how to check, hope for the best.
41 # Don't know how to check, hope for the best.
42 code = 206
42 code = 206
43 except urllib2.HTTPError, inst:
43 except urllib2.HTTPError, inst:
44 num = inst.code == 404 and errno.ENOENT or None
44 num = inst.code == 404 and errno.ENOENT or None
45 raise IOError(num, inst)
45 raise IOError(num, inst)
46 except urllib2.URLError, inst:
46 except urllib2.URLError, inst:
47 raise IOError(None, inst.reason[1])
47 raise IOError(None, inst.reason[1])
48
48
49 if code == 200:
49 if code == 200:
50 # HTTPRangeHandler does nothing if remote does not support
50 # HTTPRangeHandler does nothing if remote does not support
51 # Range headers and returns the full entity. Let's slice it.
51 # Range headers and returns the full entity. Let's slice it.
52 if bytes:
52 if bytes:
53 data = data[self.pos:self.pos + bytes]
53 data = data[self.pos:self.pos + bytes]
54 else:
54 else:
55 data = data[self.pos:]
55 data = data[self.pos:]
56 elif bytes:
56 elif bytes:
57 data = data[:bytes]
57 data = data[:bytes]
58 self.pos += len(data)
58 self.pos += len(data)
59 return data
59 return data
60 def __iter__(self):
60 def __iter__(self):
61 return iter(self.read().splitlines(1))
61 return iter(self.read().splitlines(1))
62 def close(self):
62 def close(self):
63 pass
63 pass
64
64
65 def build_opener(ui, authinfo):
65 def build_opener(ui, authinfo):
66 # urllib cannot handle URLs with embedded user or passwd
66 # urllib cannot handle URLs with embedded user or passwd
67 urlopener = url.opener(ui, authinfo)
67 urlopener = url.opener(ui, authinfo)
68 urlopener.add_handler(byterange.HTTPRangeHandler())
68 urlopener.add_handler(byterange.HTTPRangeHandler())
69
69
70 class statichttpopener(scmutil.abstractopener):
70 class statichttpopener(scmutil.abstractopener):
71 def __init__(self, base):
71 def __init__(self, base):
72 self.base = base
72 self.base = base
73
73
74 def __call__(self, path, mode="r", atomictemp=None):
74 def __call__(self, path, mode="r", atomictemp=None):
75 if mode not in ('r', 'rb'):
75 if mode not in ('r', 'rb'):
76 raise IOError('Permission denied')
76 raise IOError('Permission denied')
77 f = "/".join((self.base, urllib.quote(path)))
77 f = "/".join((self.base, urllib.quote(path)))
78 return httprangereader(f, urlopener)
78 return httprangereader(f, urlopener)
79
79
80 return statichttpopener
80 return statichttpopener
81
81
82 class statichttprepository(localrepo.localrepository):
82 class statichttprepository(localrepo.localrepository):
83 def __init__(self, ui, path):
83 def __init__(self, ui, path):
84 self._url = path
84 self._url = path
85 self.ui = ui
85 self.ui = ui
86
86
87 self.root = path
87 self.root = path
88 u = util.url(path.rstrip('/') + "/.hg")
88 u = util.url(path.rstrip('/') + "/.hg")
89 self.path, authinfo = u.authinfo()
89 self.path, authinfo = u.authinfo()
90
90
91 opener = build_opener(ui, authinfo)
91 opener = build_opener(ui, authinfo)
92 self.opener = opener(self.path)
92 self.opener = opener(self.path)
93
93
94 try:
94 try:
95 requirements = scmutil.readrequires(self.opener, self.supported)
95 requirements = scmutil.readrequires(self.opener, self.supported)
96 except IOError, inst:
96 except IOError, inst:
97 if inst.errno != errno.ENOENT:
97 if inst.errno != errno.ENOENT:
98 raise
98 raise
99 requirements = set()
99 requirements = set()
100
100
101 # check if it is a non-empty old-style repository
101 # check if it is a non-empty old-style repository
102 try:
102 try:
103 fp = self.opener("00changelog.i")
103 fp = self.opener("00changelog.i")
104 fp.read(1)
104 fp.read(1)
105 fp.close()
105 fp.close()
106 except IOError, inst:
106 except IOError, inst:
107 if inst.errno != errno.ENOENT:
107 if inst.errno != errno.ENOENT:
108 raise
108 raise
109 # we do not care about empty old-style repositories here
109 # we do not care about empty old-style repositories here
110 msg = _("'%s' does not appear to be an hg repository") % path
110 msg = _("'%s' does not appear to be an hg repository") % path
111 raise error.RepoError(msg)
111 raise error.RepoError(msg)
112
112
113 # setup store
113 # setup store
114 self.store = store.store(requirements, self.path, opener)
114 self.store = store.store(requirements, self.path, opener)
115 self.spath = self.store.path
115 self.spath = self.store.path
116 self.sopener = self.store.opener
116 self.sopener = self.store.opener
117 self.sjoin = self.store.join
117 self.sjoin = self.store.join
118
118
119 self.manifest = manifest.manifest(self.sopener)
119 self.manifest = manifest.manifest(self.sopener)
120 self.changelog = changelog.changelog(self.sopener)
120 self.changelog = changelog.changelog(self.sopener)
121 self._tags = None
121 self._tags = None
122 self.nodetagscache = None
122 self.nodetagscache = None
123 self._branchcache = None
123 self._branchcache = None
124 self._branchcachetip = None
124 self._branchcachetip = None
125 self.encodepats = None
125 self.encodepats = None
126 self.decodepats = None
126 self.decodepats = None
127 self.capabilities = self.capabilities.difference(["pushkey"])
127 self.capabilities.difference_update(["pushkey"])
128
128
129 def url(self):
129 def url(self):
130 return self._url
130 return self._url
131
131
132 def local(self):
132 def local(self):
133 return False
133 return False
134
134
135 def lock(self, wait=True):
135 def lock(self, wait=True):
136 raise util.Abort(_('cannot lock static-http repository'))
136 raise util.Abort(_('cannot lock static-http repository'))
137
137
138 def instance(ui, path, create):
138 def instance(ui, path, create):
139 if create:
139 if create:
140 raise util.Abort(_('cannot create new static-http repository'))
140 raise util.Abort(_('cannot create new static-http repository'))
141 return statichttprepository(ui, path[7:])
141 return statichttprepository(ui, path[7:])
General Comments 0
You need to be logged in to leave comments. Login now