Home | History | Annotate | Download | only in bots
      1 #!/usr/bin/env python
      2 #
      3 # Copyright 2016 Google Inc.
      4 #
      5 # Use of this source code is governed by a BSD-style license that can be
      6 # found in the LICENSE file.
      7 
      8 
      9 """Utilities for zipping and unzipping files."""
     10 
     11 
     12 import fnmatch
     13 import os
     14 import zipfile
     15 
     16 
     17 def filtered(names, blacklist):
     18   """Filter the list of file or directory names."""
     19   rv = names[:]
     20   for pattern in blacklist:
     21     rv = [n for n in rv if not fnmatch.fnmatch(n, pattern)]
     22   return rv
     23 
     24 
     25 def zip(target_dir, zip_file, blacklist=None):  # pylint: disable=W0622
     26   """Zip the given directory, write to the given zip file."""
     27   if not os.path.isdir(target_dir):
     28     raise IOError('%s does not exist!' % target_dir)
     29   blacklist = blacklist or []
     30   with zipfile.ZipFile(zip_file, 'w', zipfile.ZIP_DEFLATED, True) as z:
     31     for r, d, f in os.walk(target_dir, topdown=True):
     32       d[:] = filtered(d, blacklist)
     33       for filename in filtered(f, blacklist):
     34         filepath = os.path.join(r, filename)
     35         zi = zipfile.ZipInfo(filepath)
     36         zi.filename = os.path.relpath(filepath, target_dir)
     37         perms = os.stat(filepath).st_mode
     38         zi.external_attr = perms << 16L
     39         zi.compress_type = zipfile.ZIP_DEFLATED
     40         with open(filepath, 'rb') as f:
     41           content = f.read()
     42         z.writestr(zi, content)
     43       for dirname in d:
     44         dirpath = os.path.join(r, dirname)
     45         z.write(dirpath, os.path.relpath(dirpath, target_dir))
     46 
     47 
     48 def unzip(zip_file, target_dir):
     49   """Unzip the given zip file into the target dir."""
     50   if not os.path.isdir(target_dir):
     51     os.makedirs(target_dir)
     52   with zipfile.ZipFile(zip_file, 'r', zipfile.ZIP_DEFLATED, True) as z:
     53     for zi in z.infolist():
     54       dst_path = os.path.join(target_dir, zi.filename)
     55       if zi.filename.endswith('/'):
     56         os.mkdir(dst_path)
     57       else:
     58         with open(dst_path, 'wb') as f:
     59           f.write(z.read(zi))
     60       perms = zi.external_attr >> 16L
     61       os.chmod(dst_path, perms)
     62