File: C:/Users/fred/anaconda3/Lib/site-packages/anaconda_project/internal/ziputils.py
# -*- coding: utf-8 -*-
# -----------------------------------------------------------------------------
# Copyright (c) 2016, Anaconda, Inc. All rights reserved.
#
# Licensed under the terms of the BSD 3-Clause License.
# The full license is in the file LICENSE.txt, distributed with this software.
# -----------------------------------------------------------------------------
from __future__ import absolute_import, print_function
import os
import shutil
import tempfile
import zipfile
from anaconda_project.internal import rename
# we overwrite as long as the zip contains a file and target_path
# is a file, or the zip is a dir and target_path is a dir, but if
# they don't match we don't overwrite. Hopefully this will catch
# most mistaken collisions.
def unpack_zip(zip_path, target_path, errors):
try:
with zipfile.ZipFile(zip_path, mode='r') as zf:
target_dir, target_file = os.path.split(target_path)
tmp_dir = tempfile.mkdtemp(prefix=(target_path + "_tmp"), dir=target_dir)
try:
zf.extractall(tmp_dir)
extracted = os.listdir(tmp_dir)
if len(extracted) == 0:
errors.append("Zip archive was empty.")
return False
elif len(extracted) == 1 and extracted[0] == target_file:
# don't keep a pointless directory level, if
# the zip just contains a single directory or
# file with the same name as the target
src_path = os.path.join(tmp_dir, extracted[0])
else:
src_path = tmp_dir
src_is_dir = os.path.isdir(src_path)
target_is_dir = os.path.isdir(target_path)
if os.path.exists(target_path) and (src_is_dir != target_is_dir):
if src_is_dir:
errors.append("%s exists and isn't a directory, not unzipping a directory over it." %
target_path)
else:
errors.append("%s exists and is a directory, not unzipping a plain file over it." % target_path)
return False
else:
rename.rename_over_existing(src_path, target_path)
finally:
if os.path.isdir(tmp_dir):
shutil.rmtree(path=tmp_dir)
return True
except Exception as e:
errors.append("Failed to unzip %s: %s" % (zip_path, str(e)))
return False