diff options
Diffstat (limited to 'infra/bots/zip_utils.py')
-rw-r--r-- | infra/bots/zip_utils.py | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/infra/bots/zip_utils.py b/infra/bots/zip_utils.py new file mode 100644 index 0000000000..7f269b9e9b --- /dev/null +++ b/infra/bots/zip_utils.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python +# +# Copyright 2016 Google Inc. +# +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + + +"""Utilities for zipping and unzipping files.""" + + +import fnmatch +import os +import zipfile + + +def filtered(names, blacklist): + """Filter the list of file or directory names.""" + rv = names[:] + for pattern in blacklist: + rv = [n for n in rv if not fnmatch.fnmatch(n, pattern)] + return rv + + +def zip(target_dir, zip_file, blacklist=None): # pylint: disable=W0622 + """Zip the given directory, write to the given zip file.""" + if not os.path.isdir(target_dir): + raise IOError('%s does not exist!' % target_dir) + blacklist = blacklist or [] + with zipfile.ZipFile(zip_file, 'w') as z: + for r, d, f in os.walk(target_dir, topdown=True): + d[:] = filtered(d, blacklist) + for filename in filtered(f, blacklist): + filepath = os.path.join(r, filename) + zi = zipfile.ZipInfo(filepath) + zi.filename = os.path.relpath(filepath, target_dir) + perms = os.stat(filepath).st_mode + zi.external_attr = perms << 16L + zi.compress_type = zipfile.ZIP_STORED + with open(filepath, 'rb') as f: + content = f.read() + z.writestr(zi, content) + for dirname in d: + dirpath = os.path.join(r, dirname) + z.write(dirpath, os.path.relpath(dirpath, target_dir)) + + +def unzip(zip_file, target_dir): + """Unzip the given zip file into the target dir.""" + if not os.path.isdir(target_dir): + os.makedirs(target_dir) + with zipfile.ZipFile(zip_file, 'r') as z: + for zi in z.infolist(): + dst_path = os.path.join(target_dir, zi.filename) + if zi.filename.endswith('/'): + os.mkdir(dst_path) + else: + with open(dst_path, 'w') as f: + f.write(z.read(zi)) + perms = zi.external_attr >> 16L + os.chmod(dst_path, perms) |