From f8701a9e8d8dac505d6c021eb34ebdcfe9afcf0b Mon Sep 17 00:00:00 2001 From: retiefjimm Date: Fri, 8 Oct 2010 18:46:03 -0500 Subject: [PATCH] Fix to force mimetype file to be uncompressed and first in epub. Tested on Python 2.5.2. --- zipdir.py | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/zipdir.py b/zipdir.py index ddaeb2f7..49810ed5 100644 --- a/zipdir.py +++ b/zipdir.py @@ -44,6 +44,32 @@ def addFolderToZip(zippedHelp,folder,fpath): def inMemoryZip(files): # files have a structure of {'path/to/file' => content} dictionary io = StringIO.StringIO() + + # This fixes the uncompressed mimetype-first issue by opening + # the in memory file as STORE, putting in the mimetype, then + # closing and re-opening with DEFLATED. while it is often + # true that mimetype is the first file, we can't assume it, + # because the dict object is defined as unordered. + path='mimetype' + memzip = zipfile.ZipFile(io, 'a', compression=zipfile.ZIP_STORED) + memzip.debug = 3 + if type(files[path]) != type('str'): + data = files[path].getvalue() + else: + data = files[path] + + logging.debug("Writing ZIP path %s" % path) + try: + memzip.writestr(path, data.encode('utf-8')) + except UnicodeDecodeError, e: + memzip.writestr(path.encode('utf-8'), data.encode('utf-8')) + + memzip.close() + + # remove it from the files dict. + del(files['mimetype']) + + # open in 'a' append mode. memzip = zipfile.ZipFile(io, 'a', compression=zipfile.ZIP_DEFLATED) memzip.debug = 3 @@ -55,16 +81,12 @@ def inMemoryZip(files): # logging.debug(data) logging.debug("Writing ZIP path %s" % path) - # epub standard requires mimetype to be uncompressed and first file. - if path == 'mimetype': - compress=zipfile.ZIP_STORED - else: - compress=zipfile.ZIP_DEFLATED try: - memzip.writestr(path, data.encode('utf-8'), compress_type=compress) + memzip.writestr(path, data.encode('utf-8')) except UnicodeDecodeError, e: - memzip.writestr(path.encode('utf-8'), data.encode('utf-8'), compress_type=compress) - + memzip.writestr(path.encode('utf-8'), data.encode('utf-8')) + + # declares all the files created by Windows. for zf in memzip.filelist: zf.create_system = 0 @@ -79,4 +101,4 @@ if __name__ == '__main__': data = inMemoryZip(files) f = open('res.zip', 'w') f.write(data) - f.close() \ No newline at end of file + f.close()