diff --git a/bin/transfer-speed b/bin/transfer-speed new file mode 120000 index 0000000..085c169 --- /dev/null +++ b/bin/transfer-speed @@ -0,0 +1 @@ +../web/transfer-speed \ No newline at end of file diff --git a/web/transfer-speed b/web/transfer-speed new file mode 100755 index 0000000..0701301 --- /dev/null +++ b/web/transfer-speed @@ -0,0 +1,145 @@ +#!/usr/bin/env python + +import argparse, sys, os +import datetime + +def is_digit(d): + try: + d = int(d) + return True + except ValueError: + return False + + +def is_numerical(f): + try: + f = float(f) + return True + except ValueError: + return False + + +def get_files_size(path): + + if not os.path.exists(path): + return None + + if os.path.isfile(path): + return float(os.path.getsize(path)) + + total_size = 0 + for dirpath, dirnames, filenames in os.walk(path): + for f in filenames: + fp = os.path.join(dirpath, f) + total_size += os.path.getsize(fp) + return float(total_size) + + +def parse_speed(speed_string): + + if not "/" in speed_string: + return None + + (divisor_string, divider_string) = speed_string.split("/", 1) + + divisor = parse_size(divisor_string) + if divisor == None: + # Cannot parse + return divisor + + if divider_string == "s": + return divisor + + if divider_string == "m": + return divisor / 60 + if divider_string == "h": + return divisor / 3600 + if divider_string == "d": + return divisor / (24 * 3600) + + return None + +def parse_options(): + parser = argparse.ArgumentParser(description='Transfer speed calculator') + parser.add_argument('speed', help = "Speed of transfer (ex. 3.2Mb/s). Time units: s, m, h, d, w") + parser.add_argument('size', help = "Data size (ex. 4.55GB), or folder/file path. Units: b, kb, mb, gb, tb, pb or kib, mib ... ") + return parser.parse_args() + + +def parse_size(size_string): + + size_string = size_string.lower() + numerical_part = '' + last_digit = 0 + for i,c in enumerate(size_string): + if is_digit(c): + last_digit = i + 1 + numerical_part = size_string[0:last_digit] + + + if not is_numerical(numerical_part): + return None + + numerical_part = float(numerical_part) + multiplier_part = size_string[last_digit:] + + if multiplier_part == "b": + return numerical_part + + if multiplier_part == "kb": + return 1024 * numerical_part + if multiplier_part == "mb": + return 1024**2 * numerical_part + if multiplier_part == "gb": + return 1024**3 * numerical_part + if multiplier_part == "tb": + return 1024**4 * numerical_part + if multiplier_part == "pb": + return 1024**5 * numerical_part + + if multiplier_part == "kib": + return 1000 * numerical_part + if multiplier_part == "mib": + return 1000**2 * numerical_part + if multiplier_part == "gib": + return 1000**3 * numerical_part + if multiplier_part == "tib": + return 1000**4 * numerical_part + if multiplier_part == "pib": + return 1000**5 * numerical_part + + return None + + +def print_err(s): + sys.stderr.write(str(s)+"\n") + sys.stderr.flush() + + +def time_human(num): + return str(datetime.timedelta(seconds = num)) + + +if __name__ == "__main__": + opts = parse_options() + + speed = parse_speed(opts.speed) + if speed == None: + print_err("Cannot parse speed ( ex. 3.5Mb/s )") + print_err("Speed: %s"%( opts.speed, )) + sys.exit(1) + + size = parse_size(opts.size) + + if size == None: + size = get_files_size(opts.size) + + if size == None: + print_err("Cannot parse size, and it's not a path either ( ex. 11Gb / file.name )") + print_err("Size: %s"%( opts.size, )) + sys.exit(1) + + print(time_human(round(size/speed))) + + +