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