import asyncio # kept for __main__ block def _windy_embed(lat: float, lon: float) -> str: """Windy's official iframe-embeddable webcam map — always works.""" return ( f"https://embed.windy.com/embed.html" f"?type=map&location=coordinates&metricRain=default&metricTemp=default" f"&metricWind=default&zoom=12&overlay=webcams&product=ecmwf" f"&level=surface&lat={lat}&lon={lon}" ) def _windy(lat: float, lon: float) -> str: return f"https://www.windy.com/-Webcams/webcams?{lat},{lon},12" WEBCAM_SOURCES = [ # North America {"id": "wc-nyc", "name": "Times Square, NYC", "lat": 40.7580, "lon": -73.9855}, {"id": "wc-miami", "name": "Miami Beach, Florida", "lat": 25.7617, "lon": -80.1918}, {"id": "wc-sf", "name": "San Francisco Bay", "lat": 37.8083, "lon": -122.4156}, {"id": "wc-dc", "name": "Washington DC", "lat": 38.8899, "lon": -77.0091}, # Europe {"id": "wc-lon", "name": "Tower Bridge, London", "lat": 51.5055, "lon": -0.0754}, {"id": "wc-par", "name": "Eiffel Tower, Paris", "lat": 48.8584, "lon": 2.2945}, {"id": "wc-ber", "name": "Brandenburg Gate, Berlin", "lat": 52.5163, "lon": 13.3777}, {"id": "wc-rome", "name": "Colosseum, Rome", "lat": 41.8902, "lon": 12.4922}, {"id": "wc-barcelona", "name": "Barcelona Beach", "lat": 41.4036, "lon": 2.1744}, {"id": "wc-amsterdam", "name": "Dam Square, Amsterdam", "lat": 52.3731, "lon": 4.8932}, {"id": "wc-moscow", "name": "Moscow Kremlin View", "lat": 55.7520, "lon": 37.6175}, # Middle East & Africa {"id": "wc-istanbul", "name": "Bosphorus, Istanbul", "lat": 41.0422, "lon": 29.0083}, {"id": "wc-jerusalem", "name": "Western Wall, Jerusalem", "lat": 31.7767, "lon": 35.2345}, {"id": "wc-dxb", "name": "Dubai Marina", "lat": 25.0800, "lon": 55.1400}, {"id": "wc-cairo", "name": "Pyramids of Giza, Cairo", "lat": 29.9792, "lon": 31.1342}, # Asia & Pacific {"id": "wc-tok", "name": "Shibuya Crossing, Tokyo", "lat": 35.6595, "lon": 139.7001}, {"id": "wc-hk", "name": "Victoria Harbour, HK", "lat": 22.2855, "lon": 114.1577}, {"id": "wc-sin", "name": "Singapore Skyline", "lat": 1.2897, "lon": 103.8501}, {"id": "wc-syd", "name": "Sydney Opera House", "lat": -33.8568, "lon": 151.2153}, {"id": "wc-seoul", "name": "Seoul Skyline", "lat": 37.5665, "lon": 126.9780}, # Strategic / military-adjacent {"id": "wc-gibraltar", "name": "Strait of Gibraltar", "lat": 36.1408, "lon": -5.3536}, ] async def fetch_webcams() -> list: webcams = [ { "id": cam["id"], "name": cam["name"], "lat": cam["lat"], "lon": cam["lon"], "url": _windy(cam["lat"], cam["lon"]), "embed_url": _windy_embed(cam["lat"], cam["lon"]), "type": "webcam", "status": "ONLINE", "source": "Windy Webcams", } for cam in WEBCAM_SOURCES ] print(f"[WEBCAMS] {len(webcams)} webcam locations loaded.") return webcams if __name__ == "__main__": cams = asyncio.run(fetch_webcams()) print(f"Total webcam locations: {len(cams)}")