AegisSight Globe: Initiales Release
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.
Dieser Commit ist enthalten in:
32
src/data_gdelt.py
Normale Datei
32
src/data_gdelt.py
Normale Datei
@@ -0,0 +1,32 @@
|
||||
"""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": []}
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren