Create a Zip archive.

    Provide any of the following:
      files - A list of files
      path - A directory of .txt files
      clone - Copy any files from a zip archive not specified above

    Duplicate files will be ignored. The 'files' argument will be used first,
    then files found in the specified 'path', then in the
    specified 'clone' archive.

def make_zip(self, filename, files=None, path=None, clone=None, compress=True):
    """Create a Zip archive.

    Provide any of the following:
      files - A list of files
      path - A directory of .txt files
      clone - Copy any files from a zip archive not specified above

    Duplicate files will be ignored. The 'files' argument will be used first,
    then files found in the specified 'path', then in the
    specified 'clone' archive.
    """
    if filename and os.path.exists(filename):
      raise IOError('File exists: %s'%filename)
    files = files or []
    arcnames = []
    if path and os.path.isdir(path):
      files += glob.glob(os.path.join(path, '*.txt'))
    if compress:
      compress_level = zipfile.ZIP_DEFLATED
    else:
      compress_level = zipfile.ZIP_STORED

    # Write files.
    self.log("Creating zip archive: %s"%filename)
    zf = zipfile.ZipFile(filename, 'a', compression=compress_level)
    for f in files:
      base = os.path.basename(f)
      if base in arcnames:
        self.log('... skipping: %s'%f)
      else:
        self.log('... adding: %s'%f)
        arcnames.append(base)
        zf.write(f, base)

    # Clone from existing zip archive.
    if clone and os.path.exists(clone):
      zc = zipfile.ZipFile(clone)
      for f in zc.namelist():
        base = os.path.basename(f)
        if os.path.splitext(base)[-1] != '.txt':
          pass
          # self.log('... skipping from clone: %s'%f)
        elif base in arcnames:
          self.log('... skipping from clone: %s'%f)
        else:
          self.log('... adding from clone: %s'%f)
          arcnames.append(base)
          with zc.open(f) as i:
            data = i.read()
          zf.writestr(base, data)
    zf.close()