Show More
@@ -195,34 +195,11 b' class tarit(object):' | |||
|
195 | 195 | if self.fileobj: |
|
196 | 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 | 198 | class zipit(object): |
|
217 | 199 | '''write archive to zip file or stream. can write uncompressed, |
|
218 | 200 | or compressed with deflate.''' |
|
219 | 201 | |
|
220 | 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 | 203 | self.z = zipfile.ZipFile(pycompat.fsdecode(dest), r'w', |
|
227 | 204 | compress and zipfile.ZIP_DEFLATED or |
|
228 | 205 | zipfile.ZIP_STORED) |
@@ -290,6 +290,37 b' def parserequestfromenv(env, bodyfh):' | |||
|
290 | 290 | headers=headers, |
|
291 | 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 | 324 | class wsgiresponse(object): |
|
294 | 325 | """Represents a response to a WSGI request. |
|
295 | 326 |
@@ -24,6 +24,9 b' from .common import (' | |||
|
24 | 24 | paritygen, |
|
25 | 25 | staticfile, |
|
26 | 26 | ) |
|
27 | from . import ( | |
|
28 | request as requestmod, | |
|
29 | ) | |
|
27 | 30 | |
|
28 | 31 | from .. import ( |
|
29 | 32 | archival, |
@@ -1215,7 +1218,9 b' def archive(web, req, tmpl):' | |||
|
1215 | 1218 | req.headers.extend(headers) |
|
1216 | 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 | 1224 | matchfn=match, |
|
1220 | 1225 | subrepos=web.configbool("web", "archivesubrepos")) |
|
1221 | 1226 | return [] |
General Comments 0
You need to be logged in to leave comments.
Login now