import re import gzip from crypt import * class Backup: key = None compressMinSize = "50M" save_location = None def __init__(self, key): self.key = key def recurse(self, path): min_size = parse_size(self.compressMinSize) for f in os.listdir(path): uri = os.path.join(path, f) if os.path.isfile(uri): size = os.path.getsize(uri) print(f + " : ", human_size(size)) if size > min_size: enc = crypt(compress(uri), self.key) else: enc = crypt(uri, self.key) save(enc, os.path.join(self.save_location, f + ".enc")) elif os.path.isdir(uri): self.recurse(uri) def compress(file): if type(file) is str: infile = open(file, 'rb') elif type(file) is io.BufferedRandom or tempfile.SpooledTemporaryFile: file.seek(0) infile = file compressed_file = tempfile.SpooledTemporaryFile() with gzip.open(compressed_file, 'wb') as zipfile: while chunk := infile.read(64 * 1024): zipfile.write(chunk) return compressed_file def uncompress(file): if type(file) is io.BufferedRandom or tempfile.SpooledTemporaryFile: file.seek(0) decompressed_file = tempfile.SpooledTemporaryFile() with gzip.open(file, 'rb') as zipfile: while chunk := zipfile.read(64 * 1024): decompressed_file.write(chunk) return decompressed_file def crypt(file, key): encrypted_file = tempfile.SpooledTemporaryFile() encrypt_file(key, file, encrypted_file) return encrypted_file def uncrypt(file, key): decrypted_file = tempfile.SpooledTemporaryFile() decrypt_file(key, file, decrypted_file) return decrypted_file def save(file, name): if type(file) is io.BufferedRandom or tempfile.SpooledTemporaryFile: file.seek(0) with open(name, 'wb') as save: while chunk := file.read(64 * 1024): save.write(chunk) else: print("Unable to save " + str(file) + " of type " + str(type(file))) return def human_size(size, decimal_places=0): for unit in ['B', 'K', 'M', 'G', 'T']: if size < 1024.0: break size /= 1024.0 return f"{size:.{decimal_places}f}{unit}" def parse_size(size): units = {"B": 1, "K": 2**10, "M": 2**20, "G": 2**30, "T": 2**40} if size[-1].isdigit(): size = size + 'K' number, unit = re.match(r"([0-9]+)([BKMGT])", size, re.I).groups() return int(float(number)*units[unit])