from microdot import Microdot from microdot import send_file from microdot.websocket import with_websocket from microdot import Request import random import json import time import msgpack # Enable 500 kB files in the webui Request.max_content_length = 1024 * 1024 * 0.5 Request.max_body_length = 1024 * 1024 * 0.5 Request.max_readline = 1024 * 1024 class Server: """ Web server that serves the web ui and provides web to node communication `🔗 Source `__ Attributes ---------- cLog Reference to `run.Node.cLog` for logging transmitter: Transmission.transmission.Transmitter Reference to our `Transmission.transmission.Transmitter` instance network: Siph.Network.Network Reference to our `Siph.Network.Network` nodeID: str String converted PierMesh node ID peerIDs: dict Map of peer IDs to Websocket sessions app Microdot server instance catch: Daisy.Catch.Catch Reference to our Catch Cache instance to pull from for serving Catchs """ def __init__(self, transceiver, catch, onodeID, network, cLog): self.cLog = cLog self.transceiver = transceiver self.network = network self.network.addLookup(onodeID, self.transceiver.interface.localNode.nodeNum) self.nodeID = str(onodeID) self.peerIDs = {} self.app = Microdot() self.catch = catch # self.nmap = {self.nodeID: self.t.interface.localNode.nodeNum} # self.cLog(20, "Initialized server") @self.app.route("/res/") async def static(request, path): """ Static resources endpoint """ if ".." in path: # directory traversal is not allowed return "Not found", 404 return send_file("webui/build/res/" + path, max_age=86400) @self.app.route("/bubble") @with_websocket async def bubble(request, ws): """ Websocket handler that bridges HTMX to our transmitter Notes ----- `🔗 HTMX docs `_ """ while True: r = await ws.receive() message = json.loads(r) trigger = message["HEADERS"]["HX-Trigger"] # TODO: Drop old id from cache on regen if trigger == "gpID": peerID = str(random.randrange(0, 1000000)).zfill(6) await ws.send( """

Peer ID: {0}

""".format( peerID ) ) await ws.send( """ """.format( peerID ) ) await ws.send( """

Node ID: {0}

""".format( self.nodeID ) ) await ws.send( """ """.format( self.nodeID ) ) await ws.send( "".format( peerID ) ) await ws.send( "".format( peerID ) ) peer = {"usedLast": round(time.time() * 1000), "ws": ws} self.peerIDs[peerID] = peer elif trigger == "bubble": sender = message["bID"] data = message["chat_message"] # TODO: Setting sender name id # senderName = message["senderID"] senderName = 000000 recipient = message["recipientID"] recipientNode = message["recipientNode"] await self.t.addPackets( msgpack.dumps({"data": data}), sender, senderName, recipient, int(recipientNode), directID=self.network.doLookup(recipientNode), packetsClass=2, ) elif trigger == "catch": res = self.catch.get(message["head"], message["body"]) await ws.send('
{0}
'.format(res)) # TODO: Catch update packets elif trigger == "catchEdit": self.catch.addc( message["eID"], self.nodeID, message["sep"], message["head"], message["body"], {"html": message["catchContent"]}, ) await ws.send( """
  • OK
""" ) else: await ws.send( """
hi
""" ) @self.app.route("/") async def index(request): """ Static handler to serve the web ui """ return send_file("webui/build/index/index.html") async def sendToPeer(self, peerID: str, data: str): """ Send data to Websocket of peer with peerID """ await self.peerIDs[peerID]["ws"].send( "
  • {0}
".format(data) )