mirror of
https://github.com/R0GGER/iperf3-map.git
synced 2026-11-11 01:20:06 +01:00
112 lines
3.5 KiB
Python
112 lines
3.5 KiB
Python
import json
|
|
import requests
|
|
import time
|
|
import geonamescache
|
|
import sys
|
|
from geopy.geocoders import Nominatim
|
|
|
|
CITY_ALIASES = {
|
|
"new york": "new york city",
|
|
"frankfurt": "frankfurt am main",
|
|
"st. louis": "saint louis",
|
|
"montreal": "montréal",
|
|
"reykjavik": "reykjavík",
|
|
"sao paulo": "são paulo",
|
|
"zurich": "zürich",
|
|
"quebec": "québec",
|
|
"washington": "washington, d.c."
|
|
}
|
|
|
|
COUNTRY_FIXES = {
|
|
"UK": "GB",
|
|
"USA": "US"
|
|
}
|
|
|
|
def generate_locations():
|
|
print("Fetching server list...")
|
|
url = "https://export.iperf3serverlist.net/listed_iperf3_servers.json"
|
|
try:
|
|
response = requests.get(url, timeout=30)
|
|
response.raise_for_status()
|
|
servers = response.json()
|
|
except Exception as e:
|
|
print(f"Failed to fetch server list: {e}")
|
|
raise RuntimeError(f"Failed to fetch server list: {e}") from e
|
|
|
|
print(f"Found {len(servers)} servers.")
|
|
|
|
gc = geonamescache.GeonamesCache()
|
|
cities = gc.get_cities()
|
|
cities_by_name = {}
|
|
|
|
print("Loading offline database...")
|
|
for city_id, city_data in cities.items():
|
|
name = city_data['name'].lower()
|
|
country = city_data['countrycode']
|
|
key = f"{name}, {country}"
|
|
cities_by_name[key] = {
|
|
"lat": float(city_data['latitude']),
|
|
"lon": float(city_data['longitude'])
|
|
}
|
|
|
|
geolocator = Nominatim(user_agent="iperf3-map-generator-v2", timeout=10)
|
|
|
|
unique_keys = set()
|
|
for server in servers:
|
|
city = server.get('SITE')
|
|
country = server.get('COUNTRY')
|
|
if city and country:
|
|
if country in COUNTRY_FIXES:
|
|
country = COUNTRY_FIXES[country]
|
|
unique_keys.add((city, country))
|
|
|
|
print(f"Found {len(unique_keys)} unique locations to process.")
|
|
|
|
results = {}
|
|
|
|
for city, country in unique_keys:
|
|
key = f"{city}, {country}"
|
|
|
|
city_lower = city.lower()
|
|
search_city = CITY_ALIASES.get(city_lower, city_lower)
|
|
|
|
offline_key = f"{search_city}, {country}"
|
|
if offline_key in cities_by_name:
|
|
results[key] = cities_by_name[offline_key]
|
|
continue
|
|
|
|
try:
|
|
search_query = f"{search_city}, {country}"
|
|
print(f"Geocoding online: {search_query}...")
|
|
location = geolocator.geocode(search_query)
|
|
if location:
|
|
results[key] = {
|
|
"lat": location.latitude,
|
|
"lon": location.longitude
|
|
}
|
|
print(f"Found: {location.latitude}, {location.longitude}")
|
|
time.sleep(1.1)
|
|
else:
|
|
print(f"Not found online: {search_query}")
|
|
except Exception as e:
|
|
print(f"Error geocoding {key}: {e}")
|
|
|
|
print(f"Resolved {len(results)} locations.")
|
|
|
|
sorted_results = dict(sorted(results.items()))
|
|
|
|
try:
|
|
with open('prefilled_locations.json', 'w', encoding='utf-8') as f:
|
|
json.dump(sorted_results, f, indent=2)
|
|
except Exception as e:
|
|
print(f"Failed to write prefilled_locations.json: {e}")
|
|
raise RuntimeError(f"Failed to write prefilled_locations.json: {e}") from e
|
|
|
|
print("Saved to prefilled_locations.json")
|
|
return True
|
|
|
|
if __name__ == "__main__":
|
|
sys.stdout = open('gen_log.txt', 'w', encoding='utf-8')
|
|
sys.stderr = sys.stdout
|
|
generate_locations()
|