1cb93a386Sopenharmony_ci#!/usr/bin/env python 2cb93a386Sopenharmony_ci# 3cb93a386Sopenharmony_ci# Copyright 2016 Google Inc. 4cb93a386Sopenharmony_ci# 5cb93a386Sopenharmony_ci# Use of this source code is governed by a BSD-style license that can be 6cb93a386Sopenharmony_ci# found in the LICENSE file. 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci 9cb93a386Sopenharmony_ci"""Utilities for zipping and unzipping files.""" 10cb93a386Sopenharmony_ci 11cb93a386Sopenharmony_ci 12cb93a386Sopenharmony_cifrom __future__ import print_function 13cb93a386Sopenharmony_ciimport fnmatch 14cb93a386Sopenharmony_ciimport ntpath 15cb93a386Sopenharmony_ciimport os 16cb93a386Sopenharmony_ciimport posixpath 17cb93a386Sopenharmony_ciimport zipfile 18cb93a386Sopenharmony_ci 19cb93a386Sopenharmony_ci 20cb93a386Sopenharmony_cidef filtered(names, to_skip): 21cb93a386Sopenharmony_ci """Filter the list of file or directory names.""" 22cb93a386Sopenharmony_ci rv = names[:] 23cb93a386Sopenharmony_ci for pattern in to_skip: 24cb93a386Sopenharmony_ci rv = [n for n in rv if not fnmatch.fnmatch(n, pattern)] 25cb93a386Sopenharmony_ci return rv 26cb93a386Sopenharmony_ci 27cb93a386Sopenharmony_ci 28cb93a386Sopenharmony_cidef zip(target_dir, zip_file, to_skip=None): # pylint: disable=W0622 29cb93a386Sopenharmony_ci """Zip the given directory, write to the given zip file.""" 30cb93a386Sopenharmony_ci if not os.path.isdir(target_dir): 31cb93a386Sopenharmony_ci raise IOError('%s does not exist!' % target_dir) 32cb93a386Sopenharmony_ci to_skip = to_skip or [] 33cb93a386Sopenharmony_ci with zipfile.ZipFile(zip_file, 'w', zipfile.ZIP_DEFLATED, True) as z: 34cb93a386Sopenharmony_ci for r, d, f in os.walk(target_dir, topdown=True): 35cb93a386Sopenharmony_ci d[:] = filtered(d, to_skip) 36cb93a386Sopenharmony_ci for filename in filtered(f, to_skip): 37cb93a386Sopenharmony_ci filepath = os.path.join(r, filename) 38cb93a386Sopenharmony_ci zi = zipfile.ZipInfo(filepath) 39cb93a386Sopenharmony_ci zi.filename = os.path.relpath(filepath, target_dir) 40cb93a386Sopenharmony_ci if os.name == 'nt': 41cb93a386Sopenharmony_ci # Dumb path separator replacement for Windows. 42cb93a386Sopenharmony_ci zi.filename = zi.filename.replace(ntpath.sep, posixpath.sep) 43cb93a386Sopenharmony_ci try: 44cb93a386Sopenharmony_ci perms = os.stat(filepath).st_mode 45cb93a386Sopenharmony_ci except OSError: 46cb93a386Sopenharmony_ci if os.path.islink(filepath): 47cb93a386Sopenharmony_ci print('Skipping symlink %s' % filepath) 48cb93a386Sopenharmony_ci continue 49cb93a386Sopenharmony_ci else: 50cb93a386Sopenharmony_ci raise 51cb93a386Sopenharmony_ci zi.external_attr = perms << 16 52cb93a386Sopenharmony_ci zi.compress_type = zipfile.ZIP_DEFLATED 53cb93a386Sopenharmony_ci with open(filepath, 'rb') as f: 54cb93a386Sopenharmony_ci content = f.read() 55cb93a386Sopenharmony_ci z.writestr(zi, content) 56cb93a386Sopenharmony_ci for dirname in d: 57cb93a386Sopenharmony_ci dirpath = os.path.join(r, dirname) 58cb93a386Sopenharmony_ci z.write(dirpath, os.path.relpath(dirpath, target_dir)) 59cb93a386Sopenharmony_ci 60cb93a386Sopenharmony_ci 61cb93a386Sopenharmony_cidef unzip(zip_file, target_dir): 62cb93a386Sopenharmony_ci """Unzip the given zip file into the target dir.""" 63cb93a386Sopenharmony_ci if not os.path.isdir(target_dir): 64cb93a386Sopenharmony_ci os.makedirs(target_dir) 65cb93a386Sopenharmony_ci with zipfile.ZipFile(zip_file, 'r', zipfile.ZIP_DEFLATED, True) as z: 66cb93a386Sopenharmony_ci for zi in z.infolist(): 67cb93a386Sopenharmony_ci dst_subpath = zi.filename 68cb93a386Sopenharmony_ci if os.name == 'nt': 69cb93a386Sopenharmony_ci # Dumb path separator replacement for Windows. 70cb93a386Sopenharmony_ci dst_subpath = dst_subpath.replace(posixpath.sep, ntpath.sep) 71cb93a386Sopenharmony_ci dst_path = os.path.join(target_dir, dst_subpath) 72cb93a386Sopenharmony_ci if dst_path.endswith(os.path.sep): 73cb93a386Sopenharmony_ci os.mkdir(dst_path) 74cb93a386Sopenharmony_ci else: 75cb93a386Sopenharmony_ci with open(dst_path, 'wb') as f: 76cb93a386Sopenharmony_ci f.write(z.read(zi)) 77cb93a386Sopenharmony_ci perms = zi.external_attr >> 16 78cb93a386Sopenharmony_ci os.chmod(dst_path, perms) 79