|
Packit Service |
39273c |
#
|
|
Packit Service |
39273c |
# Copyright (C) 2013 Red Hat, Inc.
|
|
Packit Service |
39273c |
#
|
|
Packit Service |
39273c |
# This copyrighted material is made available to anyone wishing to use,
|
|
Packit Service |
39273c |
# modify, copy, or redistribute it subject to the terms and conditions of
|
|
Packit Service |
39273c |
# the GNU General Public License v.2, or (at your option) any later version.
|
|
Packit Service |
39273c |
# This program is distributed in the hope that it will be useful, but WITHOUT
|
|
Packit Service |
39273c |
# ANY WARRANTY expressed or implied, including the implied warranties of
|
|
Packit Service |
39273c |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
|
Packit Service |
39273c |
# Public License for more details. You should have received a copy of the
|
|
Packit Service |
39273c |
# GNU General Public License along with this program; if not, write to the
|
|
Packit Service |
39273c |
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
Packit Service |
39273c |
# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the
|
|
Packit Service |
39273c |
# source code or documentation are not subject to the GNU General Public
|
|
Packit Service |
39273c |
# License and may only be used or replicated with the express permission of
|
|
Packit Service |
39273c |
# Red Hat, Inc.
|
|
Packit Service |
39273c |
#
|
|
Packit Service |
39273c |
# Red Hat Author(s): Vratislav Podzimek <vpodzime@redhat.com>
|
|
Packit Service |
39273c |
#
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
"""Module with various utility functions used by the addon."""
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
import os
|
|
Packit Service |
39273c |
import os.path
|
|
Packit Service |
39273c |
import shutil
|
|
Packit Service |
39273c |
import glob
|
|
Packit Service |
39273c |
import hashlib
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
def ensure_dir_exists(dirpath):
|
|
Packit Service |
39273c |
"""
|
|
Packit Service |
39273c |
Checks if a given directory exists and if not, it creates the directory as
|
|
Packit Service |
39273c |
well as all the nonexisting directories in its path.
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
:param dirpath: path to the directory to be checked/created
|
|
Packit Service |
39273c |
:type dirpath: str
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
"""
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
if not dirpath:
|
|
Packit Service |
39273c |
# nothing can be done for an empty string
|
|
Packit Service |
39273c |
return
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
if not os.path.isdir(dirpath):
|
|
Packit Service |
39273c |
os.makedirs(dirpath)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
def universal_copy(src, dst):
|
|
Packit Service |
39273c |
"""
|
|
Packit Service |
39273c |
Function that copies the files or directories specified by the src argument
|
|
Packit Service |
39273c |
to the destination given by the dst argument. It should follow the same
|
|
Packit Service |
39273c |
rules as the standard 'cp' utility.
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
:param src: source to copy -- may be a glob, file path or a directory path
|
|
Packit Service |
39273c |
:type src: str
|
|
Packit Service |
39273c |
:param dst: destination to copy to
|
|
Packit Service |
39273c |
:type src: str
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
"""
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
if glob.has_magic(src):
|
|
Packit Service |
39273c |
# src is a glob
|
|
Packit Service |
39273c |
sources = glob.glob(src)
|
|
Packit Service |
39273c |
else:
|
|
Packit Service |
39273c |
# not a glob
|
|
Packit Service |
39273c |
sources = [src]
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
for item in sources:
|
|
Packit Service |
39273c |
if os.path.isdir(item):
|
|
Packit Service |
39273c |
if os.path.isdir(dst):
|
|
Packit Service |
39273c |
item = item.rstrip("/")
|
|
Packit Service |
39273c |
dirname = item.rsplit("/", 1)[-1]
|
|
Packit Service |
39273c |
shutil.copytree(item, join_paths(dst, dirname))
|
|
Packit Service |
39273c |
else:
|
|
Packit Service |
39273c |
shutil.copytree(item, dst)
|
|
Packit Service |
39273c |
else:
|
|
Packit Service |
39273c |
shutil.copy2(item, dst)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
def keep_type_map(func, iterable):
|
|
Packit Service |
39273c |
"""
|
|
Packit Service |
39273c |
Function that maps the given function to items in the given iterable
|
|
Packit Service |
39273c |
keeping the type of the iterable.
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
:param func: function to be mapped on the items in the iterable
|
|
Packit Service |
39273c |
:type func: in_item -> out_item
|
|
Packit Service |
39273c |
:param iterable: iterable providing the items the function should be mapped
|
|
Packit Service |
39273c |
on
|
|
Packit Service |
39273c |
:type iterable: iterable
|
|
Packit Service |
39273c |
:return: iterable providing items produced by the function mapped on the
|
|
Packit Service |
39273c |
input items
|
|
Packit Service |
39273c |
:rtype: the same type as input iterable or generator if the iterable is not
|
|
Packit Service |
39273c |
of any basic Python types
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
"""
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
if isinstance(iterable, dict):
|
|
Packit Service |
39273c |
return dict((func(key), iterable[key]) for key in iterable)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
items_gen = (func(item) for item in iterable)
|
|
Packit Service |
39273c |
if isinstance(iterable, list):
|
|
Packit Service |
39273c |
return list(items_gen)
|
|
Packit Service |
39273c |
elif isinstance(iterable, tuple):
|
|
Packit Service |
39273c |
if iterable.__class__ is tuple:
|
|
Packit Service |
39273c |
return tuple(items_gen)
|
|
Packit Service |
39273c |
else:
|
|
Packit Service |
39273c |
return iterable.__class__(*items_gen)
|
|
Packit Service |
39273c |
elif isinstance(iterable, set):
|
|
Packit Service |
39273c |
return set(items_gen)
|
|
Packit Service |
39273c |
elif isinstance(iterable, str):
|
|
Packit Service |
39273c |
return "".join(items_gen)
|
|
Packit Service |
39273c |
else:
|
|
Packit Service |
39273c |
return items_gen
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
def join_paths(path1, path2):
|
|
Packit Service |
39273c |
"""
|
|
Packit Service |
39273c |
Joins two paths as one would expect -- i.e. just like the os.path.join
|
|
Packit Service |
39273c |
function except for doing crazy things when the second argument is an
|
|
Packit Service |
39273c |
absolute path.
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
:param path1: first path
|
|
Packit Service |
39273c |
:type path1: str
|
|
Packit Service |
39273c |
:param path2: second path
|
|
Packit Service |
39273c |
:type path2: str
|
|
Packit Service |
39273c |
:return: path1 and path2 joined with the file separator
|
|
Packit Service |
39273c |
:rtype: str
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
"""
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
# os.path.normpath doesn't squash two starting slashes
|
|
Packit Service |
39273c |
path1.replace("//", "/")
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
return os.path.normpath(path1 + os.path.sep + path2)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
def get_hashing_algorithm(fingerprint):
|
|
Packit Service |
39273c |
"""
|
|
Packit Service |
39273c |
Get hashing algorithm for the given fingerprint or None if fingerprint of
|
|
Packit Service |
39273c |
unsupported length is given.
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
:param fingerprint: hexa fingerprint to get the hashing algorithm for
|
|
Packit Service |
39273c |
:type fingerprint: hexadecimal str
|
|
Packit Service |
39273c |
:return: one of the hashlib.* hash objects
|
|
Packit Service |
39273c |
:rtype: hashlib.HASH object
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
"""
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
hashes = (hashlib.md5(), hashlib.sha1(), hashlib.sha224(),
|
|
Packit Service |
39273c |
hashlib.sha256(), hashlib.sha384(), hashlib.sha512())
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
if len(fingerprint) % 2 == 1:
|
|
Packit Service |
39273c |
return None
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
num_bytes = len(fingerprint) / 2
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
for hash_obj in hashes:
|
|
Packit Service |
39273c |
# pylint: disable-msg=E1103
|
|
Packit Service |
39273c |
if hash_obj.digest_size == num_bytes:
|
|
Packit Service |
39273c |
return hash_obj
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
return None
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
def get_file_fingerprint(fpath, hash_obj):
|
|
Packit Service |
39273c |
"""
|
|
Packit Service |
39273c |
Get fingerprint of the given file with the given hashing algorithm.
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
:param fpath: path to the file to get fingerprint for
|
|
Packit Service |
39273c |
:type fpath: str
|
|
Packit Service |
39273c |
:param hash_obj: hashing algorithm to get fingerprint with
|
|
Packit Service |
39273c |
:type hash_obj: hashlib.HASH
|
|
Packit Service |
39273c |
:return: fingerprint of the given file with the given algorithm
|
|
Packit Service |
39273c |
:rtype: hexadecimal str
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
"""
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
with open(fpath, "rb") as fobj:
|
|
Packit Service |
39273c |
bsize = 4 * 1024
|
|
Packit Service |
39273c |
# process file as 4 KB blocks
|
|
Packit Service |
39273c |
buf = fobj.read(bsize)
|
|
Packit Service |
39273c |
while buf:
|
|
Packit Service |
39273c |
hash_obj.update(buf)
|
|
Packit Service |
39273c |
buf = fobj.read(bsize)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
return hash_obj.hexdigest()
|