/usr/share/pyshared/translate/misc/zipfileext.py is in translate-toolkit 1.10.0-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | #!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright 2004, 2005 Zuza Software Foundation
#
# This file is part of translate.
#
# translate is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# translate is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
"""Extensions to zipfile standard module that will hopefully get
included in future."""
from zipfile import ZipFile, struct, structCentralDir, \
stringCentralDir, structEndArchive, stringEndArchive
class ZipFileExt(ZipFile, object):
"""a ZipFile that can handle replacing objects"""
def delete(self, name):
"""Delete the file from the archive. If it appears multiple
times only the first instance will be deleted."""
for i in range(0, len(self.filelist)):
if self.filelist[i].filename == name:
if self.debug:
print "Removing", name
deleted_offset = self.filelist[i].header_offset
# "file_offset" is only available in python up to 2.4
if hasattr(self.filelist[i], "file_offset"):
deleted_size = ((self.filelist[i].file_offset -
self.filelist[i].header_offset) +
self.filelist[i].compress_size)
else:
deleted_size = ((len(self.filelist[i].FileHeader()) -
self.filelist[i].header_offset) +
self.filelist[i].compress_size)
zinfo_size = (struct.calcsize(structCentralDir) +
len(self.filelist[i].filename) +
len(self.filelist[i].extra))
# Remove the file's data from the archive.
current_offset = self.fp.tell()
# go to the end of the archive to calculate the
# total archive_size
self.fp.seek(0, 2)
archive_size = self.fp.tell()
self.fp.seek(deleted_offset + deleted_size)
buf = self.fp.read()
self.fp.seek(deleted_offset)
self.fp.write(buf)
self.fp.truncate(archive_size - deleted_size - zinfo_size)
# go to the end of the archive to calculate the
# total archive_size
self.fp.seek(0, 2)
if self.debug >= 2:
if self.fp.tell() != (archive_size - deleted_size -
zinfo_size):
print "truncation failed: %r != %r" % \
(self.fp.tell(),
(archive_size - deleted_size - zinfo_size))
if current_offset > deleted_offset + deleted_size:
current_offset -= deleted_size
elif current_offset > deleted_offset:
current_offset = deleted_offset
self.fp.seek(current_offset, 0)
# Remove file from central directory.
del self.filelist[i]
# Adjust the remaining offsets in the central directory.
for j in range(i, len(self.filelist)):
if self.filelist[j].header_offset > deleted_offset:
self.filelist[j].header_offset -= deleted_size
# "file_offset" is only available in python up to 2.4
if hasattr(self.filelist[i], "file_offset"):
if self.filelist[j].file_offset > deleted_offset:
self.filelist[j].file_offset -= deleted_size
del self.NameToInfo[name]
return
if self.debug:
print name, "not in archive"
def close(self):
"""Close the file, and for mode "w" and "a" write the ending
records."""
if self.fp is None:
return
self.writeendrec()
if not self._filePassed:
self.fp.close()
self.fp = None
def writeendrec(self):
"""Write the ending records (without neccessarily closing the file)"""
if self.mode in ("w", "a"): # write ending records
count = 0
pos1 = self.fp.tell()
for zinfo in self.filelist: # write central directory
count = count + 1
dt = zinfo.date_time
dosdate = (dt[0] - 1980) << 9 | dt[1] << 5 | dt[2]
dostime = dt[3] << 11 | dt[4] << 5 | (dt[5] // 2)
filename, zinfo.flag_bits = zinfo._encodeFilenameFlags()
centdir = struct.pack(structCentralDir,
stringCentralDir, zinfo.create_version,
zinfo.create_system, zinfo.extract_version, zinfo.reserved,
zinfo.flag_bits, zinfo.compress_type, dostime, dosdate,
zinfo.CRC, zinfo.compress_size, zinfo.file_size,
len(filename), len(zinfo.extra), len(zinfo.comment),
0, zinfo.internal_attr, zinfo.external_attr,
zinfo.header_offset)
self.fp.write(centdir)
self.fp.write(filename)
self.fp.write(zinfo.extra)
self.fp.write(zinfo.comment)
pos2 = self.fp.tell()
# Write end-of-zip-archive record
endrec = struct.pack(structEndArchive, stringEndArchive,
0, 0, count, count, pos2 - pos1, pos1, 0)
self.fp.write(endrec)
self.fp.seek(pos1)
|