mirror of
https://github.com/markqvist/Reticulum.git
synced 2025-05-02 06:36:14 -04:00
Indentation and formatting cleanup
This commit is contained in:
parent
e4dfd052e6
commit
bd098c338a
17 changed files with 4477 additions and 4477 deletions
|
@ -15,52 +15,52 @@ APP_NAME = "example_utilitites"
|
|||
|
||||
# This initialisation is executed when the program is started
|
||||
def program_setup(configpath, channel=None):
|
||||
# We must first initialise Reticulum
|
||||
reticulum = RNS.Reticulum(configpath)
|
||||
|
||||
# If the user did not select a "channel" we use
|
||||
# a default one called "public_information".
|
||||
# This "channel" is added to the destination name-
|
||||
# space, so the user can select different broadcast
|
||||
# channels.
|
||||
if channel == None:
|
||||
channel = "public_information"
|
||||
# We must first initialise Reticulum
|
||||
reticulum = RNS.Reticulum(configpath)
|
||||
|
||||
# If the user did not select a "channel" we use
|
||||
# a default one called "public_information".
|
||||
# This "channel" is added to the destination name-
|
||||
# space, so the user can select different broadcast
|
||||
# channels.
|
||||
if channel == None:
|
||||
channel = "public_information"
|
||||
|
||||
# We create a PLAIN destination. This is an uncencrypted endpoint
|
||||
# that anyone can listen to and send information to.
|
||||
broadcast_destination = RNS.Destination(None, RNS.Destination.IN, RNS.Destination.PLAIN, APP_NAME, "broadcast", channel)
|
||||
# We create a PLAIN destination. This is an uncencrypted endpoint
|
||||
# that anyone can listen to and send information to.
|
||||
broadcast_destination = RNS.Destination(None, RNS.Destination.IN, RNS.Destination.PLAIN, APP_NAME, "broadcast", channel)
|
||||
|
||||
# We specify a callback that will get called every time
|
||||
# the destination receives data.
|
||||
broadcast_destination.packet_callback(packet_callback)
|
||||
|
||||
# Everything's ready!
|
||||
# Let's hand over control to the main loop
|
||||
broadcastLoop(broadcast_destination)
|
||||
# We specify a callback that will get called every time
|
||||
# the destination receives data.
|
||||
broadcast_destination.packet_callback(packet_callback)
|
||||
|
||||
# Everything's ready!
|
||||
# Let's hand over control to the main loop
|
||||
broadcastLoop(broadcast_destination)
|
||||
|
||||
def packet_callback(data, packet):
|
||||
# Simply print out the received data
|
||||
print("")
|
||||
print("Received data: "+data.decode("utf-8")+"\r\n> ", end="")
|
||||
sys.stdout.flush()
|
||||
# Simply print out the received data
|
||||
print("")
|
||||
print("Received data: "+data.decode("utf-8")+"\r\n> ", end="")
|
||||
sys.stdout.flush()
|
||||
|
||||
def broadcastLoop(destination):
|
||||
# Let the user know that everything is ready
|
||||
RNS.log("Broadcast example "+RNS.prettyhexrep(destination.hash)+" running, enter text and hit enter to broadcast (Ctrl-C to quit)")
|
||||
# Let the user know that everything is ready
|
||||
RNS.log("Broadcast example "+RNS.prettyhexrep(destination.hash)+" running, enter text and hit enter to broadcast (Ctrl-C to quit)")
|
||||
|
||||
# We enter a loop that runs until the users exits.
|
||||
# If the user hits enter, we will send the information
|
||||
# that the user entered into the prompt.
|
||||
while True:
|
||||
print("> ", end="")
|
||||
entered = input()
|
||||
# We enter a loop that runs until the users exits.
|
||||
# If the user hits enter, we will send the information
|
||||
# that the user entered into the prompt.
|
||||
while True:
|
||||
print("> ", end="")
|
||||
entered = input()
|
||||
|
||||
if entered != "":
|
||||
data = entered.encode("utf-8")
|
||||
packet = RNS.Packet(destination, data)
|
||||
packet.send()
|
||||
|
||||
if entered != "":
|
||||
data = entered.encode("utf-8")
|
||||
packet = RNS.Packet(destination, data)
|
||||
packet.send()
|
||||
|
||||
|
||||
|
||||
##########################################################
|
||||
#### Program Startup #####################################
|
||||
|
@ -70,24 +70,24 @@ def broadcastLoop(destination):
|
|||
# and parses input from the user, and then starts
|
||||
# the program.
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
parser = argparse.ArgumentParser(description="Reticulum example that demonstrates sending and receiving unencrypted broadcasts")
|
||||
parser.add_argument("--config", action="store", default=None, help="path to alternative Reticulum config directory", type=str)
|
||||
parser.add_argument("--channel", action="store", default=None, help="path to alternative Reticulum config directory", type=str)
|
||||
args = parser.parse_args()
|
||||
try:
|
||||
parser = argparse.ArgumentParser(description="Reticulum example that demonstrates sending and receiving unencrypted broadcasts")
|
||||
parser.add_argument("--config", action="store", default=None, help="path to alternative Reticulum config directory", type=str)
|
||||
parser.add_argument("--channel", action="store", default=None, help="path to alternative Reticulum config directory", type=str)
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.config:
|
||||
configarg = args.config
|
||||
else:
|
||||
configarg = None
|
||||
if args.config:
|
||||
configarg = args.config
|
||||
else:
|
||||
configarg = None
|
||||
|
||||
if args.channel:
|
||||
channelarg = args.channel
|
||||
else:
|
||||
channelarg = None
|
||||
if args.channel:
|
||||
channelarg = args.channel
|
||||
else:
|
||||
channelarg = None
|
||||
|
||||
program_setup(configarg, channelarg)
|
||||
program_setup(configarg, channelarg)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("")
|
||||
exit()
|
||||
except KeyboardInterrupt:
|
||||
print("")
|
||||
exit()
|
296
Examples/Echo.py
296
Examples/Echo.py
|
@ -22,56 +22,56 @@ APP_NAME = "example_utilitites"
|
|||
# This initialisation is executed when the users chooses
|
||||
# to run as a server
|
||||
def server(configpath):
|
||||
# We must first initialise Reticulum
|
||||
reticulum = RNS.Reticulum(configpath)
|
||||
|
||||
# Randomly create a new identity for our echo server
|
||||
server_identity = RNS.Identity()
|
||||
# We must first initialise Reticulum
|
||||
reticulum = RNS.Reticulum(configpath)
|
||||
|
||||
# Randomly create a new identity for our echo server
|
||||
server_identity = RNS.Identity()
|
||||
|
||||
# We create a destination that clients can query. We want
|
||||
# to be able to verify echo replies to our clients, so we
|
||||
# create a "single" destination that can receive encrypted
|
||||
# messages. This way the client can send a request and be
|
||||
# certain that no-one else than this destination was able
|
||||
# to read it.
|
||||
echo_destination = RNS.Destination(server_identity, RNS.Destination.IN, RNS.Destination.SINGLE, APP_NAME, "echo", "request")
|
||||
# We create a destination that clients can query. We want
|
||||
# to be able to verify echo replies to our clients, so we
|
||||
# create a "single" destination that can receive encrypted
|
||||
# messages. This way the client can send a request and be
|
||||
# certain that no-one else than this destination was able
|
||||
# to read it.
|
||||
echo_destination = RNS.Destination(server_identity, RNS.Destination.IN, RNS.Destination.SINGLE, APP_NAME, "echo", "request")
|
||||
|
||||
# We configure the destination to automatically prove all
|
||||
# packets adressed to it. By doing this, RNS will automatically
|
||||
# generate a proof for each incoming packet and transmit it
|
||||
# back to the sender of that packet.
|
||||
echo_destination.set_proof_strategy(RNS.Destination.PROVE_ALL)
|
||||
|
||||
# Tell the destination which function in our program to
|
||||
# run when a packet is received. We do this so we can
|
||||
# print a log message when the server receives a request
|
||||
echo_destination.packet_callback(server_callback)
|
||||
# We configure the destination to automatically prove all
|
||||
# packets adressed to it. By doing this, RNS will automatically
|
||||
# generate a proof for each incoming packet and transmit it
|
||||
# back to the sender of that packet.
|
||||
echo_destination.set_proof_strategy(RNS.Destination.PROVE_ALL)
|
||||
|
||||
# Tell the destination which function in our program to
|
||||
# run when a packet is received. We do this so we can
|
||||
# print a log message when the server receives a request
|
||||
echo_destination.packet_callback(server_callback)
|
||||
|
||||
# Everything's ready!
|
||||
# Let's Wait for client requests or user input
|
||||
announceLoop(echo_destination)
|
||||
# Everything's ready!
|
||||
# Let's Wait for client requests or user input
|
||||
announceLoop(echo_destination)
|
||||
|
||||
|
||||
def announceLoop(destination):
|
||||
# Let the user know that everything is ready
|
||||
RNS.log("Echo server "+RNS.prettyhexrep(destination.hash)+" running, hit enter to manually send an announce (Ctrl-C to quit)")
|
||||
# Let the user know that everything is ready
|
||||
RNS.log("Echo server "+RNS.prettyhexrep(destination.hash)+" running, hit enter to manually send an announce (Ctrl-C to quit)")
|
||||
|
||||
# We enter a loop that runs until the users exits.
|
||||
# If the user hits enter, we will announce our server
|
||||
# destination on the network, which will let clients
|
||||
# know how to create messages directed towards it.
|
||||
while True:
|
||||
entered = input()
|
||||
destination.announce()
|
||||
RNS.log("Sent announce from "+RNS.prettyhexrep(destination.hash))
|
||||
# We enter a loop that runs until the users exits.
|
||||
# If the user hits enter, we will announce our server
|
||||
# destination on the network, which will let clients
|
||||
# know how to create messages directed towards it.
|
||||
while True:
|
||||
entered = input()
|
||||
destination.announce()
|
||||
RNS.log("Sent announce from "+RNS.prettyhexrep(destination.hash))
|
||||
|
||||
|
||||
def server_callback(message, packet):
|
||||
# Tell the user that we received an echo request, and
|
||||
# that we are going to send a reply to the requester.
|
||||
# Sending the proof is handled automatically, since we
|
||||
# set up the destination to prove all incoming packets.
|
||||
RNS.log("Received packet from echo client, proof sent")
|
||||
# Tell the user that we received an echo request, and
|
||||
# that we are going to send a reply to the requester.
|
||||
# Sending the proof is handled automatically, since we
|
||||
# set up the destination to prove all incoming packets.
|
||||
RNS.log("Received packet from echo client, proof sent")
|
||||
|
||||
|
||||
##########################################################
|
||||
|
@ -81,103 +81,103 @@ def server_callback(message, packet):
|
|||
# This initialisation is executed when the users chooses
|
||||
# to run as a client
|
||||
def client(destination_hexhash, configpath, timeout=None):
|
||||
# We need a binary representation of the destination
|
||||
# hash that was entered on the command line
|
||||
try:
|
||||
if len(destination_hexhash) != 20:
|
||||
raise ValueError("Destination length is invalid, must be 20 hexadecimal characters (10 bytes)")
|
||||
destination_hash = bytes.fromhex(destination_hexhash)
|
||||
except:
|
||||
RNS.log("Invalid destination entered. Check your input!\n")
|
||||
exit()
|
||||
# We need a binary representation of the destination
|
||||
# hash that was entered on the command line
|
||||
try:
|
||||
if len(destination_hexhash) != 20:
|
||||
raise ValueError("Destination length is invalid, must be 20 hexadecimal characters (10 bytes)")
|
||||
destination_hash = bytes.fromhex(destination_hexhash)
|
||||
except:
|
||||
RNS.log("Invalid destination entered. Check your input!\n")
|
||||
exit()
|
||||
|
||||
# We must first initialise Reticulum
|
||||
reticulum = RNS.Reticulum(configpath)
|
||||
# We must first initialise Reticulum
|
||||
reticulum = RNS.Reticulum(configpath)
|
||||
|
||||
# We override the loglevel to provide feedback when
|
||||
# an announce is received
|
||||
if RNS.loglevel < RNS.LOG_INFO:
|
||||
RNS.loglevel = RNS.LOG_INFO
|
||||
# We override the loglevel to provide feedback when
|
||||
# an announce is received
|
||||
if RNS.loglevel < RNS.LOG_INFO:
|
||||
RNS.loglevel = RNS.LOG_INFO
|
||||
|
||||
# Tell the user that the client is ready!
|
||||
RNS.log("Echo client ready, hit enter to send echo request to "+destination_hexhash+" (Ctrl-C to quit)")
|
||||
# Tell the user that the client is ready!
|
||||
RNS.log("Echo client ready, hit enter to send echo request to "+destination_hexhash+" (Ctrl-C to quit)")
|
||||
|
||||
# We enter a loop that runs until the user exits.
|
||||
# If the user hits enter, we will try to send an
|
||||
# echo request to the destination specified on the
|
||||
# command line.
|
||||
while True:
|
||||
input()
|
||||
|
||||
# Let's first check if RNS knows a path to the destination.
|
||||
# If it does, we'll load the server identity and create a packet
|
||||
if RNS.Transport.hasPath(destination_hash):
|
||||
# We enter a loop that runs until the user exits.
|
||||
# If the user hits enter, we will try to send an
|
||||
# echo request to the destination specified on the
|
||||
# command line.
|
||||
while True:
|
||||
input()
|
||||
|
||||
# Let's first check if RNS knows a path to the destination.
|
||||
# If it does, we'll load the server identity and create a packet
|
||||
if RNS.Transport.hasPath(destination_hash):
|
||||
|
||||
# To address the server, we need to know it's public
|
||||
# key, so we check if Reticulum knows this destination.
|
||||
# This is done by calling the "recall" method of the
|
||||
# Identity module. If the destination is known, it will
|
||||
# return an Identity instance that can be used in
|
||||
# outgoing destinations.
|
||||
server_identity = RNS.Identity.recall(destination_hash)
|
||||
# To address the server, we need to know it's public
|
||||
# key, so we check if Reticulum knows this destination.
|
||||
# This is done by calling the "recall" method of the
|
||||
# Identity module. If the destination is known, it will
|
||||
# return an Identity instance that can be used in
|
||||
# outgoing destinations.
|
||||
server_identity = RNS.Identity.recall(destination_hash)
|
||||
|
||||
# We got the correct identity instance from the
|
||||
# recall method, so let's create an outgoing
|
||||
# destination. We use the naming convention:
|
||||
# example_utilities.echo.request
|
||||
# This matches the naming we specified in the
|
||||
# server part of the code.
|
||||
request_destination = RNS.Destination(server_identity, RNS.Destination.OUT, RNS.Destination.SINGLE, APP_NAME, "echo", "request")
|
||||
# We got the correct identity instance from the
|
||||
# recall method, so let's create an outgoing
|
||||
# destination. We use the naming convention:
|
||||
# example_utilities.echo.request
|
||||
# This matches the naming we specified in the
|
||||
# server part of the code.
|
||||
request_destination = RNS.Destination(server_identity, RNS.Destination.OUT, RNS.Destination.SINGLE, APP_NAME, "echo", "request")
|
||||
|
||||
# The destination is ready, so let's create a packet.
|
||||
# We set the destination to the request_destination
|
||||
# that was just created, and the only data we add
|
||||
# is a random hash.
|
||||
echo_request = RNS.Packet(request_destination, RNS.Identity.getRandomHash())
|
||||
# The destination is ready, so let's create a packet.
|
||||
# We set the destination to the request_destination
|
||||
# that was just created, and the only data we add
|
||||
# is a random hash.
|
||||
echo_request = RNS.Packet(request_destination, RNS.Identity.getRandomHash())
|
||||
|
||||
# Send the packet! If the packet is successfully
|
||||
# sent, it will return a PacketReceipt instance.
|
||||
packet_receipt = echo_request.send()
|
||||
# Send the packet! If the packet is successfully
|
||||
# sent, it will return a PacketReceipt instance.
|
||||
packet_receipt = echo_request.send()
|
||||
|
||||
# If the user specified a timeout, we set this
|
||||
# timeout on the packet receipt, and configure
|
||||
# a callback function, that will get called if
|
||||
# the packet times out.
|
||||
if timeout != None:
|
||||
packet_receipt.set_timeout(timeout)
|
||||
packet_receipt.timeout_callback(packet_timed_out)
|
||||
# If the user specified a timeout, we set this
|
||||
# timeout on the packet receipt, and configure
|
||||
# a callback function, that will get called if
|
||||
# the packet times out.
|
||||
if timeout != None:
|
||||
packet_receipt.set_timeout(timeout)
|
||||
packet_receipt.timeout_callback(packet_timed_out)
|
||||
|
||||
# We can then set a delivery callback on the receipt.
|
||||
# This will get automatically called when a proof for
|
||||
# this specific packet is received from the destination.
|
||||
packet_receipt.delivery_callback(packet_delivered)
|
||||
# We can then set a delivery callback on the receipt.
|
||||
# This will get automatically called when a proof for
|
||||
# this specific packet is received from the destination.
|
||||
packet_receipt.delivery_callback(packet_delivered)
|
||||
|
||||
# Tell the user that the echo request was sent
|
||||
RNS.log("Sent echo request to "+RNS.prettyhexrep(request_destination.hash))
|
||||
else:
|
||||
# If we do not know this destination, tell the
|
||||
# user to wait for an announce to arrive.
|
||||
RNS.log("Destination is not yet known. Requesting path...")
|
||||
RNS.Transport.requestPath(destination_hash)
|
||||
# Tell the user that the echo request was sent
|
||||
RNS.log("Sent echo request to "+RNS.prettyhexrep(request_destination.hash))
|
||||
else:
|
||||
# If we do not know this destination, tell the
|
||||
# user to wait for an announce to arrive.
|
||||
RNS.log("Destination is not yet known. Requesting path...")
|
||||
RNS.Transport.requestPath(destination_hash)
|
||||
|
||||
# This function is called when our reply destination
|
||||
# receives a proof packet.
|
||||
def packet_delivered(receipt):
|
||||
if receipt.status == RNS.PacketReceipt.DELIVERED:
|
||||
rtt = receipt.rtt()
|
||||
if (rtt >= 1):
|
||||
rtt = round(rtt, 3)
|
||||
rttstring = str(rtt)+" seconds"
|
||||
else:
|
||||
rtt = round(rtt*1000, 3)
|
||||
rttstring = str(rtt)+" milliseconds"
|
||||
if receipt.status == RNS.PacketReceipt.DELIVERED:
|
||||
rtt = receipt.rtt()
|
||||
if (rtt >= 1):
|
||||
rtt = round(rtt, 3)
|
||||
rttstring = str(rtt)+" seconds"
|
||||
else:
|
||||
rtt = round(rtt*1000, 3)
|
||||
rttstring = str(rtt)+" milliseconds"
|
||||
|
||||
RNS.log("Valid reply received from "+RNS.prettyhexrep(receipt.destination.hash)+", round-trip time is "+rttstring)
|
||||
RNS.log("Valid reply received from "+RNS.prettyhexrep(receipt.destination.hash)+", round-trip time is "+rttstring)
|
||||
|
||||
# This function is called if a packet times out.
|
||||
def packet_timed_out(receipt):
|
||||
if receipt.status == RNS.PacketReceipt.FAILED:
|
||||
RNS.log("Packet "+RNS.prettyhexrep(receipt.hash)+" timed out")
|
||||
if receipt.status == RNS.PacketReceipt.FAILED:
|
||||
RNS.log("Packet "+RNS.prettyhexrep(receipt.hash)+" timed out")
|
||||
|
||||
|
||||
##########################################################
|
||||
|
@ -188,36 +188,36 @@ def packet_timed_out(receipt):
|
|||
# and parses input from the user, and then starts
|
||||
# the desired program mode.
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
parser = argparse.ArgumentParser(description="Simple echo server and client utility")
|
||||
parser.add_argument("-s", "--server", action="store_true", help="wait for incoming packets from clients")
|
||||
parser.add_argument("-t", "--timeout", action="store", metavar="s", default=None, help="set a reply timeout in seconds", type=float)
|
||||
parser.add_argument("--config", action="store", default=None, help="path to alternative Reticulum config directory", type=str)
|
||||
parser.add_argument("destination", nargs="?", default=None, help="hexadecimal hash of the server destination", type=str)
|
||||
args = parser.parse_args()
|
||||
try:
|
||||
parser = argparse.ArgumentParser(description="Simple echo server and client utility")
|
||||
parser.add_argument("-s", "--server", action="store_true", help="wait for incoming packets from clients")
|
||||
parser.add_argument("-t", "--timeout", action="store", metavar="s", default=None, help="set a reply timeout in seconds", type=float)
|
||||
parser.add_argument("--config", action="store", default=None, help="path to alternative Reticulum config directory", type=str)
|
||||
parser.add_argument("destination", nargs="?", default=None, help="hexadecimal hash of the server destination", type=str)
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.server:
|
||||
configarg=None
|
||||
if args.config:
|
||||
configarg = args.config
|
||||
server(configarg)
|
||||
else:
|
||||
if args.config:
|
||||
configarg = args.config
|
||||
else:
|
||||
configarg = None
|
||||
if args.server:
|
||||
configarg=None
|
||||
if args.config:
|
||||
configarg = args.config
|
||||
server(configarg)
|
||||
else:
|
||||
if args.config:
|
||||
configarg = args.config
|
||||
else:
|
||||
configarg = None
|
||||
|
||||
if args.timeout:
|
||||
timeoutarg = float(args.timeout)
|
||||
else:
|
||||
timeoutarg = None
|
||||
if args.timeout:
|
||||
timeoutarg = float(args.timeout)
|
||||
else:
|
||||
timeoutarg = None
|
||||
|
||||
if (args.destination == None):
|
||||
print("")
|
||||
parser.print_help()
|
||||
print("")
|
||||
else:
|
||||
client(args.destination, configarg, timeout=timeoutarg)
|
||||
except KeyboardInterrupt:
|
||||
print("")
|
||||
exit()
|
||||
if (args.destination == None):
|
||||
print("")
|
||||
parser.print_help()
|
||||
print("")
|
||||
else:
|
||||
client(args.destination, configarg, timeout=timeoutarg)
|
||||
except KeyboardInterrupt:
|
||||
print("")
|
||||
exit()
|
|
@ -42,132 +42,132 @@ serve_path = None
|
|||
# This initialisation is executed when the users chooses
|
||||
# to run as a server
|
||||
def server(configpath, path):
|
||||
# We must first initialise Reticulum
|
||||
reticulum = RNS.Reticulum(configpath)
|
||||
|
||||
# Randomly create a new identity for our file server
|
||||
server_identity = RNS.Identity()
|
||||
# We must first initialise Reticulum
|
||||
reticulum = RNS.Reticulum(configpath)
|
||||
|
||||
# Randomly create a new identity for our file server
|
||||
server_identity = RNS.Identity()
|
||||
|
||||
global serve_path
|
||||
serve_path = path
|
||||
global serve_path
|
||||
serve_path = path
|
||||
|
||||
# We create a destination that clients can connect to. We
|
||||
# want clients to create links to this destination, so we
|
||||
# need to create a "single" destination type.
|
||||
server_destination = RNS.Destination(server_identity, RNS.Destination.IN, RNS.Destination.SINGLE, APP_NAME, "filetransfer", "server")
|
||||
# We create a destination that clients can connect to. We
|
||||
# want clients to create links to this destination, so we
|
||||
# need to create a "single" destination type.
|
||||
server_destination = RNS.Destination(server_identity, RNS.Destination.IN, RNS.Destination.SINGLE, APP_NAME, "filetransfer", "server")
|
||||
|
||||
# We configure a function that will get called every time
|
||||
# a new client creates a link to this destination.
|
||||
server_destination.link_established_callback(client_connected)
|
||||
# We configure a function that will get called every time
|
||||
# a new client creates a link to this destination.
|
||||
server_destination.link_established_callback(client_connected)
|
||||
|
||||
# Everything's ready!
|
||||
# Let's Wait for client requests or user input
|
||||
announceLoop(server_destination)
|
||||
# Everything's ready!
|
||||
# Let's Wait for client requests or user input
|
||||
announceLoop(server_destination)
|
||||
|
||||
def announceLoop(destination):
|
||||
# Let the user know that everything is ready
|
||||
RNS.log("File server "+RNS.prettyhexrep(destination.hash)+" running")
|
||||
RNS.log("Hit enter to manually send an announce (Ctrl-C to quit)")
|
||||
# Let the user know that everything is ready
|
||||
RNS.log("File server "+RNS.prettyhexrep(destination.hash)+" running")
|
||||
RNS.log("Hit enter to manually send an announce (Ctrl-C to quit)")
|
||||
|
||||
# We enter a loop that runs until the users exits.
|
||||
# If the user hits enter, we will announce our server
|
||||
# destination on the network, which will let clients
|
||||
# know how to create messages directed towards it.
|
||||
while True:
|
||||
entered = input()
|
||||
destination.announce()
|
||||
RNS.log("Sent announce from "+RNS.prettyhexrep(destination.hash))
|
||||
# We enter a loop that runs until the users exits.
|
||||
# If the user hits enter, we will announce our server
|
||||
# destination on the network, which will let clients
|
||||
# know how to create messages directed towards it.
|
||||
while True:
|
||||
entered = input()
|
||||
destination.announce()
|
||||
RNS.log("Sent announce from "+RNS.prettyhexrep(destination.hash))
|
||||
|
||||
# Here's a convenience function for listing all files
|
||||
# in our served directory
|
||||
def list_files():
|
||||
# We add all entries from the directory that are
|
||||
# actual files, and does not start with "."
|
||||
global serve_path
|
||||
return [file for file in os.listdir(serve_path) if os.path.isfile(os.path.join(serve_path, file)) and file[:1] != "."]
|
||||
# We add all entries from the directory that are
|
||||
# actual files, and does not start with "."
|
||||
global serve_path
|
||||
return [file for file in os.listdir(serve_path) if os.path.isfile(os.path.join(serve_path, file)) and file[:1] != "."]
|
||||
|
||||
# When a client establishes a link to our server
|
||||
# destination, this function will be called with
|
||||
# a reference to the link. We then send the client
|
||||
# a list of files hosted on the server.
|
||||
def client_connected(link):
|
||||
# Check if the served directory still exists
|
||||
if os.path.isdir(serve_path):
|
||||
RNS.log("Client connected, sending file list...")
|
||||
# Check if the served directory still exists
|
||||
if os.path.isdir(serve_path):
|
||||
RNS.log("Client connected, sending file list...")
|
||||
|
||||
link.link_closed_callback(client_disconnected)
|
||||
link.link_closed_callback(client_disconnected)
|
||||
|
||||
# We pack a list of files for sending in a packet
|
||||
data = umsgpack.packb(list_files())
|
||||
# We pack a list of files for sending in a packet
|
||||
data = umsgpack.packb(list_files())
|
||||
|
||||
# Check the size of the packed data
|
||||
if len(data) <= RNS.Link.MDU:
|
||||
# If it fits in one packet, we will just
|
||||
# send it as a single packet over the link.
|
||||
list_packet = RNS.Packet(link, data)
|
||||
list_receipt = list_packet.send()
|
||||
list_receipt.set_timeout(APP_TIMEOUT)
|
||||
list_receipt.delivery_callback(list_delivered)
|
||||
list_receipt.timeout_callback(list_timeout)
|
||||
else:
|
||||
RNS.log("Too many files in served directory!", RNS.LOG_ERROR)
|
||||
RNS.log("You should implement a function to split the filelist over multiple packets.", RNS.LOG_ERROR)
|
||||
RNS.log("Hint: The client already supports it :)", RNS.LOG_ERROR)
|
||||
|
||||
# After this, we're just going to keep the link
|
||||
# open until the client requests a file. We'll
|
||||
# configure a function that get's called when
|
||||
# the client sends a packet with a file request.
|
||||
link.packet_callback(client_request)
|
||||
else:
|
||||
RNS.log("Client connected, but served path no longer exists!", RNS.LOG_ERROR)
|
||||
link.teardown()
|
||||
# Check the size of the packed data
|
||||
if len(data) <= RNS.Link.MDU:
|
||||
# If it fits in one packet, we will just
|
||||
# send it as a single packet over the link.
|
||||
list_packet = RNS.Packet(link, data)
|
||||
list_receipt = list_packet.send()
|
||||
list_receipt.set_timeout(APP_TIMEOUT)
|
||||
list_receipt.delivery_callback(list_delivered)
|
||||
list_receipt.timeout_callback(list_timeout)
|
||||
else:
|
||||
RNS.log("Too many files in served directory!", RNS.LOG_ERROR)
|
||||
RNS.log("You should implement a function to split the filelist over multiple packets.", RNS.LOG_ERROR)
|
||||
RNS.log("Hint: The client already supports it :)", RNS.LOG_ERROR)
|
||||
|
||||
# After this, we're just going to keep the link
|
||||
# open until the client requests a file. We'll
|
||||
# configure a function that get's called when
|
||||
# the client sends a packet with a file request.
|
||||
link.packet_callback(client_request)
|
||||
else:
|
||||
RNS.log("Client connected, but served path no longer exists!", RNS.LOG_ERROR)
|
||||
link.teardown()
|
||||
|
||||
def client_disconnected(link):
|
||||
RNS.log("Client disconnected")
|
||||
RNS.log("Client disconnected")
|
||||
|
||||
def client_request(message, packet):
|
||||
global serve_path
|
||||
filename = message.decode("utf-8")
|
||||
if filename in list_files():
|
||||
try:
|
||||
# If we have the requested file, we'll
|
||||
# read it and pack it as a resource
|
||||
RNS.log("Client requested \""+filename+"\"")
|
||||
file = open(os.path.join(serve_path, filename), "rb")
|
||||
file_resource = RNS.Resource(file, packet.link, callback=resource_sending_concluded)
|
||||
file_resource.filename = filename
|
||||
except Exception as e:
|
||||
# If somethign went wrong, we close
|
||||
# the link
|
||||
RNS.log("Error while reading file \""+filename+"\"", RNS.LOG_ERROR)
|
||||
packet.link.teardown()
|
||||
raise e
|
||||
else:
|
||||
# If we don't have it, we close the link
|
||||
RNS.log("Client requested an unknown file")
|
||||
packet.link.teardown()
|
||||
global serve_path
|
||||
filename = message.decode("utf-8")
|
||||
if filename in list_files():
|
||||
try:
|
||||
# If we have the requested file, we'll
|
||||
# read it and pack it as a resource
|
||||
RNS.log("Client requested \""+filename+"\"")
|
||||
file = open(os.path.join(serve_path, filename), "rb")
|
||||
file_resource = RNS.Resource(file, packet.link, callback=resource_sending_concluded)
|
||||
file_resource.filename = filename
|
||||
except Exception as e:
|
||||
# If somethign went wrong, we close
|
||||
# the link
|
||||
RNS.log("Error while reading file \""+filename+"\"", RNS.LOG_ERROR)
|
||||
packet.link.teardown()
|
||||
raise e
|
||||
else:
|
||||
# If we don't have it, we close the link
|
||||
RNS.log("Client requested an unknown file")
|
||||
packet.link.teardown()
|
||||
|
||||
# This function is called on the server when a
|
||||
# resource transfer concludes.
|
||||
def resource_sending_concluded(resource):
|
||||
if hasattr(resource, "filename"):
|
||||
name = resource.filename
|
||||
else:
|
||||
name = "resource"
|
||||
if hasattr(resource, "filename"):
|
||||
name = resource.filename
|
||||
else:
|
||||
name = "resource"
|
||||
|
||||
if resource.status == RNS.Resource.COMPLETE:
|
||||
RNS.log("Done sending \""+name+"\" to client")
|
||||
elif resource.status == RNS.Resource.FAILED:
|
||||
RNS.log("Sending \""+name+"\" to client failed")
|
||||
if resource.status == RNS.Resource.COMPLETE:
|
||||
RNS.log("Done sending \""+name+"\" to client")
|
||||
elif resource.status == RNS.Resource.FAILED:
|
||||
RNS.log("Sending \""+name+"\" to client failed")
|
||||
|
||||
def list_delivered(receipt):
|
||||
RNS.log("The file list was received by the client")
|
||||
RNS.log("The file list was received by the client")
|
||||
|
||||
def list_timeout(receipt):
|
||||
RNS.log("Sending list to client timed out, closing this link")
|
||||
link = receipt.destination
|
||||
link.teardown()
|
||||
RNS.log("Sending list to client timed out, closing this link")
|
||||
link = receipt.destination
|
||||
link.teardown()
|
||||
|
||||
##########################################################
|
||||
#### Client Part #########################################
|
||||
|
@ -194,116 +194,116 @@ file_size = 0
|
|||
# This initialisation is executed when the users chooses
|
||||
# to run as a client
|
||||
def client(destination_hexhash, configpath):
|
||||
# We need a binary representation of the destination
|
||||
# hash that was entered on the command line
|
||||
try:
|
||||
if len(destination_hexhash) != 20:
|
||||
raise ValueError("Destination length is invalid, must be 20 hexadecimal characters (10 bytes)")
|
||||
destination_hash = bytes.fromhex(destination_hexhash)
|
||||
except:
|
||||
RNS.log("Invalid destination entered. Check your input!\n")
|
||||
exit()
|
||||
# We need a binary representation of the destination
|
||||
# hash that was entered on the command line
|
||||
try:
|
||||
if len(destination_hexhash) != 20:
|
||||
raise ValueError("Destination length is invalid, must be 20 hexadecimal characters (10 bytes)")
|
||||
destination_hash = bytes.fromhex(destination_hexhash)
|
||||
except:
|
||||
RNS.log("Invalid destination entered. Check your input!\n")
|
||||
exit()
|
||||
|
||||
# We must first initialise Reticulum
|
||||
reticulum = RNS.Reticulum(configpath)
|
||||
# We must first initialise Reticulum
|
||||
reticulum = RNS.Reticulum(configpath)
|
||||
|
||||
|
||||
# Check if we know a path to the destination
|
||||
if not RNS.Transport.hasPath(destination_hash):
|
||||
RNS.log("Destination is not yet known. Requesting path and waiting for announce to arrive...")
|
||||
RNS.Transport.requestPath(destination_hash)
|
||||
while not RNS.Transport.hasPath(destination_hash):
|
||||
time.sleep(0.1)
|
||||
# Check if we know a path to the destination
|
||||
if not RNS.Transport.hasPath(destination_hash):
|
||||
RNS.log("Destination is not yet known. Requesting path and waiting for announce to arrive...")
|
||||
RNS.Transport.requestPath(destination_hash)
|
||||
while not RNS.Transport.hasPath(destination_hash):
|
||||
time.sleep(0.1)
|
||||
|
||||
# Recall the server identity
|
||||
server_identity = RNS.Identity.recall(destination_hash)
|
||||
# Recall the server identity
|
||||
server_identity = RNS.Identity.recall(destination_hash)
|
||||
|
||||
# Inform the user that we'll begin connecting
|
||||
RNS.log("Establishing link with server...")
|
||||
# Inform the user that we'll begin connecting
|
||||
RNS.log("Establishing link with server...")
|
||||
|
||||
# When the server identity is known, we set
|
||||
# up a destination
|
||||
server_destination = RNS.Destination(server_identity, RNS.Destination.OUT, RNS.Destination.SINGLE, APP_NAME, "filetransfer", "server")
|
||||
# When the server identity is known, we set
|
||||
# up a destination
|
||||
server_destination = RNS.Destination(server_identity, RNS.Destination.OUT, RNS.Destination.SINGLE, APP_NAME, "filetransfer", "server")
|
||||
|
||||
# We also want to automatically prove incoming packets
|
||||
server_destination.set_proof_strategy(RNS.Destination.PROVE_ALL)
|
||||
# We also want to automatically prove incoming packets
|
||||
server_destination.set_proof_strategy(RNS.Destination.PROVE_ALL)
|
||||
|
||||
# And create a link
|
||||
link = RNS.Link(server_destination)
|
||||
# And create a link
|
||||
link = RNS.Link(server_destination)
|
||||
|
||||
# We expect any normal data packets on the link
|
||||
# to contain a list of served files, so we set
|
||||
# a callback accordingly
|
||||
link.packet_callback(filelist_received)
|
||||
# We expect any normal data packets on the link
|
||||
# to contain a list of served files, so we set
|
||||
# a callback accordingly
|
||||
link.packet_callback(filelist_received)
|
||||
|
||||
# We'll also set up functions to inform the
|
||||
# user when the link is established or closed
|
||||
link.link_established_callback(link_established)
|
||||
link.link_closed_callback(link_closed)
|
||||
# We'll also set up functions to inform the
|
||||
# user when the link is established or closed
|
||||
link.link_established_callback(link_established)
|
||||
link.link_closed_callback(link_closed)
|
||||
|
||||
# And set the link to automatically begin
|
||||
# downloading advertised resources
|
||||
link.set_resource_strategy(RNS.Link.ACCEPT_ALL)
|
||||
link.resource_started_callback(download_began)
|
||||
link.resource_concluded_callback(download_concluded)
|
||||
# And set the link to automatically begin
|
||||
# downloading advertised resources
|
||||
link.set_resource_strategy(RNS.Link.ACCEPT_ALL)
|
||||
link.resource_started_callback(download_began)
|
||||
link.resource_concluded_callback(download_concluded)
|
||||
|
||||
menu()
|
||||
menu()
|
||||
|
||||
# Requests the specified file from the server
|
||||
def download(filename):
|
||||
global server_link, menu_mode, current_filename, transfer_size, download_started
|
||||
current_filename = filename
|
||||
download_started = 0
|
||||
transfer_size = 0
|
||||
global server_link, menu_mode, current_filename, transfer_size, download_started
|
||||
current_filename = filename
|
||||
download_started = 0
|
||||
transfer_size = 0
|
||||
|
||||
# We just create a packet containing the
|
||||
# requested filename, and send it down the
|
||||
# link. We also specify we don't need a
|
||||
# packet receipt.
|
||||
request_packet = RNS.Packet(server_link, filename.encode("utf-8"), create_receipt=False)
|
||||
request_packet.send()
|
||||
|
||||
print("")
|
||||
print(("Requested \""+filename+"\" from server, waiting for download to begin..."))
|
||||
menu_mode = "download_started"
|
||||
# We just create a packet containing the
|
||||
# requested filename, and send it down the
|
||||
# link. We also specify we don't need a
|
||||
# packet receipt.
|
||||
request_packet = RNS.Packet(server_link, filename.encode("utf-8"), create_receipt=False)
|
||||
request_packet.send()
|
||||
|
||||
print("")
|
||||
print(("Requested \""+filename+"\" from server, waiting for download to begin..."))
|
||||
menu_mode = "download_started"
|
||||
|
||||
# This function runs a simple menu for the user
|
||||
# to select which files to download, or quit
|
||||
menu_mode = None
|
||||
def menu():
|
||||
global server_files, server_link
|
||||
# Wait until we have a filelist
|
||||
while len(server_files) == 0:
|
||||
time.sleep(0.1)
|
||||
RNS.log("Ready!")
|
||||
time.sleep(0.5)
|
||||
global server_files, server_link
|
||||
# Wait until we have a filelist
|
||||
while len(server_files) == 0:
|
||||
time.sleep(0.1)
|
||||
RNS.log("Ready!")
|
||||
time.sleep(0.5)
|
||||
|
||||
global menu_mode
|
||||
menu_mode = "main"
|
||||
should_quit = False
|
||||
while (not should_quit):
|
||||
print_menu()
|
||||
global menu_mode
|
||||
menu_mode = "main"
|
||||
should_quit = False
|
||||
while (not should_quit):
|
||||
print_menu()
|
||||
|
||||
while not menu_mode == "main":
|
||||
# Wait
|
||||
time.sleep(0.25)
|
||||
while not menu_mode == "main":
|
||||
# Wait
|
||||
time.sleep(0.25)
|
||||
|
||||
user_input = input()
|
||||
if user_input == "q" or user_input == "quit" or user_input == "exit":
|
||||
should_quit = True
|
||||
print("")
|
||||
else:
|
||||
if user_input in server_files:
|
||||
download(user_input)
|
||||
else:
|
||||
try:
|
||||
if 0 <= int(user_input) < len(server_files):
|
||||
download(server_files[int(user_input)])
|
||||
except:
|
||||
pass
|
||||
user_input = input()
|
||||
if user_input == "q" or user_input == "quit" or user_input == "exit":
|
||||
should_quit = True
|
||||
print("")
|
||||
else:
|
||||
if user_input in server_files:
|
||||
download(user_input)
|
||||
else:
|
||||
try:
|
||||
if 0 <= int(user_input) < len(server_files):
|
||||
download(server_files[int(user_input)])
|
||||
except:
|
||||
pass
|
||||
|
||||
if should_quit:
|
||||
server_link.teardown()
|
||||
if should_quit:
|
||||
server_link.teardown()
|
||||
|
||||
# Prints out menus or screens for the
|
||||
# various states of the client program.
|
||||
|
@ -311,145 +311,145 @@ def menu():
|
|||
# I won't go into detail here. Just
|
||||
# strings basically.
|
||||
def print_menu():
|
||||
global menu_mode, download_time, download_started, download_finished, transfer_size, file_size
|
||||
global menu_mode, download_time, download_started, download_finished, transfer_size, file_size
|
||||
|
||||
if menu_mode == "main":
|
||||
clear_screen()
|
||||
print_filelist()
|
||||
print("")
|
||||
print("Select a file to download by entering name or number, or q to quit")
|
||||
print(("> "), end=' ')
|
||||
elif menu_mode == "download_started":
|
||||
download_began = time.time()
|
||||
while menu_mode == "download_started":
|
||||
time.sleep(0.1)
|
||||
if time.time() > download_began+APP_TIMEOUT:
|
||||
print("The download timed out")
|
||||
time.sleep(1)
|
||||
server_link.teardown()
|
||||
if menu_mode == "main":
|
||||
clear_screen()
|
||||
print_filelist()
|
||||
print("")
|
||||
print("Select a file to download by entering name or number, or q to quit")
|
||||
print(("> "), end=' ')
|
||||
elif menu_mode == "download_started":
|
||||
download_began = time.time()
|
||||
while menu_mode == "download_started":
|
||||
time.sleep(0.1)
|
||||
if time.time() > download_began+APP_TIMEOUT:
|
||||
print("The download timed out")
|
||||
time.sleep(1)
|
||||
server_link.teardown()
|
||||
|
||||
if menu_mode == "downloading":
|
||||
print("Download started")
|
||||
print("")
|
||||
while menu_mode == "downloading":
|
||||
global current_download
|
||||
percent = round(current_download.progress() * 100.0, 1)
|
||||
print(("\rProgress: "+str(percent)+" % "), end=' ')
|
||||
sys.stdout.flush()
|
||||
time.sleep(0.1)
|
||||
if menu_mode == "downloading":
|
||||
print("Download started")
|
||||
print("")
|
||||
while menu_mode == "downloading":
|
||||
global current_download
|
||||
percent = round(current_download.progress() * 100.0, 1)
|
||||
print(("\rProgress: "+str(percent)+" % "), end=' ')
|
||||
sys.stdout.flush()
|
||||
time.sleep(0.1)
|
||||
|
||||
if menu_mode == "save_error":
|
||||
print(("\rProgress: 100.0 %"), end=' ')
|
||||
sys.stdout.flush()
|
||||
print("")
|
||||
print("Could not write downloaded file to disk")
|
||||
current_download.status = RNS.Resource.FAILED
|
||||
menu_mode = "download_concluded"
|
||||
if menu_mode == "save_error":
|
||||
print(("\rProgress: 100.0 %"), end=' ')
|
||||
sys.stdout.flush()
|
||||
print("")
|
||||
print("Could not write downloaded file to disk")
|
||||
current_download.status = RNS.Resource.FAILED
|
||||
menu_mode = "download_concluded"
|
||||
|
||||
if menu_mode == "download_concluded":
|
||||
if current_download.status == RNS.Resource.COMPLETE:
|
||||
print(("\rProgress: 100.0 %"), end=' ')
|
||||
sys.stdout.flush()
|
||||
if menu_mode == "download_concluded":
|
||||
if current_download.status == RNS.Resource.COMPLETE:
|
||||
print(("\rProgress: 100.0 %"), end=' ')
|
||||
sys.stdout.flush()
|
||||
|
||||
# Print statistics
|
||||
hours, rem = divmod(download_time, 3600)
|
||||
minutes, seconds = divmod(rem, 60)
|
||||
timestring = "{:0>2}:{:0>2}:{:05.2f}".format(int(hours),int(minutes),seconds)
|
||||
print("")
|
||||
print("")
|
||||
print("--- Statistics -----")
|
||||
print("\tTime taken : "+timestring)
|
||||
print("\tFile size : "+size_str(file_size))
|
||||
print("\tData transferred : "+size_str(transfer_size))
|
||||
print("\tEffective rate : "+size_str(file_size/download_time, suffix='b')+"/s")
|
||||
print("\tTransfer rate : "+size_str(transfer_size/download_time, suffix='b')+"/s")
|
||||
print("")
|
||||
print("The download completed! Press enter to return to the menu.")
|
||||
print("")
|
||||
input()
|
||||
# Print statistics
|
||||
hours, rem = divmod(download_time, 3600)
|
||||
minutes, seconds = divmod(rem, 60)
|
||||
timestring = "{:0>2}:{:0>2}:{:05.2f}".format(int(hours),int(minutes),seconds)
|
||||
print("")
|
||||
print("")
|
||||
print("--- Statistics -----")
|
||||
print("\tTime taken : "+timestring)
|
||||
print("\tFile size : "+size_str(file_size))
|
||||
print("\tData transferred : "+size_str(transfer_size))
|
||||
print("\tEffective rate : "+size_str(file_size/download_time, suffix='b')+"/s")
|
||||
print("\tTransfer rate : "+size_str(transfer_size/download_time, suffix='b')+"/s")
|
||||
print("")
|
||||
print("The download completed! Press enter to return to the menu.")
|
||||
print("")
|
||||
input()
|
||||
|
||||
else:
|
||||
print("")
|
||||
print("The download failed! Press enter to return to the menu.")
|
||||
input()
|
||||
else:
|
||||
print("")
|
||||
print("The download failed! Press enter to return to the menu.")
|
||||
input()
|
||||
|
||||
current_download = None
|
||||
menu_mode = "main"
|
||||
print_menu()
|
||||
current_download = None
|
||||
menu_mode = "main"
|
||||
print_menu()
|
||||
|
||||
# This function prints out a list of files
|
||||
# on the connected server.
|
||||
def print_filelist():
|
||||
global server_files
|
||||
print("Files on server:")
|
||||
for index,file in enumerate(server_files):
|
||||
print("\t("+str(index)+")\t"+file)
|
||||
global server_files
|
||||
print("Files on server:")
|
||||
for index,file in enumerate(server_files):
|
||||
print("\t("+str(index)+")\t"+file)
|
||||
|
||||
def filelist_received(filelist_data, packet):
|
||||
global server_files, menu_mode
|
||||
try:
|
||||
# Unpack the list and extend our
|
||||
# local list of available files
|
||||
filelist = umsgpack.unpackb(filelist_data)
|
||||
for file in filelist:
|
||||
if not file in server_files:
|
||||
server_files.append(file)
|
||||
global server_files, menu_mode
|
||||
try:
|
||||
# Unpack the list and extend our
|
||||
# local list of available files
|
||||
filelist = umsgpack.unpackb(filelist_data)
|
||||
for file in filelist:
|
||||
if not file in server_files:
|
||||
server_files.append(file)
|
||||
|
||||
# If the menu is already visible,
|
||||
# we'll update it with what was
|
||||
# just received
|
||||
if menu_mode == "main":
|
||||
print_menu()
|
||||
except:
|
||||
RNS.log("Invalid file list data received, closing link")
|
||||
packet.link.teardown()
|
||||
# If the menu is already visible,
|
||||
# we'll update it with what was
|
||||
# just received
|
||||
if menu_mode == "main":
|
||||
print_menu()
|
||||
except:
|
||||
RNS.log("Invalid file list data received, closing link")
|
||||
packet.link.teardown()
|
||||
|
||||
# This function is called when a link
|
||||
# has been established with the server
|
||||
def link_established(link):
|
||||
# We store a reference to the link
|
||||
# instance for later use
|
||||
global server_link
|
||||
server_link = link
|
||||
# We store a reference to the link
|
||||
# instance for later use
|
||||
global server_link
|
||||
server_link = link
|
||||
|
||||
# Inform the user that the server is
|
||||
# connected
|
||||
RNS.log("Link established with server")
|
||||
RNS.log("Waiting for filelist...")
|
||||
# Inform the user that the server is
|
||||
# connected
|
||||
RNS.log("Link established with server")
|
||||
RNS.log("Waiting for filelist...")
|
||||
|
||||
# And set up a small job to check for
|
||||
# a potential timeout in receiving the
|
||||
# file list
|
||||
thread = threading.Thread(target=filelist_timeout_job)
|
||||
thread.setDaemon(True)
|
||||
thread.start()
|
||||
# And set up a small job to check for
|
||||
# a potential timeout in receiving the
|
||||
# file list
|
||||
thread = threading.Thread(target=filelist_timeout_job)
|
||||
thread.setDaemon(True)
|
||||
thread.start()
|
||||
|
||||
# This job just sleeps for the specified
|
||||
# time, and then checks if the file list
|
||||
# was received. If not, the program will
|
||||
# exit.
|
||||
def filelist_timeout_job():
|
||||
time.sleep(APP_TIMEOUT)
|
||||
time.sleep(APP_TIMEOUT)
|
||||
|
||||
global server_files
|
||||
if len(server_files) == 0:
|
||||
RNS.log("Timed out waiting for filelist, exiting")
|
||||
os._exit(0)
|
||||
global server_files
|
||||
if len(server_files) == 0:
|
||||
RNS.log("Timed out waiting for filelist, exiting")
|
||||
os._exit(0)
|
||||
|
||||
|
||||
# When a link is closed, we'll inform the
|
||||
# user, and exit the program
|
||||
def link_closed(link):
|
||||
if link.teardown_reason == RNS.Link.TIMEOUT:
|
||||
RNS.log("The link timed out, exiting now")
|
||||
elif link.teardown_reason == RNS.Link.DESTINATION_CLOSED:
|
||||
RNS.log("The link was closed by the server, exiting now")
|
||||
else:
|
||||
RNS.log("Link closed, exiting now")
|
||||
|
||||
RNS.Reticulum.exit_handler()
|
||||
time.sleep(1.5)
|
||||
os._exit(0)
|
||||
if link.teardown_reason == RNS.Link.TIMEOUT:
|
||||
RNS.log("The link timed out, exiting now")
|
||||
elif link.teardown_reason == RNS.Link.DESTINATION_CLOSED:
|
||||
RNS.log("The link was closed by the server, exiting now")
|
||||
else:
|
||||
RNS.log("Link closed, exiting now")
|
||||
|
||||
RNS.Reticulum.exit_handler()
|
||||
time.sleep(1.5)
|
||||
os._exit(0)
|
||||
|
||||
# When RNS detects that the download has
|
||||
# started, we'll update our menu state
|
||||
|
@ -471,45 +471,45 @@ def download_began(resource):
|
|||
# or not, we'll update our menu state and
|
||||
# inform the user about how it all went.
|
||||
def download_concluded(resource):
|
||||
global menu_mode, current_filename, download_started, download_finished, download_time
|
||||
download_finished = time.time()
|
||||
download_time = download_finished - download_started
|
||||
global menu_mode, current_filename, download_started, download_finished, download_time
|
||||
download_finished = time.time()
|
||||
download_time = download_finished - download_started
|
||||
|
||||
saved_filename = current_filename
|
||||
saved_filename = current_filename
|
||||
|
||||
|
||||
if resource.status == RNS.Resource.COMPLETE:
|
||||
counter = 0
|
||||
while os.path.isfile(saved_filename):
|
||||
counter += 1
|
||||
saved_filename = current_filename+"."+str(counter)
|
||||
if resource.status == RNS.Resource.COMPLETE:
|
||||
counter = 0
|
||||
while os.path.isfile(saved_filename):
|
||||
counter += 1
|
||||
saved_filename = current_filename+"."+str(counter)
|
||||
|
||||
try:
|
||||
file = open(saved_filename, "wb")
|
||||
file.write(resource.data.read())
|
||||
file.close()
|
||||
menu_mode = "download_concluded"
|
||||
except:
|
||||
menu_mode = "save_error"
|
||||
else:
|
||||
menu_mode = "download_concluded"
|
||||
try:
|
||||
file = open(saved_filename, "wb")
|
||||
file.write(resource.data.read())
|
||||
file.close()
|
||||
menu_mode = "download_concluded"
|
||||
except:
|
||||
menu_mode = "save_error"
|
||||
else:
|
||||
menu_mode = "download_concluded"
|
||||
|
||||
# A convenience function for printing a human-
|
||||
# readable file size
|
||||
def size_str(num, suffix='B'):
|
||||
units = ['','Ki','Mi','Gi','Ti','Pi','Ei','Zi']
|
||||
last_unit = 'Yi'
|
||||
units = ['','Ki','Mi','Gi','Ti','Pi','Ei','Zi']
|
||||
last_unit = 'Yi'
|
||||
|
||||
if suffix == 'b':
|
||||
num *= 8
|
||||
units = ['','K','M','G','T','P','E','Z']
|
||||
last_unit = 'Y'
|
||||
if suffix == 'b':
|
||||
num *= 8
|
||||
units = ['','K','M','G','T','P','E','Z']
|
||||
last_unit = 'Y'
|
||||
|
||||
for unit in units:
|
||||
if abs(num) < 1024.0:
|
||||
return "%3.2f %s%s" % (num, unit, suffix)
|
||||
num /= 1024.0
|
||||
return "%.2f %s%s" % (num, last_unit, suffix)
|
||||
for unit in units:
|
||||
if abs(num) < 1024.0:
|
||||
return "%3.2f %s%s" % (num, unit, suffix)
|
||||
num /= 1024.0
|
||||
return "%.2f %s%s" % (num, last_unit, suffix)
|
||||
|
||||
# A convenience function for clearing the screen
|
||||
def clear_screen():
|
||||
|
@ -523,31 +523,31 @@ def clear_screen():
|
|||
# and parses input of from the user, and then
|
||||
# starts up the desired program mode.
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
parser = argparse.ArgumentParser(description="Simple file transfer server and client utility")
|
||||
parser.add_argument("-s", "--serve", action="store", metavar="dir", help="serve a directory of files to clients")
|
||||
parser.add_argument("--config", action="store", default=None, help="path to alternative Reticulum config directory", type=str)
|
||||
parser.add_argument("destination", nargs="?", default=None, help="hexadecimal hash of the server destination", type=str)
|
||||
args = parser.parse_args()
|
||||
try:
|
||||
parser = argparse.ArgumentParser(description="Simple file transfer server and client utility")
|
||||
parser.add_argument("-s", "--serve", action="store", metavar="dir", help="serve a directory of files to clients")
|
||||
parser.add_argument("--config", action="store", default=None, help="path to alternative Reticulum config directory", type=str)
|
||||
parser.add_argument("destination", nargs="?", default=None, help="hexadecimal hash of the server destination", type=str)
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.config:
|
||||
configarg = args.config
|
||||
else:
|
||||
configarg = None
|
||||
if args.config:
|
||||
configarg = args.config
|
||||
else:
|
||||
configarg = None
|
||||
|
||||
if args.serve:
|
||||
if os.path.isdir(args.serve):
|
||||
server(configarg, args.serve)
|
||||
else:
|
||||
RNS.log("The specified directory does not exist")
|
||||
else:
|
||||
if (args.destination == None):
|
||||
print("")
|
||||
parser.print_help()
|
||||
print("")
|
||||
else:
|
||||
client(args.destination, configarg)
|
||||
if args.serve:
|
||||
if os.path.isdir(args.serve):
|
||||
server(configarg, args.serve)
|
||||
else:
|
||||
RNS.log("The specified directory does not exist")
|
||||
else:
|
||||
if (args.destination == None):
|
||||
print("")
|
||||
parser.print_help()
|
||||
print("")
|
||||
else:
|
||||
client(args.destination, configarg)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("")
|
||||
exit()
|
||||
except KeyboardInterrupt:
|
||||
print("")
|
||||
exit()
|
284
Examples/Link.py
284
Examples/Link.py
|
@ -25,65 +25,65 @@ latest_client_link = None
|
|||
# This initialisation is executed when the users chooses
|
||||
# to run as a server
|
||||
def server(configpath):
|
||||
# We must first initialise Reticulum
|
||||
reticulum = RNS.Reticulum(configpath)
|
||||
|
||||
# Randomly create a new identity for our link example
|
||||
server_identity = RNS.Identity()
|
||||
# We must first initialise Reticulum
|
||||
reticulum = RNS.Reticulum(configpath)
|
||||
|
||||
# Randomly create a new identity for our link example
|
||||
server_identity = RNS.Identity()
|
||||
|
||||
# We create a destination that clients can connect to. We
|
||||
# want clients to create links to this destination, so we
|
||||
# need to create a "single" destination type.
|
||||
server_destination = RNS.Destination(server_identity, RNS.Destination.IN, RNS.Destination.SINGLE, APP_NAME, "linkexample")
|
||||
# We create a destination that clients can connect to. We
|
||||
# want clients to create links to this destination, so we
|
||||
# need to create a "single" destination type.
|
||||
server_destination = RNS.Destination(server_identity, RNS.Destination.IN, RNS.Destination.SINGLE, APP_NAME, "linkexample")
|
||||
|
||||
# We configure a function that will get called every time
|
||||
# a new client creates a link to this destination.
|
||||
server_destination.link_established_callback(client_connected)
|
||||
# We configure a function that will get called every time
|
||||
# a new client creates a link to this destination.
|
||||
server_destination.link_established_callback(client_connected)
|
||||
|
||||
# Everything's ready!
|
||||
# Let's Wait for client requests or user input
|
||||
server_loop(server_destination)
|
||||
# Everything's ready!
|
||||
# Let's Wait for client requests or user input
|
||||
server_loop(server_destination)
|
||||
|
||||
def server_loop(destination):
|
||||
# Let the user know that everything is ready
|
||||
RNS.log("Link example "+RNS.prettyhexrep(destination.hash)+" running, waiting for a connection.")
|
||||
RNS.log("Hit enter to manually send an announce (Ctrl-C to quit)")
|
||||
# Let the user know that everything is ready
|
||||
RNS.log("Link example "+RNS.prettyhexrep(destination.hash)+" running, waiting for a connection.")
|
||||
RNS.log("Hit enter to manually send an announce (Ctrl-C to quit)")
|
||||
|
||||
# We enter a loop that runs until the users exits.
|
||||
# If the user hits enter, we will announce our server
|
||||
# destination on the network, which will let clients
|
||||
# know how to create messages directed towards it.
|
||||
while True:
|
||||
entered = input()
|
||||
destination.announce()
|
||||
RNS.log("Sent announce from "+RNS.prettyhexrep(destination.hash))
|
||||
# We enter a loop that runs until the users exits.
|
||||
# If the user hits enter, we will announce our server
|
||||
# destination on the network, which will let clients
|
||||
# know how to create messages directed towards it.
|
||||
while True:
|
||||
entered = input()
|
||||
destination.announce()
|
||||
RNS.log("Sent announce from "+RNS.prettyhexrep(destination.hash))
|
||||
|
||||
# When a client establishes a link to our server
|
||||
# destination, this function will be called with
|
||||
# a reference to the link.
|
||||
def client_connected(link):
|
||||
global latest_client_link
|
||||
global latest_client_link
|
||||
|
||||
RNS.log("Client connected")
|
||||
link.link_closed_callback(client_disconnected)
|
||||
link.packet_callback(server_packet_received)
|
||||
latest_client_link = link
|
||||
RNS.log("Client connected")
|
||||
link.link_closed_callback(client_disconnected)
|
||||
link.packet_callback(server_packet_received)
|
||||
latest_client_link = link
|
||||
|
||||
def client_disconnected(link):
|
||||
RNS.log("Client disconnected")
|
||||
RNS.log("Client disconnected")
|
||||
|
||||
def server_packet_received(message, packet):
|
||||
global latest_client_link
|
||||
global latest_client_link
|
||||
|
||||
# When data is received over any active link,
|
||||
# it will all be directed to the last client
|
||||
# that connected.
|
||||
text = message.decode("utf-8")
|
||||
RNS.log("Received data on the link: "+text)
|
||||
|
||||
reply_text = "I received \""+text+"\" over the link"
|
||||
reply_data = reply_text.encode("utf-8")
|
||||
RNS.Packet(latest_client_link, reply_data).send()
|
||||
# When data is received over any active link,
|
||||
# it will all be directed to the last client
|
||||
# that connected.
|
||||
text = message.decode("utf-8")
|
||||
RNS.log("Received data on the link: "+text)
|
||||
|
||||
reply_text = "I received \""+text+"\" over the link"
|
||||
reply_data = reply_text.encode("utf-8")
|
||||
RNS.Packet(latest_client_link, reply_data).send()
|
||||
|
||||
|
||||
##########################################################
|
||||
|
@ -96,112 +96,112 @@ server_link = None
|
|||
# This initialisation is executed when the users chooses
|
||||
# to run as a client
|
||||
def client(destination_hexhash, configpath):
|
||||
# We need a binary representation of the destination
|
||||
# hash that was entered on the command line
|
||||
try:
|
||||
if len(destination_hexhash) != 20:
|
||||
raise ValueError("Destination length is invalid, must be 20 hexadecimal characters (10 bytes)")
|
||||
destination_hash = bytes.fromhex(destination_hexhash)
|
||||
except:
|
||||
RNS.log("Invalid destination entered. Check your input!\n")
|
||||
exit()
|
||||
# We need a binary representation of the destination
|
||||
# hash that was entered on the command line
|
||||
try:
|
||||
if len(destination_hexhash) != 20:
|
||||
raise ValueError("Destination length is invalid, must be 20 hexadecimal characters (10 bytes)")
|
||||
destination_hash = bytes.fromhex(destination_hexhash)
|
||||
except:
|
||||
RNS.log("Invalid destination entered. Check your input!\n")
|
||||
exit()
|
||||
|
||||
# We must first initialise Reticulum
|
||||
reticulum = RNS.Reticulum(configpath)
|
||||
# We must first initialise Reticulum
|
||||
reticulum = RNS.Reticulum(configpath)
|
||||
|
||||
# Check if we know a path to the destination
|
||||
if not RNS.Transport.hasPath(destination_hash):
|
||||
RNS.log("Destination is not yet known. Requesting path and waiting for announce to arrive...")
|
||||
RNS.Transport.requestPath(destination_hash)
|
||||
while not RNS.Transport.hasPath(destination_hash):
|
||||
time.sleep(0.1)
|
||||
# Check if we know a path to the destination
|
||||
if not RNS.Transport.hasPath(destination_hash):
|
||||
RNS.log("Destination is not yet known. Requesting path and waiting for announce to arrive...")
|
||||
RNS.Transport.requestPath(destination_hash)
|
||||
while not RNS.Transport.hasPath(destination_hash):
|
||||
time.sleep(0.1)
|
||||
|
||||
# Recall the server identity
|
||||
server_identity = RNS.Identity.recall(destination_hash)
|
||||
# Recall the server identity
|
||||
server_identity = RNS.Identity.recall(destination_hash)
|
||||
|
||||
# Inform the user that we'll begin connecting
|
||||
RNS.log("Establishing link with server...")
|
||||
# Inform the user that we'll begin connecting
|
||||
RNS.log("Establishing link with server...")
|
||||
|
||||
# When the server identity is known, we set
|
||||
# up a destination
|
||||
server_destination = RNS.Destination(server_identity, RNS.Destination.OUT, RNS.Destination.SINGLE, APP_NAME, "linkexample")
|
||||
# When the server identity is known, we set
|
||||
# up a destination
|
||||
server_destination = RNS.Destination(server_identity, RNS.Destination.OUT, RNS.Destination.SINGLE, APP_NAME, "linkexample")
|
||||
|
||||
# And create a link
|
||||
link = RNS.Link(server_destination)
|
||||
# And create a link
|
||||
link = RNS.Link(server_destination)
|
||||
|
||||
# We set a callback that will get executed
|
||||
# every time a packet is received over the
|
||||
# link
|
||||
link.packet_callback(client_packet_received)
|
||||
# We set a callback that will get executed
|
||||
# every time a packet is received over the
|
||||
# link
|
||||
link.packet_callback(client_packet_received)
|
||||
|
||||
# We'll also set up functions to inform the
|
||||
# user when the link is established or closed
|
||||
link.link_established_callback(link_established)
|
||||
link.link_closed_callback(link_closed)
|
||||
# We'll also set up functions to inform the
|
||||
# user when the link is established or closed
|
||||
link.link_established_callback(link_established)
|
||||
link.link_closed_callback(link_closed)
|
||||
|
||||
# Everything is set up, so let's enter a loop
|
||||
# for the user to interact with the example
|
||||
client_loop()
|
||||
# Everything is set up, so let's enter a loop
|
||||
# for the user to interact with the example
|
||||
client_loop()
|
||||
|
||||
def client_loop():
|
||||
global server_link
|
||||
global server_link
|
||||
|
||||
# Wait for the link to become active
|
||||
while not server_link:
|
||||
time.sleep(0.1)
|
||||
# Wait for the link to become active
|
||||
while not server_link:
|
||||
time.sleep(0.1)
|
||||
|
||||
should_quit = False
|
||||
while not should_quit:
|
||||
try:
|
||||
print("> ", end=" ")
|
||||
text = input()
|
||||
should_quit = False
|
||||
while not should_quit:
|
||||
try:
|
||||
print("> ", end=" ")
|
||||
text = input()
|
||||
|
||||
# Check if we should quit the example
|
||||
if text == "quit" or text == "q" or text == "exit":
|
||||
should_quit = True
|
||||
server_link.teardown()
|
||||
# Check if we should quit the example
|
||||
if text == "quit" or text == "q" or text == "exit":
|
||||
should_quit = True
|
||||
server_link.teardown()
|
||||
|
||||
# If not, send the entered text over the link
|
||||
if text != "":
|
||||
data = text.encode("utf-8")
|
||||
RNS.Packet(server_link, data).send()
|
||||
except Exception as e:
|
||||
should_quit = True
|
||||
server_link.teardown()
|
||||
# If not, send the entered text over the link
|
||||
if text != "":
|
||||
data = text.encode("utf-8")
|
||||
RNS.Packet(server_link, data).send()
|
||||
except Exception as e:
|
||||
should_quit = True
|
||||
server_link.teardown()
|
||||
|
||||
# This function is called when a link
|
||||
# has been established with the server
|
||||
def link_established(link):
|
||||
# We store a reference to the link
|
||||
# instance for later use
|
||||
global server_link
|
||||
server_link = link
|
||||
# We store a reference to the link
|
||||
# instance for later use
|
||||
global server_link
|
||||
server_link = link
|
||||
|
||||
# Inform the user that the server is
|
||||
# connected
|
||||
RNS.log("Link established with server, enter some text to send, or \"quit\" to quit")
|
||||
# Inform the user that the server is
|
||||
# connected
|
||||
RNS.log("Link established with server, enter some text to send, or \"quit\" to quit")
|
||||
|
||||
# When a link is closed, we'll inform the
|
||||
# user, and exit the program
|
||||
def link_closed(link):
|
||||
if link.teardown_reason == RNS.Link.TIMEOUT:
|
||||
RNS.log("The link timed out, exiting now")
|
||||
elif link.teardown_reason == RNS.Link.DESTINATION_CLOSED:
|
||||
RNS.log("The link was closed by the server, exiting now")
|
||||
else:
|
||||
RNS.log("Link closed, exiting now")
|
||||
|
||||
RNS.Reticulum.exit_handler()
|
||||
time.sleep(1.5)
|
||||
os._exit(0)
|
||||
if link.teardown_reason == RNS.Link.TIMEOUT:
|
||||
RNS.log("The link timed out, exiting now")
|
||||
elif link.teardown_reason == RNS.Link.DESTINATION_CLOSED:
|
||||
RNS.log("The link was closed by the server, exiting now")
|
||||
else:
|
||||
RNS.log("Link closed, exiting now")
|
||||
|
||||
RNS.Reticulum.exit_handler()
|
||||
time.sleep(1.5)
|
||||
os._exit(0)
|
||||
|
||||
# When a packet is received over the link, we
|
||||
# simply print out the data.
|
||||
def client_packet_received(message, packet):
|
||||
text = message.decode("utf-8")
|
||||
RNS.log("Received data on the link: "+text)
|
||||
print("> ", end=" ")
|
||||
sys.stdout.flush()
|
||||
text = message.decode("utf-8")
|
||||
RNS.log("Received data on the link: "+text)
|
||||
print("> ", end=" ")
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
##########################################################
|
||||
|
@ -212,28 +212,28 @@ def client_packet_received(message, packet):
|
|||
# and parses input of from the user, and then
|
||||
# starts up the desired program mode.
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
parser = argparse.ArgumentParser(description="Simple link example")
|
||||
parser.add_argument("-s", "--server", action="store_true", help="wait for incoming link requests from clients")
|
||||
parser.add_argument("--config", action="store", default=None, help="path to alternative Reticulum config directory", type=str)
|
||||
parser.add_argument("destination", nargs="?", default=None, help="hexadecimal hash of the server destination", type=str)
|
||||
args = parser.parse_args()
|
||||
try:
|
||||
parser = argparse.ArgumentParser(description="Simple link example")
|
||||
parser.add_argument("-s", "--server", action="store_true", help="wait for incoming link requests from clients")
|
||||
parser.add_argument("--config", action="store", default=None, help="path to alternative Reticulum config directory", type=str)
|
||||
parser.add_argument("destination", nargs="?", default=None, help="hexadecimal hash of the server destination", type=str)
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.config:
|
||||
configarg = args.config
|
||||
else:
|
||||
configarg = None
|
||||
if args.config:
|
||||
configarg = args.config
|
||||
else:
|
||||
configarg = None
|
||||
|
||||
if args.server:
|
||||
server(configarg)
|
||||
else:
|
||||
if (args.destination == None):
|
||||
print("")
|
||||
parser.print_help()
|
||||
print("")
|
||||
else:
|
||||
client(args.destination, configarg)
|
||||
if args.server:
|
||||
server(configarg)
|
||||
else:
|
||||
if (args.destination == None):
|
||||
print("")
|
||||
parser.print_help()
|
||||
print("")
|
||||
else:
|
||||
client(args.destination, configarg)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("")
|
||||
exit()
|
||||
except KeyboardInterrupt:
|
||||
print("")
|
||||
exit()
|
|
@ -15,45 +15,45 @@ APP_NAME = "example_utilitites"
|
|||
|
||||
# This initialisation is executed when the program is started
|
||||
def program_setup(configpath):
|
||||
# We must first initialise Reticulum
|
||||
reticulum = RNS.Reticulum(configpath)
|
||||
|
||||
# Randomly create a new identity for our example
|
||||
identity = RNS.Identity()
|
||||
# We must first initialise Reticulum
|
||||
reticulum = RNS.Reticulum(configpath)
|
||||
|
||||
# Randomly create a new identity for our example
|
||||
identity = RNS.Identity()
|
||||
|
||||
# Using the identity we just created, we create a destination.
|
||||
# Destinations are endpoints in Reticulum, that can be addressed
|
||||
# and communicated with. Destinations can also announce their
|
||||
# existence, which will let the network know they are reachable
|
||||
# and autoomatically create paths to them, from anywhere else
|
||||
# in the network.
|
||||
destination = RNS.Destination(identity, RNS.Destination.IN, RNS.Destination.SINGLE, APP_NAME, "minimalsample")
|
||||
# Using the identity we just created, we create a destination.
|
||||
# Destinations are endpoints in Reticulum, that can be addressed
|
||||
# and communicated with. Destinations can also announce their
|
||||
# existence, which will let the network know they are reachable
|
||||
# and autoomatically create paths to them, from anywhere else
|
||||
# in the network.
|
||||
destination = RNS.Destination(identity, RNS.Destination.IN, RNS.Destination.SINGLE, APP_NAME, "minimalsample")
|
||||
|
||||
# We configure the destination to automatically prove all
|
||||
# packets adressed to it. By doing this, RNS will automatically
|
||||
# generate a proof for each incoming packet and transmit it
|
||||
# back to the sender of that packet. This will let anyone that
|
||||
# tries to communicate with the destination know whether their
|
||||
# communication was received correctly.
|
||||
destination.set_proof_strategy(RNS.Destination.PROVE_ALL)
|
||||
|
||||
# Everything's ready!
|
||||
# Let's hand over control to the announce loop
|
||||
announceLoop(destination)
|
||||
# We configure the destination to automatically prove all
|
||||
# packets adressed to it. By doing this, RNS will automatically
|
||||
# generate a proof for each incoming packet and transmit it
|
||||
# back to the sender of that packet. This will let anyone that
|
||||
# tries to communicate with the destination know whether their
|
||||
# communication was received correctly.
|
||||
destination.set_proof_strategy(RNS.Destination.PROVE_ALL)
|
||||
|
||||
# Everything's ready!
|
||||
# Let's hand over control to the announce loop
|
||||
announceLoop(destination)
|
||||
|
||||
|
||||
def announceLoop(destination):
|
||||
# Let the user know that everything is ready
|
||||
RNS.log("Minimal example "+RNS.prettyhexrep(destination.hash)+" running, hit enter to manually send an announce (Ctrl-C to quit)")
|
||||
# Let the user know that everything is ready
|
||||
RNS.log("Minimal example "+RNS.prettyhexrep(destination.hash)+" running, hit enter to manually send an announce (Ctrl-C to quit)")
|
||||
|
||||
# We enter a loop that runs until the users exits.
|
||||
# If the user hits enter, we will announce our server
|
||||
# destination on the network, which will let clients
|
||||
# know how to create messages directed towards it.
|
||||
while True:
|
||||
entered = input()
|
||||
destination.announce()
|
||||
RNS.log("Sent announce from "+RNS.prettyhexrep(destination.hash))
|
||||
# We enter a loop that runs until the users exits.
|
||||
# If the user hits enter, we will announce our server
|
||||
# destination on the network, which will let clients
|
||||
# know how to create messages directed towards it.
|
||||
while True:
|
||||
entered = input()
|
||||
destination.announce()
|
||||
RNS.log("Sent announce from "+RNS.prettyhexrep(destination.hash))
|
||||
|
||||
|
||||
##########################################################
|
||||
|
@ -64,18 +64,18 @@ def announceLoop(destination):
|
|||
# and parses input from the user, and then starts
|
||||
# the desired program mode.
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
parser = argparse.ArgumentParser(description="Bare minimum example to start Reticulum and create a destination")
|
||||
parser.add_argument("--config", action="store", default=None, help="path to alternative Reticulum config directory", type=str)
|
||||
args = parser.parse_args()
|
||||
try:
|
||||
parser = argparse.ArgumentParser(description="Bare minimum example to start Reticulum and create a destination")
|
||||
parser.add_argument("--config", action="store", default=None, help="path to alternative Reticulum config directory", type=str)
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.config:
|
||||
configarg = args.config
|
||||
else:
|
||||
configarg = None
|
||||
if args.config:
|
||||
configarg = args.config
|
||||
else:
|
||||
configarg = None
|
||||
|
||||
program_setup(configarg)
|
||||
program_setup(configarg)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("")
|
||||
exit()
|
||||
except KeyboardInterrupt:
|
||||
print("")
|
||||
exit()
|
Loading…
Add table
Add a link
Reference in a new issue