initial rough-cut of fetcher code
This commit is contained in:
commit
c347d800ce
2 changed files with 297 additions and 0 deletions
295
fetcher.py
Executable file
295
fetcher.py
Executable file
|
|
@ -0,0 +1,295 @@
|
|||
#!/bin/python
|
||||
|
||||
import os
|
||||
import io
|
||||
import shutil
|
||||
import argparse
|
||||
import time
|
||||
import RNS
|
||||
# from io import BufferedReader
|
||||
# import io
|
||||
# import LXMF
|
||||
|
||||
|
||||
# class Fetcher:
|
||||
# # DEFAULT_PATH = "/page/index.mu"
|
||||
# DEFAULT_TIMEOUT = 10
|
||||
# DEFAULT_CACHE_TIME = 12*60*60
|
||||
|
||||
# NO_PATH = 0x00
|
||||
# PATH_REQUESTED = 0x01
|
||||
# ESTABLISHING_LINK = 0x02
|
||||
# LINK_TIMEOUT = 0x03
|
||||
# LINK_ESTABLISHED = 0x04
|
||||
# REQUESTING = 0x05
|
||||
# REQUEST_SENT = 0x06
|
||||
# REQUEST_FAILED = 0x07
|
||||
# REQUEST_TIMEOUT = 0x08
|
||||
# RECEIVING_RESPONSE = 0x09
|
||||
# DISCONECTED = 0xFE
|
||||
# DONE = 0xFF
|
||||
|
||||
|
||||
# def retrieve_url(self, url, request_data = None):
|
||||
# self.previous_destination_hash = self.destination_hash
|
||||
# self.previous_path = self.path
|
||||
|
||||
# destination_hash = None
|
||||
# path = None
|
||||
|
||||
# components = url.split(":")
|
||||
# if len(components) == 1:
|
||||
# if len(components[0]) == (RNS.Reticulum.TRUNCATED_HASHLENGTH//8)*2:
|
||||
# try:
|
||||
# destination_hash = bytes.fromhex(components[0])
|
||||
# except Exception as e:
|
||||
# raise ValueError("Malformed URL")
|
||||
# # path = Browser.DEFAULT_PATH
|
||||
# else:
|
||||
# raise ValueError("Malformed URL")
|
||||
# elif len(components) == 2:
|
||||
# if len(components[0]) == (RNS.Reticulum.TRUNCATED_HASHLENGTH//8)*2:
|
||||
# try:
|
||||
# destination_hash = bytes.fromhex(components[0])
|
||||
# except Exception as e:
|
||||
# raise ValueError("Malformed URL")
|
||||
# path = components[1]
|
||||
# # if len(path) == 0:
|
||||
# # path = Browser.DEFAULT_PATH
|
||||
# else:
|
||||
# if len(components[0]) == 0:
|
||||
# if self.destination_hash != None:
|
||||
# destination_hash = self.destination_hash
|
||||
# path = components[1]
|
||||
# if len(path) == 0:
|
||||
# path = Browser.DEFAULT_PATH
|
||||
# else:
|
||||
# raise ValueError("Malformed URL")
|
||||
# else:
|
||||
# raise ValueError("Malformed URL")
|
||||
# else:
|
||||
# raise ValueError("Malformed URL")
|
||||
|
||||
# if destination_hash != None and path != None:
|
||||
# if path.startswith("/file/"):
|
||||
# if destination_hash != self.loopback:
|
||||
# if destination_hash == self.destination_hash:
|
||||
# self.download_file(destination_hash, path)
|
||||
# else:
|
||||
# RNS.log("Cannot request file download from a node that is not currently connected.", RNS.LOG_ERROR)
|
||||
# RNS.log("The requested URL was: "+str(url), RNS.LOG_ERROR)
|
||||
# else:
|
||||
# self.download_local_file(path)
|
||||
# else:
|
||||
# self.set_destination_hash(destination_hash)
|
||||
# self.set_path(path)
|
||||
# self.set_request_data(request_data)
|
||||
# self.load_page()
|
||||
|
||||
# def download_file(self, destination_hash, path):
|
||||
# if self.link == None or self.link.destination.hash != self.destination_hash:
|
||||
# if not RNS.Transport.has_path(self.destination_hash):
|
||||
# self.status = Browser.NO_PATH
|
||||
# self.update_display()
|
||||
|
||||
# RNS.Transport.request_path(self.destination_hash)
|
||||
# self.status = Browser.PATH_REQUESTED
|
||||
# self.update_display()
|
||||
|
||||
# pr_time = time.time()+RNS.Transport.first_hop_timeout(self.destination_hash)
|
||||
# while not RNS.Transport.has_path(self.destination_hash):
|
||||
# now = time.time()
|
||||
# if now > pr_time+self.timeout:
|
||||
# self.request_timeout()
|
||||
# return
|
||||
|
||||
# time.sleep(0.25)
|
||||
|
||||
# self.status = Browser.ESTABLISHING_LINK
|
||||
# self.update_display()
|
||||
|
||||
# identity = RNS.Identity.recall(self.destination_hash)
|
||||
# destination = RNS.Destination(
|
||||
# identity,
|
||||
# RNS.Destination.OUT,
|
||||
# RNS.Destination.SINGLE,
|
||||
# self.app_name,
|
||||
# self.aspects
|
||||
# )
|
||||
|
||||
# self.link = RNS.Link(destination, established_callback = self.link_established, closed_callback = self.link_closed)
|
||||
|
||||
# while self.status == Browser.ESTABLISHING_LINK:
|
||||
# time.sleep(0.1)
|
||||
|
||||
# if self.status != Browser.LINK_ESTABLISHED:
|
||||
# return
|
||||
|
||||
# self.update_display()
|
||||
|
||||
# if self.link != None and self.link.destination.hash == self.destination_hash:
|
||||
# # Send the request
|
||||
# self.status = Browser.REQUESTING
|
||||
# self.response_progress = 0
|
||||
# self.response_speed = None
|
||||
# self.progress_updated_at = None
|
||||
# self.previous_progress = 0
|
||||
# self.response_size = None
|
||||
# self.response_transfer_size = None
|
||||
# self.saved_file_name = None
|
||||
|
||||
# self.update_display()
|
||||
# receipt = self.link.request(
|
||||
# path,
|
||||
# data = None,
|
||||
# response_callback = self.file_received,
|
||||
# failed_callback = self.request_failed,
|
||||
# progress_callback = self.response_progressed
|
||||
# )
|
||||
|
||||
# if receipt:
|
||||
# self.last_request_receipt = receipt
|
||||
# self.last_request_id = receipt.request_id
|
||||
# self.status = Browser.REQUEST_SENT
|
||||
# self.update_display()
|
||||
# else:
|
||||
# self.link.teardown()
|
||||
|
||||
# global server link
|
||||
server_link = None
|
||||
file = None
|
||||
|
||||
def link_established(link):
|
||||
global server_link
|
||||
server_link = link
|
||||
print("link established")
|
||||
|
||||
def link_closed():
|
||||
print("link closed")
|
||||
|
||||
def file_received(request_receipt):
|
||||
global file
|
||||
file = True
|
||||
try:
|
||||
if type(request_receipt.response) == io.BufferedReader:
|
||||
if request_receipt.metadata != None:
|
||||
file_name = os.path.basename(request_receipt.metadata["name"].decode("utf-8"))
|
||||
file_handle = request_receipt.response
|
||||
file_destination = "."+"/"+file_name
|
||||
|
||||
counter = 0
|
||||
while os.path.isfile(file_destination):
|
||||
counter += 1
|
||||
file_destination = "."+"/"+file_name+"."+str(counter)
|
||||
|
||||
shutil.move(file_handle.name, file_destination)
|
||||
|
||||
else:
|
||||
file_name = request_receipt.response[0]
|
||||
file_data = request_receipt.response[1]
|
||||
file_destination_name = os.path.basename(file_name)
|
||||
file_destination = "."+"/"+file_destination_name
|
||||
|
||||
counter = 0
|
||||
while os.path.isfile(file_destination):
|
||||
counter += 1
|
||||
file_destination = "."+"/"+file_destination_name+"."+str(counter)
|
||||
|
||||
fh = open(file_destination, "wb")
|
||||
fh.write(file_data)
|
||||
fh.close()
|
||||
|
||||
# self.saved_file_name = file_destination.replace(self.app.downloads_path+"/", "", 1)
|
||||
|
||||
# self.status = Browser.DONE
|
||||
# self.response_progress = 0
|
||||
# self.response_speed = None
|
||||
# self.progress_updated_at = None
|
||||
# self.previous_progress = 0
|
||||
|
||||
# self.update_display()
|
||||
except Exception as e:
|
||||
RNS.log("An error occurred while handling file response. The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||
|
||||
|
||||
print("file received")
|
||||
|
||||
def request_failed(req_receipt):
|
||||
print("request failed")
|
||||
# print(str(e))
|
||||
|
||||
def response_progressed(req_receipt):
|
||||
# print("response progressed")
|
||||
return
|
||||
|
||||
parser = argparse.ArgumentParser(description="request a resource from a target node")
|
||||
parser.add_argument("URL", help="the LXMF URL of the resource to be fetched")
|
||||
|
||||
args = parser.parse_args()
|
||||
arglist = args.URL.split(":")
|
||||
dest_hash = arglist[0]
|
||||
resource_path = arglist[1]
|
||||
print(dest_hash)
|
||||
print(resource_path)
|
||||
|
||||
|
||||
r = RNS.Reticulum()
|
||||
RNS.loglevel = RNS.LOG_DEBUG
|
||||
# router = LXMF.LXMRouter(storagepath="./tmp2")
|
||||
# router.register_delivery_callback(delivery_callback)
|
||||
ident = RNS.Identity()
|
||||
|
||||
dest_hash = bytes.fromhex(dest_hash)
|
||||
dest_ident = RNS.Identity.recall(dest_hash)
|
||||
|
||||
# need these to connect to a nomadnetwork node
|
||||
app_name = "nomadnetwork"
|
||||
aspects = "node"
|
||||
|
||||
destination = RNS.Destination(
|
||||
dest_ident,
|
||||
RNS.Destination.OUT,
|
||||
RNS.Destination.SINGLE,
|
||||
app_name,
|
||||
aspects
|
||||
)
|
||||
|
||||
|
||||
# with open(args.GCODE_FILE, "rb") as f:
|
||||
# contents = f.read()
|
||||
# content_size = len(contents)
|
||||
|
||||
# Look up the path to the destination.
|
||||
print("looking up path to destination...")
|
||||
if not RNS.Transport.has_path(dest_hash):
|
||||
RNS.Transport.request_path(dest_hash)
|
||||
while not RNS.Transport.has_path(dest_hash):
|
||||
time.sleep(0.1)
|
||||
|
||||
# establish link
|
||||
link = RNS.Link(destination, established_callback = link_established, closed_callback = link_closed)
|
||||
|
||||
|
||||
while not server_link:
|
||||
time.sleep(0.1)
|
||||
|
||||
receipt = link.request(
|
||||
resource_path,
|
||||
data = None,
|
||||
response_callback = file_received,
|
||||
failed_callback = request_failed,
|
||||
progress_callback = response_progressed
|
||||
)
|
||||
|
||||
while not file:
|
||||
time.sleep(0.1)
|
||||
|
||||
# if receipt:
|
||||
# last_request_receipt = receipt
|
||||
# last_request_id = receipt.request_id
|
||||
# # status = Browser.REQUEST_SENT
|
||||
# # update_display()
|
||||
# else:
|
||||
# link.teardown()
|
||||
|
||||
# print(ident)
|
||||
2
requirements.txt
Normal file
2
requirements.txt
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
rns
|
||||
lxmf
|
||||
Loading…
Add table
Add a link
Reference in a new issue