#!/usr/bin/python3 import zipfile import os from io import BytesIO import argparse def printProgressBar(iteration, total, prefix = '', suffix = '', decimals = 1, length = 100, fill = '█', printEnd = "\r"): """ As found in Stack Overflow answer: https://stackoverflow.com/a/34325723 Call in a loop to create terminal progress bar @params: iteration - Required : current iteration (Int) total - Required : total iterations (Int) prefix - Optional : prefix string (Str) suffix - Optional : suffix string (Str) decimals - Optional : positive number of decimals in percent complete (Int) length - Optional : character length of bar (Int) fill - Optional : bar fill character (Str) printEnd - Optional : end character (e.g. "\r", "\r\n") (Str) """ percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total))) filledLength = int(length * iteration // total) bar = fill * filledLength + '|' * (length - filledLength) print(f'\r{prefix} |{bar}| {percent}% {suffix}', end = printEnd) # Print New Line on Complete if iteration == total: print() def can_float(str): try: float(str) return True except ValueError: return False def get_max_size(): while True: mx_group_size = input("Enter the maximum (in GB) zipped file size (1.7 is default): ").strip() or "1.7" if can_float(mx_group_size): return float(mx_group_size) else: print(f"You did not enter a number. Please try again.") def get_zip_path(): while True: zip_path = input("Enter the path to the zipped file: ") if os.path.isfile(zip_path): return zip_path else: print(f"The file at {zip_path} does not exist. Please try again.") def split_zip(input_zip_path, output_folder, max_group_size): max_group_size = max_group_size * 1024 * 1024 * 1024 # Ensure the output folder exists base = os.path.basename(input_zip_path) file_name = os.path.splitext(base)[0] if not os.path.exists(output_folder): os.makedirs(output_folder) with zipfile.ZipFile(input_zip_path, 'r') as source_zip: members = source_zip.namelist() l = len(members) group_size = 0 group_number = 1 i = 1 printProgressBar(0, l, prefix = 'Progress:', suffix = 'Complete', length = 50) for member in members: i = i + 1 printProgressBar(i, l, prefix = 'Progress:', suffix = 'Complete', length = 50) # Read the file content from the zip archive with BytesIO(source_zip.read(member)) as file_content: # Check if adding this file would exceed the maximum group size if (group_size + len(file_content.getvalue())) > max_group_size: print(f'\nDone: {file_name}-group_{group_number}.zip ', end="\r") group_number += 1 print(f'\nNext: {file_name}-group_{group_number}.zip') group_size = 0 # i = 0 output_zip_path = os.path.join(output_folder, f'{file_name}-group_{group_number}.zip') with zipfile.ZipFile(output_zip_path, 'a') as target_zip: target_zip.writestr(member, file_content.getvalue()) # Update the size of the current group group_size += len(file_content.getvalue()) print(f'Successfully split {input_zip_path} into {group_number} groups.', end="\r") # Example usage # input_zip_path = 'path/to/your/large.zip' # Create an argument parser object parser = argparse.ArgumentParser(description='Check for a specific flag.') # Add a flag argument to the parser parser.add_argument('-s', '--group_size', help='Specify Group Size') parser.add_argument('-f', '--file_location', help='Specify File Location') # Parse the command-line arguments args = parser.parse_args() if args.group_size: mx_group_size = args.group_size if can_float(mx_group_size): max_group_size = float(mx_group_size) else: max_group_size = get_max_size() else: max_group_size = get_max_size() if args.file_location: input_zip_path = args.file_location else: input_zip_path = get_zip_path() output_folder = 'output' split_zip(input_zip_path, output_folder, max_group_size)