Package translate :: Package misc :: Module zipfileext
[hide private]
[frames] | no frames]

Source Code for Module translate.misc.zipfileext

  1  #!/usr/bin/env python 
  2  # -*- coding: utf-8 -*- 
  3  #  
  4  # Copyright 2004, 2005 Zuza Software Foundation 
  5  #  
  6  # This file is part of translate. 
  7  # 
  8  # translate is free software; you can redistribute it and/or modify 
  9  # it under the terms of the GNU General Public License as published by 
 10  # the Free Software Foundation; either version 2 of the License, or 
 11  # (at your option) any later version. 
 12  #  
 13  # translate is distributed in the hope that it will be useful, 
 14  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 15  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 16  # GNU General Public License for more details. 
 17  # 
 18  # You should have received a copy of the GNU General Public License 
 19  # along with translate; if not, write to the Free Software 
 20  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 21   
 22  """extensions to zipfile standard module that will hopefully get included in future...""" 
 23   
 24  from zipfile import ZipFile, struct, structCentralDir, stringCentralDir, structEndArchive, stringEndArchive 
 25   
26 -class ZipFileExt(ZipFile, object):
27 """a ZipFile that can handle replacing objects"""
28 - def delete(self, name):
29 """Delete the file from the archive. If it appears multiple 30 times only the first instance will be deleted.""" 31 for i in range (0, len(self.filelist)): 32 if self.filelist[i].filename == name: 33 if self.debug: 34 print "Removing", name 35 deleted_offset = self.filelist[i].header_offset 36 # "file_offset" is only available in python up to 2.4 37 if hasattr(self.filelist[i], "file_offset"): 38 deleted_size = (self.filelist[i].file_offset - self.filelist[i].header_offset) + self.filelist[i].compress_size 39 else: 40 deleted_size = (len(self.filelist[i].FileHeader()) - self.filelist[i].header_offset) + self.filelist[i].compress_size 41 zinfo_size = struct.calcsize(structCentralDir) + len(self.filelist[i].filename) + len(self.filelist[i].extra) 42 # Remove the file's data from the archive. 43 current_offset = self.fp.tell() 44 # go to the end of the archive to calculate the total archive_size 45 self.fp.seek(0, 2) 46 archive_size = self.fp.tell() 47 self.fp.seek(deleted_offset + deleted_size) 48 buf = self.fp.read() 49 self.fp.seek(deleted_offset) 50 self.fp.write(buf) 51 self.fp.truncate(archive_size - deleted_size - zinfo_size) 52 # go to the end of the archive to calculate the total archive_size 53 self.fp.seek(0, 2) 54 if self.debug >= 2: 55 if self.fp.tell() != archive_size - deleted_size - zinfo_size: 56 print "truncation failed: %r != %r" % (self.fp.tell(), archive_size - deleted_size - zinfo_size) 57 if current_offset > deleted_offset + deleted_size: 58 current_offset -= deleted_size 59 elif current_offset > deleted_offset: 60 current_offset = deleted_offset 61 self.fp.seek(current_offset, 0) 62 # Remove file from central directory. 63 del self.filelist[i] 64 # Adjust the remaining offsets in the central directory. 65 for j in range (i, len(self.filelist)): 66 if self.filelist[j].header_offset > deleted_offset: 67 self.filelist[j].header_offset -= deleted_size 68 # "file_offset" is only available in python up to 2.4 69 if hasattr(self.filelist[i], "file_offset"): 70 if self.filelist[j].file_offset > deleted_offset: 71 self.filelist[j].file_offset -= deleted_size 72 del self.NameToInfo[name] 73 return 74 if self.debug: 75 print name, "not in archive"
76
77 - def close(self):
78 """Close the file, and for mode "w" and "a" write the ending 79 records.""" 80 if self.fp is None: 81 return 82 self.writeendrec() 83 if not self._filePassed: 84 self.fp.close() 85 self.fp = None
86
87 - def writeendrec(self):
88 """Write the ending records (without neccessarily closing the file)""" 89 if self.mode in ("w", "a"): # write ending records 90 count = 0 91 current_offset = self.fp.tell() 92 pos1 = self.fp.tell() 93 for zinfo in self.filelist: # write central directory 94 count = count + 1 95 dt = zinfo.date_time 96 dosdate = (dt[0] - 1980) << 9 | dt[1] << 5 | dt[2] 97 dostime = dt[3] << 11 | dt[4] << 5 | (dt[5] // 2) 98 centdir = struct.pack(structCentralDir, 99 stringCentralDir, zinfo.create_version, 100 zinfo.create_system, zinfo.extract_version, zinfo.reserved, 101 zinfo.flag_bits, zinfo.compress_type, dostime, dosdate, 102 zinfo.CRC, zinfo.compress_size, zinfo.file_size, 103 len(zinfo.filename), len(zinfo.extra), len(zinfo.comment), 104 0, zinfo.internal_attr, zinfo.external_attr, 105 zinfo.header_offset) 106 self.fp.write(centdir) 107 self.fp.write(zinfo.filename) 108 self.fp.write(zinfo.extra) 109 self.fp.write(zinfo.comment) 110 pos2 = self.fp.tell() 111 # Write end-of-zip-archive record 112 endrec = struct.pack(structEndArchive, stringEndArchive, 113 0, 0, count, count, pos2 - pos1, pos1, 0) 114 self.fp.write(endrec) 115 self.fp.seek(pos1)
116