Back to index

enigmail  1.4.3
Public Member Functions | Public Attributes | Private Attributes
MozZipFile.ZipFile Class Reference

List of all members.

Public Member Functions

def __init__
def writestr
def close

Public Attributes

 lockfile
 end
 debug
 fp

Private Attributes

 _remove

Detailed Description

Class with methods to open, read, write, close, list zip files.

Subclassing zipfile.ZipFile to allow for overwriting of existing
entries, though only for writestr, not for write.

Definition at line 45 of file MozZipFile.py.


Constructor & Destructor Documentation

def MozZipFile.ZipFile.__init__ (   self,
  file,
  mode = "r",
  compression = zipfile.ZIP_STORED,
  lock = False 
)

Definition at line 52 of file MozZipFile.py.

00052 
00053                lock = False):
00054     if lock:
00055       assert isinstance(file, basestring)
00056       self.lockfile = lockFile(file + '.lck')
00057     else:
00058       self.lockfile = None
00059 
00060     if mode == 'a' and lock:
00061       # appending to a file which doesn't exist fails, but we can't check
00062       # existence util we hold the lock
00063       if (not os.path.isfile(file)) or os.path.getsize(file) == 0:
00064         mode = 'w'
00065 
00066     zipfile.ZipFile.__init__(self, file, mode, compression)
00067     self._remove = []
00068     self.end = self.fp.tell()
00069     self.debug = 0


Member Function Documentation

def MozZipFile.ZipFile.close (   self)
Close the file, and for mode "w" and "a" write the ending
records.

Overwritten to compact overwritten entries.

Definition at line 129 of file MozZipFile.py.

00129 
00130   def close(self):
00131     """Close the file, and for mode "w" and "a" write the ending
00132     records.
00133 
00134     Overwritten to compact overwritten entries.
00135     """
00136     if not self._remove:
00137       # we don't have anything special to do, let's just call base
00138       r = zipfile.ZipFile.close(self)
00139       self.lockfile = None
00140       return r
00141 
00142     if self.fp.mode != 'r+b':
00143       # adjust file mode if we originally just wrote, now we rewrite
00144       self.fp.close()
00145       self.fp = open(self.filename, 'r+b')
00146     all = map(lambda zi: (zi, True), self.filelist) + \
00147         map(lambda zi: (zi, False), self._remove)
00148     all.sort(lambda l, r: cmp(l[0].header_offset, r[0].header_offset))
00149     # empty _remove for multiple closes
00150     self._remove = []
00151 
00152     lengths = [all[i+1][0].header_offset - all[i][0].header_offset
00153                for i in xrange(len(all)-1)]
00154     lengths.append(self.end - all[-1][0].header_offset)
00155     to_pos = 0
00156     for (zi, keep), length in zip(all, lengths):
00157       if not keep:
00158         continue
00159       oldoff = zi.header_offset
00160       # python <= 2.4 has file_offset
00161       if hasattr(zi, 'file_offset'):
00162         zi.file_offset = zi.file_offset + to_pos - oldoff
00163       zi.header_offset = to_pos
00164       self.fp.seek(oldoff)
00165       content = self.fp.read(length)
00166       self.fp.seek(to_pos)
00167       self.fp.write(content)
00168       to_pos += length
00169     self.fp.truncate()
00170     zipfile.ZipFile.close(self)
00171     self.lockfile = None
def MozZipFile.ZipFile.writestr (   self,
  zinfo_or_arcname,
  bytes 
)
Write contents into the archive.

The contents is the argument 'bytes',  'zinfo_or_arcname' is either
a ZipInfo instance or the name of the file in the archive.
This method is overloaded to allow overwriting existing entries.

Definition at line 70 of file MozZipFile.py.

00070 
00071   def writestr(self, zinfo_or_arcname, bytes):
00072     """Write contents into the archive.
00073 
00074     The contents is the argument 'bytes',  'zinfo_or_arcname' is either
00075     a ZipInfo instance or the name of the file in the archive.
00076     This method is overloaded to allow overwriting existing entries.
00077     """
00078     if not isinstance(zinfo_or_arcname, zipfile.ZipInfo):
00079       zinfo = zipfile.ZipInfo(filename=zinfo_or_arcname,
00080                               date_time=time.localtime(time.time()))
00081       zinfo.compress_type = self.compression
00082       # Add some standard UNIX file access permissions (-rw-r--r--).
00083       zinfo.external_attr = (0x81a4 & 0xFFFF) << 16L
00084     else:
00085       zinfo = zinfo_or_arcname
00086 
00087     # Now to the point why we overwrote this in the first place,
00088     # remember the entry numbers if we already had this entry.
00089     # Optimizations:
00090     # If the entry to overwrite is the last one, just reuse that.
00091     # If we store uncompressed and the new content has the same size
00092     # as the old, reuse the existing entry.
00093 
00094     doSeek = False # store if we need to seek to the eof after overwriting
00095     if self.NameToInfo.has_key(zinfo.filename):
00096       # Find the last ZipInfo with our name.
00097       # Last, because that's catching multiple overwrites
00098       i = len(self.filelist)
00099       while i > 0:
00100         i -= 1
00101         if self.filelist[i].filename == zinfo.filename:
00102           break
00103       zi = self.filelist[i]
00104       if ((zinfo.compress_type == zipfile.ZIP_STORED
00105            and zi.compress_size == len(bytes))
00106           or (i + 1) == len(self.filelist)):
00107         # make sure we're allowed to write, otherwise done by writestr below
00108         self._writecheck(zi)
00109         # overwrite existing entry
00110         self.fp.seek(zi.header_offset)
00111         if (i + 1) == len(self.filelist):
00112           # this is the last item in the file, just truncate
00113           self.fp.truncate()
00114         else:
00115           # we need to move to the end of the file afterwards again
00116           doSeek = True
00117         # unhook the current zipinfo, the writestr of our superclass
00118         # will add a new one
00119         self.filelist.pop(i)
00120         self.NameToInfo.pop(zinfo.filename)
00121       else:
00122         # Couldn't optimize, sadly, just remember the old entry for removal
00123         self._remove.append(self.filelist.pop(i))
00124     zipfile.ZipFile.writestr(self, zinfo, bytes)
00125     self.filelist.sort(lambda l, r: cmp(l.header_offset, r.header_offset))
00126     if doSeek:
00127       self.fp.seek(self.end)
00128     self.end = self.fp.tell()


Member Data Documentation

Definition at line 66 of file MozZipFile.py.

Definition at line 68 of file MozZipFile.py.

Definition at line 67 of file MozZipFile.py.

Definition at line 144 of file MozZipFile.py.

Definition at line 55 of file MozZipFile.py.


The documentation for this class was generated from the following file: