diff --git a/config_webrx.py b/config_webrx.py index 0613278..12f9c14 100644 --- a/config_webrx.py +++ b/config_webrx.py @@ -230,3 +230,10 @@ csdr_print_bufsizes = False # This prints the buffer sizes used for csdr proces csdr_through = False # Setting this True will print out how much data is going into the DSP chains. nmux_memory = 50 #in megabytes. This sets the approximate size of the circular buffer used by nmux. + +google_maps_api_key = "" + +# how long should positions be visible on the map? +# they will start fading out after half of that +# in seconds; default: 2 hours +map_position_retention_time = 2 * 60 * 60 \ No newline at end of file diff --git a/owrx/map.py b/owrx/map.py index a799c92..2819a3e 100644 --- a/owrx/map.py +++ b/owrx/map.py @@ -1,4 +1,9 @@ -from datetime import datetime +from datetime import datetime, timedelta +import threading, time +from owrx.config import PropertyManager + +import logging +logger = logging.getLogger(__name__) class Location(object): @@ -17,6 +22,16 @@ class Map(object): def __init__(self): self.clients = [] self.positions = {} + + def removeLoop(): + while True: + try: + self.removeOldPositions() + except Exception: + logger.exception("error while removing old map positions") + time.sleep(60) + + threading.Thread(target=removeLoop, daemon=True).start() super().__init__() def broadcast(self, update): @@ -25,7 +40,14 @@ class Map(object): def addClient(self, client): self.clients.append(client) - client.write_update([{"callsign": callsign, "location": record["loc"].__dict__()} for (callsign, record) in self.positions.items()]) + client.write_update([ + { + "callsign": callsign, + "location": record["location"].__dict__(), + "lastseen": record["updated"].timestamp() * 1000 + } + for (callsign, record) in self.positions.items() + ]) def removeClient(self, client): try: @@ -34,9 +56,28 @@ class Map(object): pass def updateLocation(self, callsign, loc: Location): - self.positions[callsign] = {"loc": loc, "updated": datetime.now()} - self.broadcast([{"callsign": callsign, "location": loc.__dict__()}]) + ts = datetime.now() + self.positions[callsign] = {"location": loc, "updated": ts} + self.broadcast([ + { + "callsign": callsign, + "location": loc.__dict__(), + "lastseen": ts.timestamp() * 1000 + } + ]) + def removeLocation(self, callsign): + self.positions.pop(callsign, None) + # TODO broadcast removal to clients + + def removeOldPositions(self): + pm = PropertyManager.getSharedInstance() + retention = timedelta(seconds=pm["map_position_retention_time"]) + cutoff = datetime.now() - retention + + to_be_removed = [callsign for (callsign, pos) in self.positions.items() if pos["updated"] < cutoff] + for callsign in to_be_removed: + self.removeLocation(callsign) class LatLngLocation(Location): def __init__(self, lat: float, lon: float):