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