diff --git a/aif/constants_fallback.py b/aif/constants_fallback.py index fcb1cf1..12de2c0 100644 --- a/aif/constants_fallback.py +++ b/aif/constants_fallback.py @@ -1,4 +1,4 @@ -import os +import hashlib import re import subprocess # I wish there was a better way to get the supported LUKS ciphers. import uuid @@ -287,3 +287,6 @@ MDADM_SUPPORTED_LAYOUTS = {5: (re.compile(r'^((left|right)-a?symmetric|[lr][as]| None)} # glibc doesn't support bcrypt/blowfish nor des (nor any of the others, like e.g. scrypt) CRYPT_SUPPORTED_HASHTYPES = ('sha512', 'sha256', 'md5') +HASH_BUILTIN_SUPPORTED_TYPES = tuple(sorted(list(hashlib.algorithms_available))) +HASH_EXTRA_SUPPORTED_TYPES = set(('adler32', 'crc32')) +HASH_SUPPORTED_TYPES = tuple(sorted(list(hashlib.algorithms_available.union(HASH_EXTRA_SUPPORTED_TYPES)))) diff --git a/aif/utils/file_handler.py b/aif/utils/file_handler.py index d10c699..4bfa239 100644 --- a/aif/utils/file_handler.py +++ b/aif/utils/file_handler.py @@ -9,6 +9,9 @@ class File(object): self.path_rel = pathlib.PurePosixPath(self.orig_path) self.path_full = pathlib.PurePosixPath(self.fullpath) + def __str(self): + return(self.fullpath) + class Directory(object): def __init__(self, dir_path): @@ -19,25 +22,35 @@ class Directory(object): self.files = [] self.dirs = [] - def populateFilesDirs(self, recursive = False): + def __str__(self): + return(self.fullpath) + + def populateFilesDirs(self, recursive = False, native = False): if not recursive: for i in os.listdir(self.fullpath): if os.path.isdir(os.path.join(self.fullpath, i)): self.dirs.append(i) elif os.path.isfile(os.path.join(self.fullpath, i)): - self.files.append(i) + if not native: + self.files.append(i) + else: + self.files.append(File(i)) else: for root, dirs, files in os.walk(self.fullpath): for f in files: fpath = os.path.join(root, f) - relfpath = pathlib.PurePosixPath(fpath).relative_to(self.path_full) - self.files.append(relfpath) + relfpath = str(pathlib.PurePosixPath(fpath).relative_to(self.path_full)) + if not native: + self.files.append(relfpath) + else: + self.files.append(relfpath) for d in dirs: dpath = os.path.join(root, d) - reldpath = pathlib.PurePosixPath(dpath).relative_to(self.path_full) + reldpath = str(pathlib.PurePosixPath(dpath).relative_to(self.path_full)) self.dirs.append(reldpath) if root not in self.dirs: - self.dirs.append(dirs) - self.dirs.sort() - self.files.sort() + self.dirs.append(root) + if not native: + self.dirs.sort() + self.files.sort() return(None) diff --git a/aif/utils/hash_handler.py b/aif/utils/hash_handler.py index e69de29..260569f 100644 --- a/aif/utils/hash_handler.py +++ b/aif/utils/hash_handler.py @@ -0,0 +1,48 @@ +import hashlib +import pathlib +import zlib +## +import aif.constants_fallback +from . import file_handler + + +class Hash(object): + def __init__(self, file_path): + self.hashers = None + + def configure(self, hashalgo = None): + self.hashers = {} + if hashalgo: + if not isinstance(hashalgo, list): + hashalgo = [hashalgo] + else: + hashalgo = list(aif.constants_fallback.HASH_SUPPORTED_TYPES) + for h in hashalgo: + if h not in aif.constants_fallback.HASH_SUPPORTED_TYPES: + raise ValueError('Hash algorithm not supported') + if h not in aif.constants_fallback.HASH_EXTRA_SUPPORTED_TYPES: + hasher = hashlib.new(h) + else: # adler32 and crc32 + hasher = getattr(zlib, h) + self.hashers[h] = hasher + return() + + def hashData(self, data): + results = {} + if not self.hashers: + self.configure() + for hashtype, hasher in self.hashers.items(): + if hashtype in aif.constants_fallback.HASH_EXTRA_SUPPORTED_TYPES: + results[hashtype] = hasher(data) + else: + rslt = hasher.update(data) + results[hashtype] = rslt.hexdigest() + return(results) + + def hashFile(self, file_path): + if not isinstance(file_path, (str, file_handler.File, pathlib.Path, pathlib.PurePath)): + raise ValueError('file_path must be a path expression') + file_path = str(file_path) + with open(file_path, 'rb') as fh: + results = self.hashData(fh.read()) + return(results)