From ea0ee8d3d71597eb1527466facafaa3115754af5 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 10 Feb 2010 17:38:24 -0700 Subject: [PATCH] ... --- src/calibre/utils/zipfile.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/calibre/utils/zipfile.py b/src/calibre/utils/zipfile.py index c5f849a073..6bf6f2f83c 100644 --- a/src/calibre/utils/zipfile.py +++ b/src/calibre/utils/zipfile.py @@ -143,7 +143,7 @@ def decode_arcname(name): name = name.decode(encoding) except: name = name.decode('utf-8', 'replace') - return sanitize_file_name(name.encode(filesystem_encoding, 'replace')) + return name.encode(filesystem_encoding, 'replace') def is_zipfile(filename): @@ -690,6 +690,7 @@ class ZipFile: self.debug = 0 # Level of printing: 0 through 3 self.NameToInfo = {} # Find file info given name self.filelist = [] # List of ZipInfo instances for archive + self.extract_mapping = {} self.compression = compression # Method of compression self.mode = key = mode.replace('b', '')[0] self.pwd = None @@ -1054,9 +1055,14 @@ class ZipFile: if not os.path.exists(targetpath): # Could be a previously automatically created directory with closing(self.open(member, pwd=pwd)) as source: - with open(targetpath, 'wb') as target: - shutil.copyfileobj(source, target) - + try: + with open(targetpath, 'wb') as target: + shutil.copyfileobj(source, target) + except: + targetpath = sanitize_file_name(targetpath) + with open(targetpath, 'wb') as target: + shutil.copyfileobj(source, target) + self.extract_mapping[member.filename] = targetpath return targetpath def _writecheck(self, zinfo): @@ -1337,14 +1343,14 @@ def safe_replace(zipstream, name, datastream): names = z.infolist() with TemporaryDirectory('_zipfile_replace') as tdir: z.extractall(path=tdir) + mapping = z.extract_mapping path = os.path.join(tdir, *name.split('/')) shutil.copyfileobj(datastream, open(path, 'wb')) zipstream.seek(0) zipstream.truncate() with closing(ZipFile(zipstream, 'w')) as z: for info in names: - fname = decode_arcname(info.filename) - current = os.path.join(tdir, *fname.split('/')) + current = mapping[info.filename] if os.path.isdir(current): z.writestr(info.filename+'/', '', 0700) else: