##// END OF EJS Templates
More whitespace cleanups...
mpm@selenic.com -
r575:7f5ce4bb default
parent child Browse files
Show More
@@ -9,9 +9,9 b''
9 9 # Lesser General Public License for more details.
10 10 #
11 11 # You should have received a copy of the GNU Lesser General Public
12 # License along with this library; if not, write to the
13 # Free Software Foundation, Inc.,
14 # 59 Temple Place, Suite 330,
12 # License along with this library; if not, write to the
13 # Free Software Foundation, Inc.,
14 # 59 Temple Place, Suite 330,
15 15 # Boston, MA 02111-1307 USA
16 16
17 17 # This file is part of urlgrabber, a high-level cross-protocol url-grabber
@@ -25,59 +25,59 b' import urllib'
25 25 import urllib2
26 26 import rfc822
27 27
28 try:
28 try:
29 29 from cStringIO import StringIO
30 except ImportError, msg:
30 except ImportError, msg:
31 31 from StringIO import StringIO
32 32
33 33 class RangeError(IOError):
34 34 """Error raised when an unsatisfiable range is requested."""
35 35 pass
36
36
37 37 class HTTPRangeHandler(urllib2.BaseHandler):
38 38 """Handler that enables HTTP Range headers.
39
39
40 40 This was extremely simple. The Range header is a HTTP feature to
41 begin with so all this class does is tell urllib2 that the
42 "206 Partial Content" reponse from the HTTP server is what we
41 begin with so all this class does is tell urllib2 that the
42 "206 Partial Content" reponse from the HTTP server is what we
43 43 expected.
44
44
45 45 Example:
46 46 import urllib2
47 47 import byterange
48
48
49 49 range_handler = range.HTTPRangeHandler()
50 50 opener = urllib2.build_opener(range_handler)
51
51
52 52 # install it
53 53 urllib2.install_opener(opener)
54
54
55 55 # create Request and set Range header
56 56 req = urllib2.Request('http://www.python.org/')
57 57 req.header['Range'] = 'bytes=30-50'
58 58 f = urllib2.urlopen(req)
59 59 """
60
60
61 61 def http_error_206(self, req, fp, code, msg, hdrs):
62 62 # 206 Partial Content Response
63 63 r = urllib.addinfourl(fp, hdrs, req.get_full_url())
64 64 r.code = code
65 65 r.msg = msg
66 66 return r
67
67
68 68 def http_error_416(self, req, fp, code, msg, hdrs):
69 69 # HTTP's Range Not Satisfiable error
70 70 raise RangeError('Requested Range Not Satisfiable')
71 71
72 72 class RangeableFileObject:
73 73 """File object wrapper to enable raw range handling.
74 This was implemented primarilary for handling range
75 specifications for file:// urls. This object effectively makes
76 a file object look like it consists only of a range of bytes in
74 This was implemented primarilary for handling range
75 specifications for file:// urls. This object effectively makes
76 a file object look like it consists only of a range of bytes in
77 77 the stream.
78
78
79 79 Examples:
80 # expose 10 bytes, starting at byte position 20, from
80 # expose 10 bytes, starting at byte position 20, from
81 81 # /etc/aliases.
82 82 >>> fo = RangeableFileObject(file('/etc/passwd', 'r'), (20,30))
83 83 # seek seeks within the range (to position 23 in this case)
@@ -89,11 +89,11 b' class RangeableFileObject:'
89 89 # byte in the range. the following will return only 7 bytes.
90 90 >>> fo.read(30)
91 91 """
92
92
93 93 def __init__(self, fo, rangetup):
94 94 """Create a RangeableFileObject.
95 fo -- a file like object. only the read() method need be
96 supported but supporting an optimized seek() is
95 fo -- a file like object. only the read() method need be
96 supported but supporting an optimized seek() is
97 97 preferable.
98 98 rangetup -- a (firstbyte,lastbyte) tuple specifying the range
99 99 to work over.
@@ -103,7 +103,7 b' class RangeableFileObject:'
103 103 (self.firstbyte, self.lastbyte) = range_tuple_normalize(rangetup)
104 104 self.realpos = 0
105 105 self._do_seek(self.firstbyte)
106
106
107 107 def __getattr__(self, name):
108 108 """This effectively allows us to wrap at the instance level.
109 109 Any attribute not found in _this_ object will be searched for
@@ -111,16 +111,16 b' class RangeableFileObject:'
111 111 if hasattr(self.fo, name):
112 112 return getattr(self.fo, name)
113 113 raise AttributeError, name
114
114
115 115 def tell(self):
116 116 """Return the position within the range.
117 This is different from fo.seek in that position 0 is the
117 This is different from fo.seek in that position 0 is the
118 118 first byte position of the range tuple. For example, if
119 119 this object was created with a range tuple of (500,899),
120 120 tell() will return 0 when at byte position 500 of the file.
121 121 """
122 122 return (self.realpos - self.firstbyte)
123
123
124 124 def seek(self,offset,whence=0):
125 125 """Seek within the byte range.
126 126 Positioning is identical to that described under tell().
@@ -133,13 +133,13 b' class RangeableFileObject:'
133 133 elif whence == 2: # absolute from end of file
134 134 # XXX: are we raising the right Error here?
135 135 raise IOError('seek from end of file not supported.')
136
136
137 137 # do not allow seek past lastbyte in range
138 138 if self.lastbyte and (realoffset >= self.lastbyte):
139 139 realoffset = self.lastbyte
140
140
141 141 self._do_seek(realoffset - self.realpos)
142
142
143 143 def read(self, size=-1):
144 144 """Read within the range.
145 145 This method will limit the size read based on the range.
@@ -148,7 +148,7 b' class RangeableFileObject:'
148 148 rslt = self.fo.read(size)
149 149 self.realpos += len(rslt)
150 150 return rslt
151
151
152 152 def readline(self, size=-1):
153 153 """Read lines within the range.
154 154 This method will limit the size read based on the range.
@@ -157,7 +157,7 b' class RangeableFileObject:'
157 157 rslt = self.fo.readline(size)
158 158 self.realpos += len(rslt)
159 159 return rslt
160
160
161 161 def _calc_read_size(self, size):
162 162 """Handles calculating the amount of data to read based on
163 163 the range.
@@ -169,7 +169,7 b' class RangeableFileObject:'
169 169 else:
170 170 size = (self.lastbyte - self.realpos)
171 171 return size
172
172
173 173 def _do_seek(self,offset):
174 174 """Seek based on whether wrapped object supports seek().
175 175 offset is relative to the current position (self.realpos).
@@ -180,7 +180,7 b' class RangeableFileObject:'
180 180 else:
181 181 self.fo.seek(self.realpos + offset)
182 182 self.realpos+= offset
183
183
184 184 def _poor_mans_seek(self,offset):
185 185 """Seek by calling the wrapped file objects read() method.
186 186 This is used for file like objects that do not have native
@@ -188,7 +188,7 b' class RangeableFileObject:'
188 188 to manually seek to the desired position.
189 189 offset -- read this number of bytes from the wrapped
190 190 file object.
191 raise RangeError if we encounter EOF before reaching the
191 raise RangeError if we encounter EOF before reaching the
192 192 specified offset.
193 193 """
194 194 pos = 0
@@ -237,10 +237,10 b' class FileRangeHandler(urllib2.FileHandl'
237 237 return urllib.addinfourl(fo, headers, 'file:'+file)
238 238
239 239
240 # FTP Range Support
240 # FTP Range Support
241 241 # Unfortunately, a large amount of base FTP code had to be copied
242 242 # from urllib and urllib2 in order to insert the FTP REST command.
243 # Code modifications for range support have been commented as
243 # Code modifications for range support have been commented as
244 244 # follows:
245 245 # -- range support modifications start/end here
246 246
@@ -271,7 +271,7 b' class FTPRangeHandler(urllib2.FTPHandler'
271 271 host = unquote(host)
272 272 user = unquote(user or '')
273 273 passwd = unquote(passwd or '')
274
274
275 275 try:
276 276 host = socket.gethostbyname(host)
277 277 except socket.error, msg:
@@ -290,22 +290,22 b' class FTPRangeHandler(urllib2.FTPHandler'
290 290 if attr.lower() == 'type' and \
291 291 value in ('a', 'A', 'i', 'I', 'd', 'D'):
292 292 type = value.upper()
293
293
294 294 # -- range support modifications start here
295 295 rest = None
296 range_tup = range_header_to_tuple(req.headers.get('Range',None))
296 range_tup = range_header_to_tuple(req.headers.get('Range',None))
297 297 assert range_tup != ()
298 298 if range_tup:
299 299 (fb,lb) = range_tup
300 300 if fb > 0: rest = fb
301 301 # -- range support modifications end here
302
302
303 303 fp, retrlen = fw.retrfile(file, type, rest)
304
304
305 305 # -- range support modifications start here
306 306 if range_tup:
307 307 (fb,lb) = range_tup
308 if lb == '':
308 if lb == '':
309 309 if retrlen is None or retrlen == 0:
310 310 raise RangeError('Requested Range Not Satisfiable due to unobtainable file length.')
311 311 lb = retrlen
@@ -317,7 +317,7 b' class FTPRangeHandler(urllib2.FTPHandler'
317 317 retrlen = lb - fb
318 318 fp = RangeableFileObject(fp, (0,retrlen))
319 319 # -- range support modifications end here
320
320
321 321 headers = ""
322 322 mtype = mimetypes.guess_type(req.get_full_url())[0]
323 323 if mtype:
@@ -389,17 +389,17 b' class ftpwrapper(urllib.ftpwrapper):'
389 389 _rangere = None
390 390 def range_header_to_tuple(range_header):
391 391 """Get a (firstbyte,lastbyte) tuple from a Range header value.
392
392
393 393 Range headers have the form "bytes=<firstbyte>-<lastbyte>". This
394 394 function pulls the firstbyte and lastbyte values and returns
395 395 a (firstbyte,lastbyte) tuple. If lastbyte is not specified in
396 396 the header value, it is returned as an empty string in the
397 397 tuple.
398
398
399 399 Return None if range_header is None
400 Return () if range_header does not conform to the range spec
400 Return () if range_header does not conform to the range spec
401 401 pattern.
402
402
403 403 """
404 404 global _rangere
405 405 if range_header is None: return None
@@ -407,9 +407,9 b' def range_header_to_tuple(range_header):'
407 407 import re
408 408 _rangere = re.compile(r'^bytes=(\d{1,})-(\d*)')
409 409 match = _rangere.match(range_header)
410 if match:
410 if match:
411 411 tup = range_tuple_normalize(match.group(1,2))
412 if tup and tup[1]:
412 if tup and tup[1]:
413 413 tup = (tup[0],tup[1]+1)
414 414 return tup
415 415 return ()
@@ -422,14 +422,14 b' def range_tuple_to_header(range_tup):'
422 422 if range_tup is None: return None
423 423 range_tup = range_tuple_normalize(range_tup)
424 424 if range_tup:
425 if range_tup[1]:
425 if range_tup[1]:
426 426 range_tup = (range_tup[0],range_tup[1] - 1)
427 427 return 'bytes=%s-%s' % range_tup
428
428
429 429 def range_tuple_normalize(range_tup):
430 430 """Normalize a (first_byte,last_byte) range tuple.
431 431 Return a tuple whose first element is guaranteed to be an int
432 and whose second element will be '' (meaning: the last byte) or
432 and whose second element will be '' (meaning: the last byte) or
433 433 an int. Finally, return None if the normalized tuple == (0,'')
434 434 as that is equivelant to retrieving the entire file.
435 435 """
@@ -441,7 +441,7 b' def range_tuple_normalize(range_tup):'
441 441 # handle last byte
442 442 try: lb = range_tup[1]
443 443 except IndexError: lb = ''
444 else:
444 else:
445 445 if lb is None: lb = ''
446 446 elif lb != '': lb = int(lb)
447 447 # check if range is over the entire file
@@ -449,4 +449,3 b' def range_tuple_normalize(range_tup):'
449 449 # check that the range is valid
450 450 if lb < fb: raise RangeError('Invalid byte range: %s-%s' % (fb,lb))
451 451 return (fb,lb)
452
@@ -647,7 +647,7 b' class localrepository:'
647 647 if cp:
648 648 meta["copy"] = cp
649 649 meta["copyrev"] = hex(m1.get(cp, m2.get(cp, nullid)))
650 self.ui.debug(" %s: copy %s:%s\n" % (f, cp, meta["copyrev"]))
650 self.ui.debug(" %s: copy %s:%s\n" % (f, cp, meta["copyrev"]))
651 651
652 652 r = self.file(f)
653 653 fp1 = m1.get(f, nullid)
@@ -813,7 +813,7 b' class localrepository:'
813 813 while n != bottom:
814 814 p = self.changelog.parents(n)[0]
815 815 if i == f:
816 l.append(n)
816 l.append(n)
817 817 f = f * 2
818 818 n = p
819 819 i += 1
@@ -1,7 +1,7 b''
1 1 # hgweb.py - web interface to a mercurial repository
2 2 #
3 3 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
4 # Copyright 2005 Matt Mackall <mpm@selenic.com>
4 # Copyright 2005 Matt Mackall <mpm@selenic.com>
5 5 #
6 6 # This software may be used and distributed according to the terms
7 7 # of the GNU General Public License, incorporated herein by reference.
@@ -657,7 +657,7 b' class hgweb:'
657 657 except KeyError:
658 658 write(self.search(hi))
659 659 return
660
660
661 661 write(self.changelog(hi))
662 662
663 663 elif args['cmd'][0] == 'changeset':
@@ -1,6 +1,6 b''
1 1 #!/usr/bin/env python
2
3 # This is the mercurial setup script.
2 #
3 # This is the mercurial setup script.
4 4 #
5 5 # './setup.py install', or
6 6 # './setup.py --help' for more options
@@ -35,7 +35,7 b' try:'
35 35 data_files=[('mercurial/templates',
36 36 ['templates/map'] +
37 37 glob.glob('templates/map-*') +
38 glob.glob('templates/*.tmpl'))],
38 glob.glob('templates/*.tmpl'))],
39 39 cmdclass = { 'install_data' : install_package_data },
40 40 scripts=['hg', 'hgmerge'])
41 41 finally:
General Comments 0
You need to be logged in to leave comments. Login now