mirror of
https://github.com/markqvist/Reticulum.git
synced 2024-11-26 15:30:18 +00:00
Merge acd893a6e6
into dae40f2684
This commit is contained in:
commit
1aa3a0230a
@ -37,26 +37,48 @@ SIG_EXT = "rsg"
|
||||
ENCRYPT_EXT = "rfe"
|
||||
CHUNK_SIZE = 16*1024*1024
|
||||
|
||||
def spin(until=None, msg=None, timeout=None):
|
||||
|
||||
def spin(until=None, msg="", timeout=None):
|
||||
i = 0
|
||||
syms = "⢄⢂⢁⡁⡈⡐⡠"
|
||||
if timeout != None:
|
||||
if timeout is not None:
|
||||
timeout = time.time()+timeout
|
||||
|
||||
print(msg+" ", end=" ")
|
||||
while (timeout == None or time.time()<timeout) and not until():
|
||||
print(msg, end=" ")
|
||||
while (timeout is None or time.time()<timeout) and not until():
|
||||
time.sleep(0.1)
|
||||
print(("\b\b"+syms[i]+" "), end="")
|
||||
print(("\b\b", syms[i]), end=" ", sep="")
|
||||
sys.stdout.flush()
|
||||
i = (i+1)%len(syms)
|
||||
|
||||
print("\r"+" "*len(msg)+" \r", end="")
|
||||
print("\r", *len(msg), "\r", end="", sep="")
|
||||
|
||||
if timeout != None and time.time() > timeout:
|
||||
if timeout is not None and time.time() > timeout:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
def get_keys(args: argparse.Namespace, identity) -> None:
|
||||
"""Get public or/and private keys"""
|
||||
|
||||
if args.base64:
|
||||
RNS.log("Public Key : " + base64.urlsafe_b64encode(identity.get_public_key()).decode("utf-8"))
|
||||
elif args.base32:
|
||||
RNS.log("Public Key : " + base64.b32encode(identity.get_public_key()).decode("utf-8"))
|
||||
else:
|
||||
RNS.log("Public Key : " + RNS.hexrep(identity.get_public_key(), delimit=False))
|
||||
if identity.prv:
|
||||
if args.print_private:
|
||||
if args.base64:
|
||||
RNS.log("Private Key : " + base64.urlsafe_b64encode(identity.get_private_key()).decode("utf-8"))
|
||||
elif args.base32:
|
||||
RNS.log("Private Key : " + base64.b32encode(identity.get_private_key()).decode("utf-8"))
|
||||
else:
|
||||
RNS.log("Private Key : " + RNS.hexrep(identity.get_private_key(), delimit=False))
|
||||
else:
|
||||
RNS.log("Private Key : Hidden")
|
||||
|
||||
def main():
|
||||
try:
|
||||
parser = argparse.ArgumentParser(description="Reticulum Identity & Encryption Utility")
|
||||
@ -96,11 +118,7 @@ def main():
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
ops = 0;
|
||||
for t in [args.encrypt, args.decrypt, args.validate, args.sign]:
|
||||
if t:
|
||||
ops += 1
|
||||
|
||||
ops = sum(1 for t in [args.encrypt, args.decrypt, args.validate, args.sign] if t)
|
||||
if ops > 1:
|
||||
RNS.log("This utility currently only supports one of the encrypt, decrypt, sign or verify operations per invocation", RNS.LOG_ERROR)
|
||||
exit(1)
|
||||
@ -134,22 +152,8 @@ def main():
|
||||
exit(42)
|
||||
|
||||
RNS.log("Identity imported")
|
||||
if args.base64:
|
||||
RNS.log("Public Key : "+base64.urlsafe_b64encode(identity.get_public_key()).decode("utf-8"))
|
||||
elif args.base32:
|
||||
RNS.log("Public Key : "+base64.b32encode(identity.get_public_key()).decode("utf-8"))
|
||||
else:
|
||||
RNS.log("Public Key : "+RNS.hexrep(identity.get_public_key(), delimit=False))
|
||||
if identity.prv:
|
||||
if args.print_private:
|
||||
if args.base64:
|
||||
RNS.log("Private Key : "+base64.urlsafe_b64encode(identity.get_private_key()).decode("utf-8"))
|
||||
elif args.base32:
|
||||
RNS.log("Private Key : "+base64.b32encode(identity.get_private_key()).decode("utf-8"))
|
||||
else:
|
||||
RNS.log("Private Key : "+RNS.hexrep(identity.get_private_key(), delimit=False))
|
||||
else:
|
||||
RNS.log("Private Key : Hidden")
|
||||
|
||||
get_keys(args, identity)
|
||||
|
||||
if args.write:
|
||||
try:
|
||||
@ -208,7 +212,7 @@ def main():
|
||||
destination_hash = bytes.fromhex(identity_str)
|
||||
identity = RNS.Identity.recall(destination_hash)
|
||||
|
||||
if identity == None:
|
||||
if identity is None:
|
||||
if not args.request:
|
||||
RNS.log("Could not recall Identity for "+RNS.prettyhexrep(destination_hash)+".", RNS.LOG_ERROR)
|
||||
RNS.log("You can query the network for unknown Identities with the -R option.", RNS.LOG_ERROR)
|
||||
@ -216,7 +220,7 @@ def main():
|
||||
else:
|
||||
RNS.Transport.request_path(destination_hash)
|
||||
def spincheck():
|
||||
return RNS.Identity.recall(destination_hash) != None
|
||||
return RNS.Identity.recall(destination_hash) is not None
|
||||
spin(spincheck, "Requesting unknown Identity for "+RNS.prettyhexrep(destination_hash), args.t)
|
||||
|
||||
if not spincheck():
|
||||
@ -224,17 +228,15 @@ def main():
|
||||
exit(6)
|
||||
else:
|
||||
identity = RNS.Identity.recall(destination_hash)
|
||||
RNS.log("Received Identity "+str(identity)+" for destination "+RNS.prettyhexrep(destination_hash)+" from the network")
|
||||
RNS.log(" ".join(["Received Identity", str(identity), "for destination", RNS.prettyhexrep(destination_hash), "from the network"]))
|
||||
|
||||
else:
|
||||
RNS.log("Recalled Identity "+str(identity)+" for destination "+RNS.prettyhexrep(destination_hash))
|
||||
|
||||
RNS.log(" ".join(["Recalled Identity", str(identity), "for destination", RNS.prettyhexrep(destination_hash)]))
|
||||
|
||||
except Exception as e:
|
||||
RNS.log("Invalid hexadecimal hash provided", RNS.LOG_ERROR)
|
||||
exit(7)
|
||||
|
||||
|
||||
else:
|
||||
# Try loading Identity from file
|
||||
if not os.path.isfile(identity_str):
|
||||
@ -243,13 +245,13 @@ def main():
|
||||
else:
|
||||
try:
|
||||
identity = RNS.Identity.from_file(identity_str)
|
||||
RNS.log("Loaded Identity "+str(identity)+" from "+str(identity_str))
|
||||
RNS.log(" ".join(["Loaded Identity", str(identity), "from", str(identity_str)]))
|
||||
|
||||
except Exception as e:
|
||||
RNS.log("Could not decode Identity from specified file")
|
||||
exit(9)
|
||||
|
||||
if identity != None:
|
||||
if identity is not None:
|
||||
if args.hash:
|
||||
try:
|
||||
aspects = args.hash.split(".")
|
||||
@ -259,9 +261,9 @@ def main():
|
||||
else:
|
||||
app_name = aspects[0]
|
||||
aspects = aspects[1:]
|
||||
if identity.pub != None:
|
||||
if identity.pub is not None:
|
||||
destination = RNS.Destination(identity, RNS.Destination.OUT, RNS.Destination.SINGLE, app_name, *aspects)
|
||||
RNS.log("The "+str(args.hash)+" destination for this Identity is "+RNS.prettyhexrep(destination.hash))
|
||||
RNS.log(" ".join(["The", str(args.hash), "destination for this Identity is", RNS.prettyhexrep(destination.hash)]))
|
||||
RNS.log("The full destination specifier is "+str(destination))
|
||||
time.sleep(0.25)
|
||||
exit(0)
|
||||
@ -282,7 +284,7 @@ def main():
|
||||
else:
|
||||
app_name = aspects[0]
|
||||
aspects = aspects[1:]
|
||||
if identity.prv != None:
|
||||
if identity.prv is not None:
|
||||
destination = RNS.Destination(identity, RNS.Destination.IN, RNS.Destination.SINGLE, app_name, *aspects)
|
||||
RNS.log("Created destination "+str(destination))
|
||||
RNS.log("Announcing destination "+RNS.prettyhexrep(destination.hash))
|
||||
@ -291,7 +293,7 @@ def main():
|
||||
exit(0)
|
||||
else:
|
||||
destination = RNS.Destination(identity, RNS.Destination.OUT, RNS.Destination.SINGLE, app_name, *aspects)
|
||||
RNS.log("The "+str(args.announce)+" destination for this Identity is "+RNS.prettyhexrep(destination.hash))
|
||||
RNS.log(" ".join(["The", str(args.announce), "destination for this Identity is", RNS.prettyhexrep(destination.hash)]))
|
||||
RNS.log("The full destination specifier is "+str(destination))
|
||||
RNS.log("Cannot announce this destination, since the private key is not held")
|
||||
time.sleep(0.25)
|
||||
@ -303,22 +305,7 @@ def main():
|
||||
exit(0)
|
||||
|
||||
if args.print_identity:
|
||||
if args.base64:
|
||||
RNS.log("Public Key : "+base64.urlsafe_b64encode(identity.get_public_key()).decode("utf-8"))
|
||||
elif args.base32:
|
||||
RNS.log("Public Key : "+base64.b32encode(identity.get_public_key()).decode("utf-8"))
|
||||
else:
|
||||
RNS.log("Public Key : "+RNS.hexrep(identity.get_public_key(), delimit=False))
|
||||
if identity.prv:
|
||||
if args.print_private:
|
||||
if args.base64:
|
||||
RNS.log("Private Key : "+base64.urlsafe_b64encode(identity.get_private_key()).decode("utf-8"))
|
||||
elif args.base32:
|
||||
RNS.log("Private Key : "+base64.b32encode(identity.get_private_key()).decode("utf-8"))
|
||||
else:
|
||||
RNS.log("Private Key : "+RNS.hexrep(identity.get_private_key(), delimit=False))
|
||||
else:
|
||||
RNS.log("Private Key : Hidden")
|
||||
get_keys(args, identity)
|
||||
exit(0)
|
||||
|
||||
if args.export:
|
||||
@ -373,7 +360,7 @@ def main():
|
||||
if args.decrypt and not args.write and not args.stdout and args.read and args.read.lower().endswith("."+ENCRYPT_EXT):
|
||||
args.write = str(args.read).replace("."+ENCRYPT_EXT, "")
|
||||
|
||||
if args.sign and identity.prv == None:
|
||||
if args.sign and identity.prv is None:
|
||||
RNS.log("Specified Identity does not hold a private key. Cannot sign.", RNS.LOG_ERROR)
|
||||
exit(14)
|
||||
|
||||
@ -399,7 +386,7 @@ def main():
|
||||
# data_output = sys.stdout
|
||||
|
||||
if args.sign:
|
||||
if identity.prv == None:
|
||||
if identity.prv is None:
|
||||
RNS.log("Specified Identity does not hold a private key. Cannot sign.", RNS.LOG_ERROR)
|
||||
exit(16)
|
||||
|
||||
@ -423,7 +410,7 @@ def main():
|
||||
|
||||
if not args.stdout:
|
||||
if args.read:
|
||||
RNS.log("File "+str(args.read)+" signed with "+str(identity)+" to "+str(args.write))
|
||||
RNS.log(" ".join([ "File", str(args.read), "signed with", str(identity), "to", str(args.write) ]))
|
||||
exit(0)
|
||||
|
||||
except Exception as e:
|
||||
@ -457,18 +444,17 @@ def main():
|
||||
RNS.log("The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||
exit(21)
|
||||
|
||||
|
||||
validated = identity.validate(sig_input.read(), data_input.read())
|
||||
sig_input.close()
|
||||
data_input.close()
|
||||
|
||||
if not validated:
|
||||
if not args.stdout:
|
||||
RNS.log("Signature "+str(args.validate)+" for file "+str(args.read)+" is invalid", RNS.LOG_ERROR)
|
||||
RNS.log(" ".join(["Signature", str(args.validate), "for file", str(args.read), "is invalid"]), RNS.LOG_ERROR)
|
||||
exit(22)
|
||||
else:
|
||||
if not args.stdout:
|
||||
RNS.log("Signature "+str(args.validate)+" for file "+str(args.read)+" made by Identity "+str(identity)+" is valid")
|
||||
RNS.log(" ".join(["Signature", str(args.validate), "for file", str(args.read), "made by Identity", str(identity), "is valid"]))
|
||||
exit(0)
|
||||
|
||||
except Exception as e:
|
||||
@ -511,7 +497,7 @@ def main():
|
||||
data_input.close()
|
||||
if not args.stdout:
|
||||
if args.read:
|
||||
RNS.log("File "+str(args.read)+" encrypted for "+str(identity)+" to "+str(args.write))
|
||||
RNS.log(" ".join(["File", str(args.read), "encrypted for", str(identity), "to", str(args.write)]))
|
||||
exit(0)
|
||||
|
||||
except Exception as e:
|
||||
@ -529,7 +515,7 @@ def main():
|
||||
exit(26)
|
||||
|
||||
if args.decrypt:
|
||||
if identity.prv == None:
|
||||
if identity.prv is None:
|
||||
RNS.log("Specified Identity does not hold a private key. Cannot decrypt.", RNS.LOG_ERROR)
|
||||
exit(27)
|
||||
|
||||
@ -544,7 +530,7 @@ def main():
|
||||
exit(29)
|
||||
|
||||
if not args.stdout:
|
||||
RNS.log("Decrypting "+str(args.read)+"...")
|
||||
RNS.log("".join(["Decrypting ", str(args.read), "..."]))
|
||||
|
||||
try:
|
||||
more_data = True
|
||||
@ -552,7 +538,7 @@ def main():
|
||||
chunk = data_input.read(CHUNK_SIZE)
|
||||
if chunk:
|
||||
plaintext = identity.decrypt(chunk)
|
||||
if plaintext == None:
|
||||
if plaintext is None:
|
||||
if not args.stdout:
|
||||
RNS.log("Data could not be decrypted with the specified Identity")
|
||||
exit(30)
|
||||
@ -564,7 +550,7 @@ def main():
|
||||
data_input.close()
|
||||
if not args.stdout:
|
||||
if args.read:
|
||||
RNS.log("File "+str(args.read)+" decrypted with "+str(identity)+" to "+str(args.write))
|
||||
RNS.log(" ".join(["File", str(args.read), "decrypted with", str(identity), "to", str(args.write)]))
|
||||
exit(0)
|
||||
|
||||
except Exception as e:
|
||||
@ -581,20 +567,10 @@ def main():
|
||||
pass
|
||||
exit(31)
|
||||
|
||||
if True:
|
||||
pass
|
||||
|
||||
elif False:
|
||||
pass
|
||||
|
||||
else:
|
||||
print("")
|
||||
parser.print_help()
|
||||
print("")
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("")
|
||||
exit(255)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -24,7 +24,6 @@
|
||||
|
||||
import RNS
|
||||
import argparse
|
||||
import time
|
||||
|
||||
from RNS._version import __version__
|
||||
|
||||
@ -38,9 +37,10 @@ def program_setup(configdir, verbosity = 0, quietness = 0, service = False):
|
||||
else:
|
||||
targetlogdest = RNS.LOG_STDOUT
|
||||
|
||||
reticulum = RNS.Reticulum(configdir=configdir, verbosity=targetverbosity, logdest=targetlogdest)
|
||||
RNS.Reticulum(configdir=configdir, verbosity=targetverbosity, logdest=targetlogdest)
|
||||
exit(0)
|
||||
|
||||
|
||||
def main():
|
||||
try:
|
||||
parser = argparse.ArgumentParser(description="Reticulum Distributed Identity Resolver")
|
||||
@ -49,17 +49,15 @@ def main():
|
||||
parser.add_argument('-q', '--quiet', action='count', default=0)
|
||||
parser.add_argument("--exampleconfig", action='store_true', default=False, help="print verbose configuration example to stdout and exit")
|
||||
parser.add_argument("--version", action="version", version="ir {version}".format(version=__version__))
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.exampleconfig:
|
||||
print(__example_rns_config__)
|
||||
exit()
|
||||
|
||||
configarg = None
|
||||
if args.config:
|
||||
configarg = args.config
|
||||
else:
|
||||
configarg = None
|
||||
|
||||
program_setup(configdir=configarg, verbosity=args.verbose, quietness=args.quiet)
|
||||
|
||||
@ -67,6 +65,7 @@ def main():
|
||||
print("")
|
||||
exit()
|
||||
|
||||
|
||||
__example_rns_config__ = '''# This is an example Identity Resolver file.
|
||||
'''
|
||||
|
||||
|
@ -27,6 +27,7 @@ import argparse
|
||||
|
||||
from RNS._version import __version__
|
||||
|
||||
|
||||
def size_str(num, suffix='B'):
|
||||
units = ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z']
|
||||
last_unit = 'Y'
|
||||
@ -46,6 +47,14 @@ def size_str(num, suffix='B'):
|
||||
|
||||
return "%.2f%s%s" % (num, last_unit, suffix)
|
||||
|
||||
|
||||
def convert_bytes_to_hex(value_obj):
|
||||
if isinstance(value_obj, bytes):
|
||||
return RNS.hexrep(value_obj, delimit=False)
|
||||
elif isinstance(value_obj, dict):
|
||||
return {key: convert_bytes_to_hex(value) for key, value in value_obj.items()}
|
||||
return value_obj
|
||||
|
||||
def program_setup(configdir, dispall=False, verbosity=0, name_filter=None, json=False, astats=False, sorting=None, sort_reverse=False):
|
||||
reticulum = RNS.Reticulum(configdir = configdir, loglevel = 3+verbosity)
|
||||
|
||||
@ -55,44 +64,37 @@ def program_setup(configdir, dispall=False, verbosity=0, name_filter=None, json=
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
if stats != None:
|
||||
if stats is None:
|
||||
print("Could not get RNS status")
|
||||
return
|
||||
|
||||
if json:
|
||||
import json
|
||||
for s in stats:
|
||||
if isinstance(stats[s], bytes):
|
||||
stats[s] = RNS.hexrep(stats[s], delimit=False)
|
||||
|
||||
if isinstance(stats[s], dict):
|
||||
for i in stats[s]:
|
||||
if isinstance(i, dict):
|
||||
for k in i:
|
||||
if isinstance(i[k], bytes):
|
||||
i[k] = RNS.hexrep(i[k], delimit=False)
|
||||
|
||||
for s, value in stats.items():
|
||||
stats[s] = convert_bytes_to_hex(value)
|
||||
print(json.dumps(stats))
|
||||
exit()
|
||||
|
||||
interfaces = stats["interfaces"]
|
||||
if sorting != None and isinstance(sorting, str):
|
||||
if sorting is not None and isinstance(sorting, str):
|
||||
sorting = sorting.lower()
|
||||
if sorting == "rate" or sorting == "bitrate":
|
||||
interfaces.sort(key=lambda i: i["bitrate"], reverse=not sort_reverse)
|
||||
if sorting == "rx":
|
||||
elif sorting == "rx":
|
||||
interfaces.sort(key=lambda i: i["rxb"], reverse=not sort_reverse)
|
||||
if sorting == "tx":
|
||||
elif sorting == "tx":
|
||||
interfaces.sort(key=lambda i: i["txb"], reverse=not sort_reverse)
|
||||
if sorting == "traffic":
|
||||
elif sorting == "traffic":
|
||||
interfaces.sort(key=lambda i: i["rxb"]+i["txb"], reverse=not sort_reverse)
|
||||
if sorting == "announces" or sorting == "announce":
|
||||
elif sorting == "announces" or sorting == "announce":
|
||||
interfaces.sort(key=lambda i: i["incoming_announce_frequency"]+i["outgoing_announce_frequency"], reverse=not sort_reverse)
|
||||
if sorting == "arx":
|
||||
elif sorting == "arx":
|
||||
interfaces.sort(key=lambda i: i["incoming_announce_frequency"], reverse=not sort_reverse)
|
||||
if sorting == "atx":
|
||||
elif sorting == "atx":
|
||||
interfaces.sort(key=lambda i: i["outgoing_announce_frequency"], reverse=not sort_reverse)
|
||||
if sorting == "held":
|
||||
elif sorting == "held":
|
||||
interfaces.sort(key=lambda i: i["held_announces"], reverse=not sort_reverse)
|
||||
|
||||
|
||||
for ifstat in interfaces:
|
||||
name = ifstat["name"]
|
||||
|
||||
@ -125,8 +127,7 @@ def program_setup(configdir, dispall=False, verbosity=0, name_filter=None, json=
|
||||
else:
|
||||
modestr = "Full"
|
||||
|
||||
|
||||
if ifstat["clients"] != None:
|
||||
if ifstat["clients"] is not None:
|
||||
clients = ifstat["clients"]
|
||||
if name.startswith("Shared Instance["):
|
||||
cnum = max(clients-1,0)
|
||||
@ -216,8 +217,6 @@ def program_setup(configdir, dispall=False, verbosity=0, name_filter=None, json=
|
||||
|
||||
print("")
|
||||
|
||||
else:
|
||||
print("Could not get RNS status")
|
||||
|
||||
def main():
|
||||
try:
|
||||
@ -292,6 +291,7 @@ def main():
|
||||
print("")
|
||||
exit()
|
||||
|
||||
|
||||
def speed_str(num, suffix='bps'):
|
||||
units = ['','k','M','G','T','P','E','Z']
|
||||
last_unit = 'Y'
|
||||
@ -308,5 +308,6 @@ def speed_str(num, suffix='bps'):
|
||||
|
||||
return "%.2f %s%s" % (num, last_unit, suffix)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
@ -28,7 +28,7 @@ import argparse
|
||||
import shlex
|
||||
import time
|
||||
import sys
|
||||
import tty
|
||||
# import tty # Commented this because commented lines below use it
|
||||
import os
|
||||
|
||||
from RNS._version import __version__
|
||||
@ -39,9 +39,10 @@ reticulum = None
|
||||
allow_all = False
|
||||
allowed_identity_hashes = []
|
||||
|
||||
|
||||
def prepare_identity(identity_path):
|
||||
global identity
|
||||
if identity_path == None:
|
||||
if identity_path is None:
|
||||
identity_path = RNS.Reticulum.identitypath+"/"+APP_NAME
|
||||
|
||||
if os.path.isfile(identity_path):
|
||||
@ -52,6 +53,7 @@ def prepare_identity(identity_path):
|
||||
identity = RNS.Identity()
|
||||
identity.to_file(identity_path)
|
||||
|
||||
|
||||
def listen(configdir, identitypath = None, verbosity = 0, quietness = 0, allowed = [], print_identity = False, disable_auth = None, disable_announce=False):
|
||||
global identity, allow_all, allowed_identity_hashes, reticulum
|
||||
|
||||
@ -69,7 +71,7 @@ def listen(configdir, identitypath = None, verbosity = 0, quietness = 0, allowed
|
||||
if disable_auth:
|
||||
allow_all = True
|
||||
else:
|
||||
if allowed != None:
|
||||
if allowed is not None:
|
||||
for a in allowed:
|
||||
try:
|
||||
dest_len = (RNS.Reticulum.TRUNCATED_HASHLENGTH//8)*2
|
||||
@ -297,6 +299,7 @@ def remote_execution_progress(request_receipt):
|
||||
link = None
|
||||
listener_destination = None
|
||||
remote_exec_grace = 2.0
|
||||
|
||||
def execute(configdir, identitypath = None, verbosity = 0, quietness = 0, detailed = False, mirror = False, noid = False, destination = None, command = None, stdin = None, stdoutl = None, stderrl = None, timeout = RNS.Transport.PATH_REQUEST_TIMEOUT, result_timeout = None, interactive = False):
|
||||
global identity, reticulum, link, listener_destination, remote_exec_grace
|
||||
|
||||
@ -548,7 +551,6 @@ def main():
|
||||
parser.add_argument("--stdout", action='store', default=None, help="max size in bytes of returned stdout", type=int)
|
||||
parser.add_argument("--stderr", action='store', default=None, help="max size in bytes of returned stderr", type=int)
|
||||
parser.add_argument("--version", action="version", version="rnx {version}".format(version=__version__))
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.listen or args.print_identity:
|
||||
@ -668,6 +670,7 @@ def size_str(num, suffix='B'):
|
||||
|
||||
return "%.2f%s%s" % (num, last_unit, suffix)
|
||||
|
||||
|
||||
def pretty_time(time, verbose=False):
|
||||
days = int(time // (24 * 3600))
|
||||
time = time % (24 * 3600)
|
||||
@ -684,31 +687,24 @@ def pretty_time(time, verbose=False):
|
||||
|
||||
components = []
|
||||
if days > 0:
|
||||
components.append(str(days)+" day"+sd if verbose else str(days)+"d")
|
||||
components.append("".join([str(days), " day", sd if verbose else str(days), "d"]))
|
||||
|
||||
if hours > 0:
|
||||
components.append(str(hours)+" hour"+sh if verbose else str(hours)+"h")
|
||||
components.append("".join([str(hours), " hour", sh if verbose else str(hours), "h"]))
|
||||
|
||||
if minutes > 0:
|
||||
components.append(str(minutes)+" minute"+sm if verbose else str(minutes)+"m")
|
||||
components.append("".join([str(minutes), " minute", sm if verbose else str(minutes), "m"]))
|
||||
|
||||
if seconds > 0:
|
||||
components.append(str(seconds)+" second"+ss if verbose else str(seconds)+"s")
|
||||
components.append("".join([str(seconds), " second", ss if verbose else str(seconds), "s"]))
|
||||
|
||||
i = 0
|
||||
tstr = ""
|
||||
for c in components:
|
||||
i += 1
|
||||
if i == 1:
|
||||
pass
|
||||
elif i < len(components):
|
||||
tstr += ", "
|
||||
elif i == len(components):
|
||||
tstr += " and "
|
||||
if len(components) > 1:
|
||||
time_string = "".join([", ".join(components[:-1]), " and ", components[-1]])
|
||||
else:
|
||||
time_string = components[0] if components else ""
|
||||
|
||||
tstr += c
|
||||
return time_string
|
||||
|
||||
return tstr
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
Loading…
Reference in New Issue
Block a user