Files
iperf3-map/generate_locations.py
2026-01-29 17:14:50 +01:00

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()