1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
import contextlib
import io
import shutil
from zipfile import ZipFile
def open_zip(fileobj, mode):
return _Zip(ZipFile(fileobj, mode))
class _Zip(object):
def __init__(self, zip_file):
self._zip_file = zip_file
def __enter__(self):
return self
def __exit__(self, *args):
self._zip_file.close()
def open(self, name):
return contextlib.closing(self._zip_file.open(name))
def exists(self, name):
try:
self._zip_file.getinfo(name)
return True
except KeyError:
return False
def read_str(self, name):
return self._zip_file.read(name).decode("utf8")
def update_zip(fileobj, files):
source = ZipFile(fileobj, "r")
try:
destination_fileobj = io.BytesIO()
destination = ZipFile(destination_fileobj, "w")
try:
names = set(source.namelist()) | set(files.keys())
for name in names:
if name in files:
contents = files[name]
else:
contents = source.read(name)
destination.writestr(name, contents)
finally:
destination.close()
finally:
source.close()
fileobj.seek(0)
destination_fileobj.seek(0)
shutil.copyfileobj(destination_fileobj, fileobj)
def uri_to_zip_entry_name(base, uri):
if uri.startswith("/"):
return uri[1:]
else:
return base + "/" + uri
|