collect announces in database

This commit is contained in:
liamcottle
2024-05-05 21:11:22 +12:00
parent f14c5929a5
commit 06f5af2ee0
2 changed files with 73 additions and 1 deletions

View File

@@ -23,6 +23,23 @@ class Config(BaseModel):
table_name = "config" table_name = "config"
class Announce(BaseModel):
id = BigAutoField()
destination_hash = CharField(unique=True) # unique destination hash that was announced
aspect = TextField(index=True) # aspect is not included in announce, but we want to filter saved announces by aspect
identity_hash = CharField(index=True) # identity hash that announced the destination
identity_public_key = CharField() # base64 encoded public key, incase we want to recreate the identity manually
app_data = TextField(null=True) # base64 encoded app data bytes
created_at = DateTimeField(default=datetime.now)
updated_at = DateTimeField(default=datetime.now)
# define table name
class Meta:
table_name = "announces"
class LxmfMessage(BaseModel): class LxmfMessage(BaseModel):
id = BigAutoField() id = BigAutoField()

57
web.py
View File

@@ -49,6 +49,7 @@ class ReticulumWebChat:
self.db.connect() self.db.connect()
self.db.create_tables([ self.db.create_tables([
database.Config, database.Config,
database.Announce,
database.LxmfMessage, database.LxmfMessage,
]) ])
@@ -73,6 +74,7 @@ class ReticulumWebChat:
# set a callback for when an lxmf announce is received # set a callback for when an lxmf announce is received
RNS.Transport.register_announce_handler(LXMFAnnounceHandler(self.on_lxmf_announce_received)) RNS.Transport.register_announce_handler(LXMFAnnounceHandler(self.on_lxmf_announce_received))
RNS.Transport.register_announce_handler(NomadnetworkNodeAnnounceHandler(self.on_nomadnet_node_announce_received))
# remember websocket clients # remember websocket clients
self.websocket_clients: List[web.WebSocketResponse] = [] self.websocket_clients: List[web.WebSocketResponse] = []
@@ -600,6 +602,29 @@ class ReticulumWebChat:
query = query.on_conflict(conflict_target=[database.LxmfMessage.hash], update=data) query = query.on_conflict(conflict_target=[database.LxmfMessage.hash], update=data)
query.execute() query.execute()
# upserts the provided announce to the database
def db_upsert_announce(self, identity: RNS.Identity, destination_hash: bytes, aspect: str, app_data: bytes):
# parse app data
parsed_app_data = None
if app_data is not None:
parsed_app_data = base64.b64encode(app_data).decode("utf-8")
# prepare data to insert or update
data = {
"destination_hash": destination_hash.hex(),
"aspect": aspect,
"identity_hash": identity.hash.hex(),
"identity_public_key": base64.b64encode(identity.get_public_key()).decode("utf-8"),
"app_data": parsed_app_data,
"updated_at": datetime.now(),
}
# upsert to database
query = database.Announce.insert(data)
query = query.on_conflict(conflict_target=[database.Announce.destination_hash], update=data)
query.execute()
# handle sending an lxmf message to reticulum # handle sending an lxmf message to reticulum
async def send_message(self, destination_hash, content: str, async def send_message(self, destination_hash, content: str,
image_field: LxmfImageField = None, image_field: LxmfImageField = None,
@@ -689,7 +714,10 @@ class ReticulumWebChat:
def on_lxmf_announce_received(self, destination_hash, announced_identity, app_data): def on_lxmf_announce_received(self, destination_hash, announced_identity, app_data):
# log received announce # log received announce
RNS.log("Received an announce from " + RNS.prettyhexrep(destination_hash)) print("Received an announce from " + RNS.prettyhexrep(destination_hash) + " for [lxmf.delivery]")
# upsert announce to database
self.db_upsert_announce(announced_identity, destination_hash, "lxmf.delivery", app_data)
# parse app data # parse app data
parsed_app_data = None parsed_app_data = None
@@ -706,6 +734,16 @@ class ReticulumWebChat:
}, },
}))) })))
# handle an announce received from reticulum, for a nomadnet node
# NOTE: cant be async, as Reticulum doesn't await it
def on_nomadnet_node_announce_received(self, destination_hash, announced_identity, app_data):
# log received announce
print("Received an announce from " + RNS.prettyhexrep(destination_hash) + " for [nomadnetwork.node]")
# upsert announce to database
self.db_upsert_announce(announced_identity, destination_hash, "nomadnetwork.node", app_data)
# class to manage config stored in database # class to manage config stored in database
class Config: class Config:
@@ -773,6 +811,23 @@ class LXMFAnnounceHandler:
pass pass
# an announce handler for nomadnetwork.node aspect that just forwards to a provided callback
class NomadnetworkNodeAnnounceHandler:
def __init__(self, received_announce_callback):
self.aspect_filter = "nomadnetwork.node"
self.received_announce_callback = received_announce_callback
# we will just pass the received announce back to the provided callback
def received_announce(self, destination_hash, announced_identity, app_data):
try:
# handle received announce
self.received_announce_callback(destination_hash, announced_identity, app_data)
except:
# ignore failure to handle received announce
pass
class NomadnetDownloader: class NomadnetDownloader:
def __init__(self, destination_hash: bytes, path: str, on_download_success: Callable[[bytes], None], on_download_failure: Callable[[str], None], on_progress_update: Callable[[float], None], timeout: int|None = None, auto_download=True): def __init__(self, destination_hash: bytes, path: str, on_download_success: Callable[[bytes], None], on_download_failure: Callable[[str], None], on_progress_update: Callable[[float], None], timeout: int|None = None, auto_download=True):