##// END OF EJS Templates
statichttprepo: use absolute_import
Gregory Szorc -
r25978:762f4c6d default
parent child Browse files
Show More
@@ -1,163 +1,179 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 __future__ import absolute_import
11 import changelog, byterange, url, error, namespaces
11
12 import localrepo, manifest, util, scmutil, store
12 import errno
13 import urllib, urllib2, errno, os
13 import os
14 import urllib
15 import urllib2
16
17 from .i18n import _
18 from . import (
19 byterange,
20 changelog,
21 error,
22 localrepo,
23 manifest,
24 namespaces,
25 scmutil,
26 store,
27 url,
28 util,
29 )
14
30
15 class httprangereader(object):
31 class httprangereader(object):
16 def __init__(self, url, opener):
32 def __init__(self, url, opener):
17 # we assume opener has HTTPRangeHandler
33 # we assume opener has HTTPRangeHandler
18 self.url = url
34 self.url = url
19 self.pos = 0
35 self.pos = 0
20 self.opener = opener
36 self.opener = opener
21 self.name = url
37 self.name = url
22 def seek(self, pos):
38 def seek(self, pos):
23 self.pos = pos
39 self.pos = pos
24 def read(self, bytes=None):
40 def read(self, bytes=None):
25 req = urllib2.Request(self.url)
41 req = urllib2.Request(self.url)
26 end = ''
42 end = ''
27 if bytes:
43 if bytes:
28 end = self.pos + bytes - 1
44 end = self.pos + bytes - 1
29 if self.pos or end:
45 if self.pos or end:
30 req.add_header('Range', 'bytes=%d-%s' % (self.pos, end))
46 req.add_header('Range', 'bytes=%d-%s' % (self.pos, end))
31
47
32 try:
48 try:
33 f = self.opener.open(req)
49 f = self.opener.open(req)
34 data = f.read()
50 data = f.read()
35 code = f.code
51 code = f.code
36 except urllib2.HTTPError as inst:
52 except urllib2.HTTPError as inst:
37 num = inst.code == 404 and errno.ENOENT or None
53 num = inst.code == 404 and errno.ENOENT or None
38 raise IOError(num, inst)
54 raise IOError(num, inst)
39 except urllib2.URLError as inst:
55 except urllib2.URLError as inst:
40 raise IOError(None, inst.reason[1])
56 raise IOError(None, inst.reason[1])
41
57
42 if code == 200:
58 if code == 200:
43 # HTTPRangeHandler does nothing if remote does not support
59 # HTTPRangeHandler does nothing if remote does not support
44 # Range headers and returns the full entity. Let's slice it.
60 # Range headers and returns the full entity. Let's slice it.
45 if bytes:
61 if bytes:
46 data = data[self.pos:self.pos + bytes]
62 data = data[self.pos:self.pos + bytes]
47 else:
63 else:
48 data = data[self.pos:]
64 data = data[self.pos:]
49 elif bytes:
65 elif bytes:
50 data = data[:bytes]
66 data = data[:bytes]
51 self.pos += len(data)
67 self.pos += len(data)
52 return data
68 return data
53 def readlines(self):
69 def readlines(self):
54 return self.read().splitlines(True)
70 return self.read().splitlines(True)
55 def __iter__(self):
71 def __iter__(self):
56 return iter(self.readlines())
72 return iter(self.readlines())
57 def close(self):
73 def close(self):
58 pass
74 pass
59
75
60 def build_opener(ui, authinfo):
76 def build_opener(ui, authinfo):
61 # urllib cannot handle URLs with embedded user or passwd
77 # urllib cannot handle URLs with embedded user or passwd
62 urlopener = url.opener(ui, authinfo)
78 urlopener = url.opener(ui, authinfo)
63 urlopener.add_handler(byterange.HTTPRangeHandler())
79 urlopener.add_handler(byterange.HTTPRangeHandler())
64
80
65 class statichttpvfs(scmutil.abstractvfs):
81 class statichttpvfs(scmutil.abstractvfs):
66 def __init__(self, base):
82 def __init__(self, base):
67 self.base = base
83 self.base = base
68
84
69 def __call__(self, path, mode='r', *args, **kw):
85 def __call__(self, path, mode='r', *args, **kw):
70 if mode not in ('r', 'rb'):
86 if mode not in ('r', 'rb'):
71 raise IOError('Permission denied')
87 raise IOError('Permission denied')
72 f = "/".join((self.base, urllib.quote(path)))
88 f = "/".join((self.base, urllib.quote(path)))
73 return httprangereader(f, urlopener)
89 return httprangereader(f, urlopener)
74
90
75 def join(self, path):
91 def join(self, path):
76 if path:
92 if path:
77 return os.path.join(self.base, path)
93 return os.path.join(self.base, path)
78 else:
94 else:
79 return self.base
95 return self.base
80
96
81 return statichttpvfs
97 return statichttpvfs
82
98
83 class statichttppeer(localrepo.localpeer):
99 class statichttppeer(localrepo.localpeer):
84 def local(self):
100 def local(self):
85 return None
101 return None
86 def canpush(self):
102 def canpush(self):
87 return False
103 return False
88
104
89 class statichttprepository(localrepo.localrepository):
105 class statichttprepository(localrepo.localrepository):
90 supported = localrepo.localrepository._basesupported
106 supported = localrepo.localrepository._basesupported
91
107
92 def __init__(self, ui, path):
108 def __init__(self, ui, path):
93 self._url = path
109 self._url = path
94 self.ui = ui
110 self.ui = ui
95
111
96 self.root = path
112 self.root = path
97 u = util.url(path.rstrip('/') + "/.hg")
113 u = util.url(path.rstrip('/') + "/.hg")
98 self.path, authinfo = u.authinfo()
114 self.path, authinfo = u.authinfo()
99
115
100 opener = build_opener(ui, authinfo)
116 opener = build_opener(ui, authinfo)
101 self.opener = opener(self.path)
117 self.opener = opener(self.path)
102 self.vfs = self.opener
118 self.vfs = self.opener
103 self._phasedefaults = []
119 self._phasedefaults = []
104
120
105 self.names = namespaces.namespaces()
121 self.names = namespaces.namespaces()
106
122
107 try:
123 try:
108 requirements = scmutil.readrequires(self.vfs, self.supported)
124 requirements = scmutil.readrequires(self.vfs, self.supported)
109 except IOError as inst:
125 except IOError as inst:
110 if inst.errno != errno.ENOENT:
126 if inst.errno != errno.ENOENT:
111 raise
127 raise
112 requirements = set()
128 requirements = set()
113
129
114 # check if it is a non-empty old-style repository
130 # check if it is a non-empty old-style repository
115 try:
131 try:
116 fp = self.vfs("00changelog.i")
132 fp = self.vfs("00changelog.i")
117 fp.read(1)
133 fp.read(1)
118 fp.close()
134 fp.close()
119 except IOError as inst:
135 except IOError as inst:
120 if inst.errno != errno.ENOENT:
136 if inst.errno != errno.ENOENT:
121 raise
137 raise
122 # we do not care about empty old-style repositories here
138 # we do not care about empty old-style repositories here
123 msg = _("'%s' does not appear to be an hg repository") % path
139 msg = _("'%s' does not appear to be an hg repository") % path
124 raise error.RepoError(msg)
140 raise error.RepoError(msg)
125
141
126 # setup store
142 # setup store
127 self.store = store.store(requirements, self.path, opener)
143 self.store = store.store(requirements, self.path, opener)
128 self.spath = self.store.path
144 self.spath = self.store.path
129 self.svfs = self.store.opener
145 self.svfs = self.store.opener
130 self.sjoin = self.store.join
146 self.sjoin = self.store.join
131 self._filecache = {}
147 self._filecache = {}
132 self.requirements = requirements
148 self.requirements = requirements
133
149
134 self.manifest = manifest.manifest(self.svfs)
150 self.manifest = manifest.manifest(self.svfs)
135 self.changelog = changelog.changelog(self.svfs)
151 self.changelog = changelog.changelog(self.svfs)
136 self._tags = None
152 self._tags = None
137 self.nodetagscache = None
153 self.nodetagscache = None
138 self._branchcaches = {}
154 self._branchcaches = {}
139 self._revbranchcache = None
155 self._revbranchcache = None
140 self.encodepats = None
156 self.encodepats = None
141 self.decodepats = None
157 self.decodepats = None
142 self._transref = None
158 self._transref = None
143
159
144 def _restrictcapabilities(self, caps):
160 def _restrictcapabilities(self, caps):
145 caps = super(statichttprepository, self)._restrictcapabilities(caps)
161 caps = super(statichttprepository, self)._restrictcapabilities(caps)
146 return caps.difference(["pushkey"])
162 return caps.difference(["pushkey"])
147
163
148 def url(self):
164 def url(self):
149 return self._url
165 return self._url
150
166
151 def local(self):
167 def local(self):
152 return False
168 return False
153
169
154 def peer(self):
170 def peer(self):
155 return statichttppeer(self)
171 return statichttppeer(self)
156
172
157 def lock(self, wait=True):
173 def lock(self, wait=True):
158 raise util.Abort(_('cannot lock static-http repository'))
174 raise util.Abort(_('cannot lock static-http repository'))
159
175
160 def instance(ui, path, create):
176 def instance(ui, path, create):
161 if create:
177 if create:
162 raise util.Abort(_('cannot create new static-http repository'))
178 raise util.Abort(_('cannot create new static-http repository'))
163 return statichttprepository(ui, path[7:])
179 return statichttprepository(ui, path[7:])
General Comments 0
You need to be logged in to leave comments. Login now