calculate any direction with transfer-time, also reformat
This commit is contained in:
@@ -1,9 +1,9 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
import datetime
|
import datetime
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
def is_digit(d):
|
def is_digit(d):
|
||||||
@@ -56,24 +56,39 @@ def get_numerical(num_string):
|
|||||||
|
|
||||||
def parse_options():
|
def parse_options():
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description="Transfer time calculator",
|
description="Transfer time calculator. Two arguments only! The third is calculated.",
|
||||||
epilog="You may omit the 'b' to time events. ex. '20 minutes / task, 7 tasks to do': %(prog)s 3/h 7",
|
epilog="You may omit the 'b' to time events. ex. '20 minutes / task, 7 tasks to do': %(prog)s 3/h 7",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
|
"--rate",
|
||||||
"-r",
|
"-r",
|
||||||
dest="rate",
|
help="Rate: inverse of speed. ex: 0.1s/b",
|
||||||
help="Rate: inverse of speed. Instead of 10b/s, write 0.1s/b",
|
action="store",
|
||||||
action="store_true",
|
default=None,
|
||||||
default=False,
|
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"speed", help="Speed of transfer (ex. 3.2Mb/s). Time units: s, m, h, d, w"
|
"--speed", "-v", help="Speed of transfer (ex. 3.2Mb/s). Time units: s, m, h, d, w", default=None
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"size",
|
"--size",
|
||||||
|
"-s",
|
||||||
help="Data size (ex. 4.55GB), or folder/file path. Units: b, kb, mb, gb, tb, pb or kib, mib ... ",
|
help="Data size (ex. 4.55GB), or folder/file path. Units: b, kb, mb, gb, tb, pb or kib, mib ... ",
|
||||||
|
default=None,
|
||||||
)
|
)
|
||||||
return parser.parse_args()
|
parser.add_argument(
|
||||||
|
"--time", "-t", help="Time used to transfer Units: s,m,h,d or [dd]:[hh]:[mm]:[ss].[ss]... ", default=None
|
||||||
|
)
|
||||||
|
parsed = parser.parse_args()
|
||||||
|
if parsed.rate and parsed.speed:
|
||||||
|
parser.error("Can't use both rate and speed")
|
||||||
|
|
||||||
|
if (
|
||||||
|
sum((int(parsed.speed is None and parsed.rate is None), int(parsed.time is None), int(parsed.size is None)))
|
||||||
|
!= 1
|
||||||
|
):
|
||||||
|
parser.error("Exactly two measures required")
|
||||||
|
|
||||||
|
return parsed
|
||||||
|
|
||||||
|
|
||||||
def parse_rate(rate_string):
|
def parse_rate(rate_string):
|
||||||
@@ -124,24 +139,24 @@ def parse_size(size_string):
|
|||||||
if multiplier_part == "kb":
|
if multiplier_part == "kb":
|
||||||
return 1024 * numerical_part
|
return 1024 * numerical_part
|
||||||
if multiplier_part == "mb":
|
if multiplier_part == "mb":
|
||||||
return 1024 ** 2 * numerical_part
|
return 1024**2 * numerical_part
|
||||||
if multiplier_part == "gb":
|
if multiplier_part == "gb":
|
||||||
return 1024 ** 3 * numerical_part
|
return 1024**3 * numerical_part
|
||||||
if multiplier_part == "tb":
|
if multiplier_part == "tb":
|
||||||
return 1024 ** 4 * numerical_part
|
return 1024**4 * numerical_part
|
||||||
if multiplier_part == "pb":
|
if multiplier_part == "pb":
|
||||||
return 1024 ** 5 * numerical_part
|
return 1024**5 * numerical_part
|
||||||
|
|
||||||
if multiplier_part == "kib":
|
if multiplier_part == "kib":
|
||||||
return 1000 * numerical_part
|
return 1000 * numerical_part
|
||||||
if multiplier_part == "mib":
|
if multiplier_part == "mib":
|
||||||
return 1000 ** 2 * numerical_part
|
return 1000**2 * numerical_part
|
||||||
if multiplier_part == "gib":
|
if multiplier_part == "gib":
|
||||||
return 1000 ** 3 * numerical_part
|
return 1000**3 * numerical_part
|
||||||
if multiplier_part == "tib":
|
if multiplier_part == "tib":
|
||||||
return 1000 ** 4 * numerical_part
|
return 1000**4 * numerical_part
|
||||||
if multiplier_part == "pib":
|
if multiplier_part == "pib":
|
||||||
return 1000 ** 5 * numerical_part
|
return 1000**5 * numerical_part
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -160,7 +175,6 @@ def parse_speed(speed_string):
|
|||||||
|
|
||||||
if divider_string == "s":
|
if divider_string == "s":
|
||||||
return divisor
|
return divisor
|
||||||
|
|
||||||
if divider_string == "m":
|
if divider_string == "m":
|
||||||
return divisor / 60
|
return divisor / 60
|
||||||
if divider_string == "h":
|
if divider_string == "h":
|
||||||
@@ -171,41 +185,97 @@ def parse_speed(speed_string):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def parse_time(time_string):
|
||||||
|
"""Return in seconds"""
|
||||||
|
if ":" in time_string:
|
||||||
|
split_time = time_string.split(":")
|
||||||
|
if len(split_time) > 0:
|
||||||
|
s = float(split_time.pop())
|
||||||
|
if len(split_time) > 0:
|
||||||
|
s += 60 * float(split_time.pop())
|
||||||
|
if len(split_time) > 0:
|
||||||
|
s += 60 * 60 * float(split_time.pop())
|
||||||
|
if len(split_time) > 0:
|
||||||
|
s += 24 * 60 * 60 * float(split_time.pop())
|
||||||
|
if len(split_time) > 0:
|
||||||
|
raise ValueError("Too many digits in time string")
|
||||||
|
return s
|
||||||
|
|
||||||
|
if is_numerical(time_string):
|
||||||
|
return float(time_string)
|
||||||
|
|
||||||
|
value = float(time_string[0:-1])
|
||||||
|
unit = time_string[-1]
|
||||||
|
|
||||||
|
if unit == "s":
|
||||||
|
return value
|
||||||
|
if unit == "m":
|
||||||
|
return 60 * value
|
||||||
|
if unit == "h":
|
||||||
|
return 60 * 60 * value
|
||||||
|
if unit == "d":
|
||||||
|
return 24 * 60 * 60 * value
|
||||||
|
if unit == "w":
|
||||||
|
return 7 * 24 * 60 * 60 * value
|
||||||
|
if unit == "y":
|
||||||
|
return 365 * 24 * 60 * 60 * value
|
||||||
|
|
||||||
|
raise ValueError("Can't parse time unit")
|
||||||
|
|
||||||
|
|
||||||
def print_err(s):
|
def print_err(s):
|
||||||
sys.stderr.write(str(s) + "\n")
|
sys.stderr.write(str(s) + "\n")
|
||||||
sys.stderr.flush()
|
sys.stderr.flush()
|
||||||
|
|
||||||
|
|
||||||
def time_human(num):
|
def time_human(seconds):
|
||||||
return str(datetime.timedelta(seconds=num))
|
return str(datetime.timedelta(seconds=seconds))
|
||||||
|
|
||||||
|
|
||||||
|
def size_human(size, precision=1):
|
||||||
|
if size == None:
|
||||||
|
return "nan"
|
||||||
|
suffixes = ["B", "KB", "MB", "GB", "TB", "PB"]
|
||||||
|
suffixIndex = 0
|
||||||
|
defPrecision = 0
|
||||||
|
while size > 1024:
|
||||||
|
suffixIndex += 1 # increment the index of the suffix
|
||||||
|
size = float(size / 1024.0) # apply the division
|
||||||
|
defPrecision = precision
|
||||||
|
return "%.*f%s" % (defPrecision, size, suffixes[suffixIndex])
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
opts = parse_options()
|
opts = parse_options()
|
||||||
|
speed, size, time = (None, None, None)
|
||||||
|
|
||||||
if opts.rate:
|
if opts.rate is not None:
|
||||||
speed = parse_rate(opts.speed.lower())
|
speed = parse_rate(opts.rate.lower())
|
||||||
if speed == None:
|
if speed is None:
|
||||||
print_err("Cannot parse rate ( ex. 3.5s/kb )")
|
raise ValueError("Cannot parse rate ( ex. 3.5s/kb ), Rate: %s" % (opts.speed,))
|
||||||
print_err("Rate: %s" % (opts.speed,))
|
|
||||||
sys.exit(1)
|
if opts.speed is not None:
|
||||||
else:
|
|
||||||
speed = parse_speed(opts.speed.lower())
|
speed = parse_speed(opts.speed.lower())
|
||||||
if speed == None:
|
if speed is None:
|
||||||
print_err("Cannot parse speed ( ex. 3.5Mb/s )")
|
raise ValueError("Cannot parse speed ( ex. 3.5Mb/s ), Speed: %s" % (opts.speed,))
|
||||||
print_err("Speed: %s" % (opts.speed,))
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
if os.path.isfile(opts.size):
|
if opts.size is not None:
|
||||||
size = get_files_size(opts.size)
|
if os.path.exists(opts.size):
|
||||||
else:
|
size = get_files_size(opts.size)
|
||||||
size = parse_size(opts.size.lower())
|
else:
|
||||||
|
size = parse_size(opts.size.lower())
|
||||||
|
|
||||||
if size == None:
|
if size is None:
|
||||||
print_err(
|
raise ValueError(
|
||||||
"Cannot parse size, and it's not a path either ( ex. 11Gb / file.name )"
|
"Cannot parse size, and it's not a path either ( ex. 11Gb / file.name ), Size: %s" % (opts.size,)
|
||||||
)
|
)
|
||||||
print_err("Size: %s" % (opts.size,))
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
print(time_human(round(size / speed)))
|
if opts.time is not None:
|
||||||
|
time = parse_time(opts.time.lower())
|
||||||
|
|
||||||
|
if time is None:
|
||||||
|
print(f"Transfer time: {time_human(round(size / speed))}")
|
||||||
|
if size is None:
|
||||||
|
print(f"Transferred size: {size_human(speed * time)}")
|
||||||
|
if speed is None:
|
||||||
|
print(f"Transfer speed: {size_human(size/time)}/s")
|
||||||
|
|||||||
Reference in New Issue
Block a user