Dateien
AegisSight-Globe/src/data_military.py
Claude Dev fd9e6558db 5 neue Layer: Militaerflug, Seekabel, Infrastruktur, ISS Tracker
MILITAERFLUGVERKEHR (adsb.lol /v2/mil):
- ~254 Militaerflugzeuge weltweit in Echtzeit (rot)
- Callsign-Labels bei Zoom (RCH=USAF, GAF=Luftwaffe etc.)
- Klick zeigt: Callsign, Registration, Typ, Hoehe, Squawk
- 20s Refresh

SEEKABEL (TeleGeography):
- Untersee-Glasfaserkabel als cyan-Linien auf dem Globus
- ~500+ internationale Kabelverbindungen
- Geopolitisch relevant (Sabotage, Abhoerung)

INFRASTRUKTUR (OpenStreetMap Overpass):
- 348 Kernkraftwerke weltweit (gelb mit Orange-Rand)
- Militaerflughaefen (rot)
- Labels bei Zoom (<500km)
- 24h Cache (statische Daten)

ISS TRACKER (Open-Notify API):
- Echtzeit-Position der ISS (roter Punkt, 420km Hoehe)
- 5s Refresh, prominentes Label
- Klick zeigt Details

Backend: data_military.py, data_infra.py (2 neue Dateien)
Frontend: military.js, cables.js, infra.js, iss.js (4 neue Dateien)
2026-03-24 23:05:43 +01:00

50 Zeilen
1.7 KiB
Python

"""Militaerflugverkehr: adsb.lol /v2/mil Endpoint."""
import asyncio, logging, time, httpx
from fastapi import APIRouter
logger = logging.getLogger("globe.military")
router = APIRouter()
_cache = {"data": None, "ts": 0}
_task = None
async def _fetch():
now = time.time()
if _cache["data"] and now - _cache["ts"] < 15:
return _cache["data"]
try:
async with httpx.AsyncClient(timeout=15) as client:
r = await client.get("https://api.adsb.lol/v2/mil")
r.raise_for_status()
ac = []
for a in r.json().get("ac", []):
if a.get("lat") and a.get("lon"):
ac.append({
"hex": a.get("hex",""), "flight": (a.get("flight") or "").strip(),
"reg": a.get("r",""), "type": a.get("t",""),
"lat": a["lat"], "lon": a["lon"],
"alt_baro": a.get("alt_baro"), "gs": a.get("gs"),
"track": a.get("track"), "squawk": a.get("squawk",""),
"dbFlags": a.get("dbFlags", 0),
})
_cache["data"] = {"ac": ac, "total": len(ac)}
_cache["ts"] = time.time()
logger.info(f"Military: {len(ac)} Flugzeuge")
except Exception as e:
logger.warning(f"Military: {e}")
return _cache["data"] or {"ac": [], "total": 0}
async def _loop():
await asyncio.sleep(5)
while True:
await _fetch()
await asyncio.sleep(20)
def start_mil_collector():
global _task
if _task is None or _task.done():
_task = asyncio.create_task(_loop())
@router.get("/military")
async def get_military():
return await _fetch()