Files
cmg-commands/cmg-split-zip-smaller-chunks.py
2024-12-21 10:14:06 -06:00

120 lines
4.4 KiB
Python
Executable File

#!/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)