[go: up one dir, main page]

Menu

[r486]: / mcomix / archive_packer.py  Maximize  Restore  History

Download this file

116 lines (87 with data), 3.8 kB

  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
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
"""archive_packer.py - Archive creation class."""
import os
import zipfile
import threading
from mcomix import log
class Packer:
"""Packer is a threaded class for packing files into ZIP archives.
It would be straight-forward to add support for more archive types,
but basically all other types are less well fitted for this particular
task than ZIP archives are (yes, really).
"""
def __init__(self, image_files, other_files, archive_path, base_name):
"""Setup a Packer object to create a ZIP archive at <archive_path>.
All files pointed to by paths in the sequences <image_files> and
<other_files> will be included in the archive when packed.
The files in <image_files> will be renamed on the form
"NN - <base_name>.ext", so that the lexical ordering of their
filenames match that of their order in the list.
The files in <other_files> will be included as they are,
assuming their filenames does not clash with other filenames in
the archive. All files are placed in the archive root.
"""
self._image_files = image_files
self._other_files = other_files
self._archive_path = archive_path
self._base_name = base_name
self._pack_thread = None
self._packing_successful = False
def pack(self):
"""Pack all the files in the file lists into the archive."""
self._pack_thread = threading.Thread(target=self._thread_pack)
self._pack_thread.setDaemon(False)
self._pack_thread.start()
def wait(self):
"""Block until the packer thread has finished. Return True if the
packer finished its work successfully.
"""
if self._pack_thread != None:
self._pack_thread.join()
return self._packing_successful
def _thread_pack(self):
try:
zfile = zipfile.ZipFile(self._archive_path, 'w')
except Exception:
log.error(_('! Could not create archive at path "%s"'),
self._archive_path)
return
used_names = []
pattern = '%%0%dd - %s%%s' % (len(str(len(self._image_files))),
self._base_name)
for i, path in enumerate(self._image_files):
filename = pattern % (i + 1, os.path.splitext(path)[1])
try:
zfile.write(path, filename, zipfile.ZIP_STORED)
except Exception:
log.error(_('! Could not add file %(sourcefile)s '
'to archive %(archivefile)s, aborting...'),
{ "sourcefile" : path,
"archivefile" : self._archive_path})
zfile.close()
try:
os.remove(self._archive_path)
except:
pass
return
used_names.append(filename)
for path in self._other_files:
filename = os.path.basename(path)
while filename in used_names:
filename = '_%s' % filename
try:
zfile.write(path, filename, zipfile.ZIP_DEFLATED)
except Exception:
log.error(_('! Could not add file %(sourcefile)s '
'to archive %(archivefile)s, aborting...'),
{ "sourcefile" : path,
"archivefile" : self._archive_path})
zfile.close()
try:
os.remove(self._archive_path)
except:
pass
return
used_names.append(filename)
zfile.close()
self._packing_successful = True
# vim: expandtab:sw=4:ts=4