diff --git a/plugins/Sidebar/SidebarPlugin.py b/plugins/Sidebar/SidebarPlugin.py index bc0f22e2..cf29eb1d 100644 --- a/plugins/Sidebar/SidebarPlugin.py +++ b/plugins/Sidebar/SidebarPlugin.py @@ -517,66 +517,108 @@ class UiWebsocketPlugin(object): -100 ]) + def getPeerLocations(self, peers): + import maxminddb + db_path = config.data_dir + '/GeoLite2-City.mmdb' + if not os.path.isfile(db_path) or os.path.getsize(db_path) == 0: + if not self.downloadGeoLiteDb(db_path): + return False + geodb = maxminddb.open_database(db_path) + + peers = peers.values() + # Place bars + peer_locations = [] + placed = {} # Already placed bars here + for peer in peers: + # Height of bar + if peer.connection and peer.connection.last_ping_delay: + ping = round(peer.connection.last_ping_delay * 1000) + else: + ping = None + + # Query and cache location + if peer.ip in loc_cache: + loc = loc_cache[peer.ip] + else: + try: + loc_data = geodb.get(peer.ip) + except: + loc_data = None + if not loc_data or "location" not in loc_data: + loc_cache[peer.ip] = None + continue + + loc = { + "lat": loc_data["location"]["latitude"], + "lon": loc_data["location"]["longitude"], + } + if "city" in loc_data: + loc["city"] = loc_data["city"]["names"]["en"] + if "country" in loc_data: + loc["country"] = loc_data["country"]["names"]["en"] + loc_cache[peer.ip] = loc + if not loc: + continue + # Create position array + lat, lon = loc["lat"], loc["lon"] + latlon = "%s,%s" % (lat, lon) + if latlon in placed: # Dont place more than 1 bar to same place, fake repos using ip address last two part + lat += float(128 - int(peer.ip.split(".")[-2])) / 50 + lon += float(128 - int(peer.ip.split(".")[-1])) / 50 + latlon = "%s,%s" % (lat, lon) + placed[latlon] = True + peer_location = {} + peer_location.update(loc) + peer_location["lat"] = lat + peer_location["lon"] = lon + peer_location["ping"] = ping + + peer_locations.append(peer_location) + + # Append myself + try: + loc_data = geodb.get(config.ip_external) + except: + loc_data = None + if loc_data and loc_data.get("location"): + peer_location = { + "lat": loc_data["location"]["latitude"], + "lon": loc_data["location"]["longitude"], + "country": loc_data["country"]["names"]["en"], + "city": loc_data["city"]["names"]["en"], + "ping": 0 + } + peer_locations.append(peer_location) + + return peer_locations + + def actionSidebarGetPeers(self, to): permissions = self.getPermissions(to) if "ADMIN" not in permissions: return self.response(to, "You don't have permission to run this command") try: - import maxminddb - db_path = config.data_dir + '/GeoLite2-City.mmdb' - if not os.path.isfile(db_path) or os.path.getsize(db_path) == 0: - if not self.downloadGeoLiteDb(db_path): - return False - geodb = maxminddb.open_database(db_path) - - peers = self.site.peers.values() - # Find avg ping + peer_locations = self.getPeerLocations(self.site.peers) + globe_data = [] ping_times = [ - peer.connection.last_ping_delay - for peer in peers - if peer.connection and peer.connection.last_ping_delay and peer.connection.last_ping_delay + peer_location["ping"] + for peer_location in peer_locations + if peer_location["ping"] ] if ping_times: ping_avg = sum(ping_times) / float(len(ping_times)) else: ping_avg = 0 - # Place bars - globe_data = [] - placed = {} # Already placed bars here - for peer in peers: - # Height of bar - if peer.connection and peer.connection.last_ping_delay: - ping = min(0.20, math.log(1 + peer.connection.last_ping_delay / ping_avg, 300)) + + for peer_location in peer_locations: + if peer_location["ping"] == 0: # Me + height = -0.135 + elif peer_location["ping"]: + height = min(0.20, math.log(1 + peer_location["ping"] / ping_avg, 300)) else: - ping = -0.03 + height = -0.03 - # Query and cache location - if peer.ip in loc_cache: - loc = loc_cache[peer.ip] - else: - try: - loc = geodb.get(peer.ip) - except: - loc = None - loc_cache[peer.ip] = loc - if not loc or "location" not in loc: - continue - - # Create position array - lat, lon = (loc["location"]["latitude"], loc["location"]["longitude"]) - latlon = "%s,%s" % (lat, lon) - if latlon in placed: # Dont place more than 1 bar to same place, fake repos using ip address last two part - lat += float(128 - int(peer.ip.split(".")[-2])) / 50 - lon += float(128 - int(peer.ip.split(".")[-1])) / 50 - latlon = "%s,%s" % (lat, lon) - placed[latlon] = True - - globe_data += (lat, lon, ping) - # Append myself - loc = geodb.get(config.ip_external) - if loc and loc.get("location"): - lat, lon = (loc["location"]["latitude"], loc["location"]["longitude"]) - globe_data += (lat, lon, -0.135) + globe_data += [peer_location["lat"], peer_location["lon"], height] self.response(to, globe_data) except Exception, err: