##// END OF EJS Templates
hgweb: refactor fake file object proxy for archiving...
Gregory Szorc -
r36891:16499427 default
parent child Browse files
Show More
@@ -195,34 +195,11 b' class tarit(object):'
195 if self.fileobj:
195 if self.fileobj:
196 self.fileobj.close()
196 self.fileobj.close()
197
197
198 class tellable(object):
199 '''provide tell method for zipfile.ZipFile when writing to http
200 response file object.'''
201
202 def __init__(self, fp):
203 self.fp = fp
204 self.offset = 0
205
206 def __getattr__(self, key):
207 return getattr(self.fp, key)
208
209 def write(self, s):
210 self.fp.write(s)
211 self.offset += len(s)
212
213 def tell(self):
214 return self.offset
215
216 class zipit(object):
198 class zipit(object):
217 '''write archive to zip file or stream. can write uncompressed,
199 '''write archive to zip file or stream. can write uncompressed,
218 or compressed with deflate.'''
200 or compressed with deflate.'''
219
201
220 def __init__(self, dest, mtime, compress=True):
202 def __init__(self, dest, mtime, compress=True):
221 if not isinstance(dest, bytes):
222 try:
223 dest.tell()
224 except (AttributeError, IOError):
225 dest = tellable(dest)
226 self.z = zipfile.ZipFile(pycompat.fsdecode(dest), r'w',
203 self.z = zipfile.ZipFile(pycompat.fsdecode(dest), r'w',
227 compress and zipfile.ZIP_DEFLATED or
204 compress and zipfile.ZIP_DEFLATED or
228 zipfile.ZIP_STORED)
205 zipfile.ZIP_STORED)
@@ -290,6 +290,37 b' def parserequestfromenv(env, bodyfh):'
290 headers=headers,
290 headers=headers,
291 bodyfh=bodyfh)
291 bodyfh=bodyfh)
292
292
293 class offsettrackingwriter(object):
294 """A file object like object that is append only and tracks write count.
295
296 Instances are bound to a callable. This callable is called with data
297 whenever a ``write()`` is attempted.
298
299 Instances track the amount of written data so they can answer ``tell()``
300 requests.
301
302 The intent of this class is to wrap the ``write()`` function returned by
303 a WSGI ``start_response()`` function. Since ``write()`` is a callable and
304 not a file object, it doesn't implement other file object methods.
305 """
306 def __init__(self, writefn):
307 self._write = writefn
308 self._offset = 0
309
310 def write(self, s):
311 res = self._write(s)
312 # Some Python objects don't report the number of bytes written.
313 if res is None:
314 self._offset += len(s)
315 else:
316 self._offset += res
317
318 def flush(self):
319 pass
320
321 def tell(self):
322 return self._offset
323
293 class wsgiresponse(object):
324 class wsgiresponse(object):
294 """Represents a response to a WSGI request.
325 """Represents a response to a WSGI request.
295
326
@@ -24,6 +24,9 b' from .common import ('
24 paritygen,
24 paritygen,
25 staticfile,
25 staticfile,
26 )
26 )
27 from . import (
28 request as requestmod,
29 )
27
30
28 from .. import (
31 from .. import (
29 archival,
32 archival,
@@ -1215,7 +1218,9 b' def archive(web, req, tmpl):'
1215 req.headers.extend(headers)
1218 req.headers.extend(headers)
1216 req.respond(HTTP_OK, mimetype)
1219 req.respond(HTTP_OK, mimetype)
1217
1220
1218 archival.archive(web.repo, req, cnode, artype, prefix=name,
1221 bodyfh = requestmod.offsettrackingwriter(req.write)
1222
1223 archival.archive(web.repo, bodyfh, cnode, artype, prefix=name,
1219 matchfn=match,
1224 matchfn=match,
1220 subrepos=web.configbool("web", "archivesubrepos"))
1225 subrepos=web.configbool("web", "archivesubrepos"))
1221 return []
1226 return []
General Comments 0
You need to be logged in to leave comments. Login now