70 lines
3.1 KiB
Python
70 lines
3.1 KiB
Python
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)}")
|