Eigenstaendige GEOINT-Anwendung mit CesiumJS 3D-Globus. Echtzeit-Datenlayer: Flugverkehr (airplanes.live, 64 Stuetzpunkte), Schiffsverkehr (AISStream.io WebSocket), Erdbeben (USGS), Nachrichten (GDELT GEO). FastAPI Backend, taktisches Dark-UI.
33 Zeilen
1.0 KiB
Python
33 Zeilen
1.0 KiB
Python
"""GDELT GEO 2.0: Geokodierte Echtzeit-Nachrichten."""
|
|
import logging
|
|
import time
|
|
|
|
import httpx
|
|
from fastapi import APIRouter, Query
|
|
|
|
logger = logging.getLogger("globe.gdelt")
|
|
router = APIRouter()
|
|
|
|
_cache: dict[str, tuple] = {}
|
|
|
|
|
|
@router.get("/gdelt")
|
|
async def get_gdelt(query: str = Query("conflict OR crisis", max_length=200)):
|
|
key = query[:50]
|
|
if key in _cache and time.time() - _cache[key][0] < 60:
|
|
return _cache[key][1]
|
|
url = f"https://api.gdeltproject.org/api/v2/geo/geo?query={query}&mode=PointData&format=GeoJSON×pan=24h&maxrows=250"
|
|
try:
|
|
async with httpx.AsyncClient(timeout=12) as client:
|
|
r = await client.get(url)
|
|
r.raise_for_status()
|
|
data = r.json()
|
|
_cache[key] = (time.time(), data)
|
|
if len(_cache) > 30:
|
|
oldest = min(_cache, key=lambda k: _cache[k][0])
|
|
del _cache[oldest]
|
|
return data
|
|
except Exception as e:
|
|
logger.warning(f"GDELT Fehler: {e}")
|
|
return {"type": "FeatureCollection", "features": []}
|