mirror of
https://github.com/markqvist/NomadNet.git
synced 2025-05-17 21:30:25 -04:00
Added file hosting to nodes.
This commit is contained in:
parent
903c75db0f
commit
e606892ff0
3 changed files with 103 additions and 8 deletions
|
@ -44,7 +44,6 @@ class Node:
|
||||||
|
|
||||||
for page in self.servedpages:
|
for page in self.servedpages:
|
||||||
request_path = "/page"+page.replace(self.app.pagespath, "")
|
request_path = "/page"+page.replace(self.app.pagespath, "")
|
||||||
|
|
||||||
self.destination.register_request_handler(
|
self.destination.register_request_handler(
|
||||||
request_path,
|
request_path,
|
||||||
response_generator = self.serve_page,
|
response_generator = self.serve_page,
|
||||||
|
@ -55,6 +54,14 @@ class Node:
|
||||||
self.servedfiles = []
|
self.servedfiles = []
|
||||||
self.scan_files(self.app.filespath)
|
self.scan_files(self.app.filespath)
|
||||||
|
|
||||||
|
for file in self.servedfiles:
|
||||||
|
request_path = "/file"+file.replace(self.app.filespath, "")
|
||||||
|
self.destination.register_request_handler(
|
||||||
|
request_path,
|
||||||
|
response_generator = self.serve_file,
|
||||||
|
allow = RNS.Destination.ALLOW_ALL
|
||||||
|
)
|
||||||
|
|
||||||
def scan_pages(self, base_path):
|
def scan_pages(self, base_path):
|
||||||
files = [file for file in os.listdir(base_path) if os.path.isfile(os.path.join(base_path, file)) and file[:1] != "."]
|
files = [file for file in os.listdir(base_path) if os.path.isfile(os.path.join(base_path, file)) and file[:1] != "."]
|
||||||
directories = [file for file in os.listdir(base_path) if os.path.isdir(os.path.join(base_path, file)) and file[:1] != "."]
|
directories = [file for file in os.listdir(base_path) if os.path.isdir(os.path.join(base_path, file)) and file[:1] != "."]
|
||||||
|
@ -76,10 +83,10 @@ class Node:
|
||||||
self.scan_files(base_path+"/"+directory)
|
self.scan_files(base_path+"/"+directory)
|
||||||
|
|
||||||
def serve_page(self, path, data, request_id, remote_identity, requested_at):
|
def serve_page(self, path, data, request_id, remote_identity, requested_at):
|
||||||
RNS.log("Request "+RNS.prettyhexrep(request_id)+" for: "+str(path), RNS.LOG_VERBOSE)
|
RNS.log("Page request "+RNS.prettyhexrep(request_id)+" for: "+str(path), RNS.LOG_VERBOSE)
|
||||||
file_path = path.replace("/page", self.app.pagespath, 1)
|
file_path = path.replace("/page", self.app.pagespath, 1)
|
||||||
try:
|
try:
|
||||||
RNS.log("Serving file: "+file_path, RNS.LOG_VERBOSE)
|
RNS.log("Serving page: "+file_path, RNS.LOG_VERBOSE)
|
||||||
fh = open(file_path, "rb")
|
fh = open(file_path, "rb")
|
||||||
response_data = fh.read()
|
response_data = fh.read()
|
||||||
fh.close()
|
fh.close()
|
||||||
|
@ -90,6 +97,22 @@ class Node:
|
||||||
RNS.log("The contained exception was: "+str(e), RNS.LOG_ERROR)
|
RNS.log("The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
# TODO: Improve file handling, this will be slow for large files
|
||||||
|
def serve_file(self, path, data, request_id, remote_identity, requested_at):
|
||||||
|
RNS.log("File request "+RNS.prettyhexrep(request_id)+" for: "+str(path), RNS.LOG_VERBOSE)
|
||||||
|
file_path = path.replace("/file", self.app.filespath, 1)
|
||||||
|
file_name = path.replace("/file/", "", 1)
|
||||||
|
try:
|
||||||
|
RNS.log("Serving file: "+file_path, RNS.LOG_VERBOSE)
|
||||||
|
fh = open(file_path, "rb")
|
||||||
|
file_data = fh.read()
|
||||||
|
fh.close()
|
||||||
|
return [file_name, file_data]
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
RNS.log("Error occurred while handling request "+RNS.prettyhexrep(request_id)+" for: "+str(path), RNS.LOG_ERROR)
|
||||||
|
RNS.log("The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||||
|
return None
|
||||||
|
|
||||||
def serve_default_index(self, path, data, request_id, remote_identity, requested_at):
|
def serve_default_index(self, path, data, request_id, remote_identity, requested_at):
|
||||||
RNS.log("Serving default index for request "+RNS.prettyhexrep(request_id)+" for: "+str(path), RNS.LOG_VERBOSE)
|
RNS.log("Serving default index for request "+RNS.prettyhexrep(request_id)+" for: "+str(path), RNS.LOG_VERBOSE)
|
||||||
|
|
|
@ -54,6 +54,8 @@ class NomadNetworkApp:
|
||||||
self.pagespath = self.configdir+"/storage/pages"
|
self.pagespath = self.configdir+"/storage/pages"
|
||||||
self.filespath = self.configdir+"/storage/files"
|
self.filespath = self.configdir+"/storage/files"
|
||||||
|
|
||||||
|
self.downloads_path = os.path.expanduser("~/Downloads")
|
||||||
|
|
||||||
if not os.path.isdir(self.storagepath):
|
if not os.path.isdir(self.storagepath):
|
||||||
os.makedirs(self.storagepath)
|
os.makedirs(self.storagepath)
|
||||||
|
|
||||||
|
@ -254,6 +256,10 @@ class NomadNetworkApp:
|
||||||
value = self.config["client"].as_bool(option)
|
value = self.config["client"].as_bool(option)
|
||||||
self.enable_client = value
|
self.enable_client = value
|
||||||
|
|
||||||
|
if option == "downloads_path":
|
||||||
|
value = self.config["client"]["downloads_path"]
|
||||||
|
self.downloads_path = os.path.expanduser(value)
|
||||||
|
|
||||||
if option == "user_interface":
|
if option == "user_interface":
|
||||||
value = value.lower()
|
value = value.lower()
|
||||||
if value == "none":
|
if value == "none":
|
||||||
|
@ -391,6 +397,7 @@ destination = file
|
||||||
|
|
||||||
enable_client = yes
|
enable_client = yes
|
||||||
user_interface = text
|
user_interface = text
|
||||||
|
downloads_path = ~/Downloads
|
||||||
|
|
||||||
[textui]
|
[textui]
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import RNS
|
import RNS
|
||||||
|
import os
|
||||||
import time
|
import time
|
||||||
import urwid
|
import urwid
|
||||||
import nomadnet
|
import nomadnet
|
||||||
|
@ -54,6 +55,7 @@ class Browser:
|
||||||
self.response_progress = 0
|
self.response_progress = 0
|
||||||
self.response_size = None
|
self.response_size = None
|
||||||
self.response_transfer_size = None
|
self.response_transfer_size = None
|
||||||
|
self.saved_file_name = None
|
||||||
self.page_data = None
|
self.page_data = None
|
||||||
self.displayed_page_data = None
|
self.displayed_page_data = None
|
||||||
self.auth_identity = auth_identity
|
self.auth_identity = auth_identity
|
||||||
|
@ -248,9 +250,16 @@ class Browser:
|
||||||
raise ValueError("Malformed URL")
|
raise ValueError("Malformed URL")
|
||||||
|
|
||||||
if destination_hash != None and path != None:
|
if destination_hash != None and path != None:
|
||||||
self.set_destination_hash(destination_hash)
|
if path.startswith("/file/"):
|
||||||
self.set_path(path)
|
if destination_hash == self.destination_hash:
|
||||||
self.load_page()
|
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.set_destination_hash(destination_hash)
|
||||||
|
self.set_path(path)
|
||||||
|
self.load_page()
|
||||||
|
|
||||||
def set_destination_hash(self, destination_hash):
|
def set_destination_hash(self, destination_hash):
|
||||||
if len(destination_hash) == RNS.Identity.TRUNCATED_HASHLENGTH//8:
|
if len(destination_hash) == RNS.Identity.TRUNCATED_HASHLENGTH//8:
|
||||||
|
@ -268,6 +277,33 @@ class Browser:
|
||||||
self.timeout = timeout
|
self.timeout = timeout
|
||||||
|
|
||||||
|
|
||||||
|
def download_file(self, destination_hash, path):
|
||||||
|
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_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()
|
||||||
|
|
||||||
|
|
||||||
def load_page(self):
|
def load_page(self):
|
||||||
load_thread = threading.Thread(target=self.__load)
|
load_thread = threading.Thread(target=self.__load)
|
||||||
load_thread.setDaemon(True)
|
load_thread.setDaemon(True)
|
||||||
|
@ -278,7 +314,7 @@ class Browser:
|
||||||
# If an established link exists, but it doesn't match the target
|
# If an established link exists, but it doesn't match the target
|
||||||
# destination, we close and clear it.
|
# destination, we close and clear it.
|
||||||
if self.link != None and self.link.destination.hash != self.destination_hash:
|
if self.link != None and self.link.destination.hash != self.destination_hash:
|
||||||
self.link.close()
|
self.link.teardown()
|
||||||
self.link = None
|
self.link = None
|
||||||
|
|
||||||
# If no link to the destination exists, we create one.
|
# If no link to the destination exists, we create one.
|
||||||
|
@ -327,6 +363,8 @@ class Browser:
|
||||||
self.response_progress = 0
|
self.response_progress = 0
|
||||||
self.response_size = None
|
self.response_size = None
|
||||||
self.response_transfer_size = None
|
self.response_transfer_size = None
|
||||||
|
self.saved_file_name = None
|
||||||
|
|
||||||
|
|
||||||
self.update_display()
|
self.update_display()
|
||||||
receipt = self.link.request(
|
receipt = self.link.request(
|
||||||
|
@ -383,6 +421,30 @@ class Browser:
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
RNS.log("An error occurred while handling response. The contained exception was: "+str(e))
|
RNS.log("An error occurred while handling response. The contained exception was: "+str(e))
|
||||||
|
|
||||||
|
|
||||||
|
def file_received(self, request_receipt):
|
||||||
|
try:
|
||||||
|
file_name = request_receipt.response[0]
|
||||||
|
file_data = request_receipt.response[1]
|
||||||
|
file_destination = self.app.downloads_path+"/"+file_name
|
||||||
|
|
||||||
|
counter = 0
|
||||||
|
while os.path.isfile(file_destination):
|
||||||
|
counter += 1
|
||||||
|
file_destination = self.app.downloads_path+"/"+file_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.update_display()
|
||||||
|
except Exception as e:
|
||||||
|
RNS.log("An error occurred while handling file response. The contained exception was: "+str(e))
|
||||||
|
|
||||||
|
|
||||||
def request_failed(self, request_receipt=None):
|
def request_failed(self, request_receipt=None):
|
||||||
if request_receipt != None:
|
if request_receipt != None:
|
||||||
|
@ -453,7 +515,10 @@ class Browser:
|
||||||
elif self.status == Browser.RECEIVING_RESPONSE:
|
elif self.status == Browser.RECEIVING_RESPONSE:
|
||||||
return "Receiving response..."
|
return "Receiving response..."
|
||||||
elif self.status == Browser.DONE:
|
elif self.status == Browser.DONE:
|
||||||
return "Done"+stats_string
|
if self.saved_file_name == None:
|
||||||
|
return "Done"+stats_string
|
||||||
|
else:
|
||||||
|
return "Saved "+str(self.saved_file_name)+stats_string
|
||||||
elif self.status == Browser.DISCONECTED:
|
elif self.status == Browser.DISCONECTED:
|
||||||
return "Disconnected"
|
return "Disconnected"
|
||||||
else:
|
else:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue