"""Universelle Sendungsverfolgung: erst DHL direkt, dann 17TRACK, sonst nur Erkennung + Links.""" import logging import time from ..config import TRACKING from .carriers import detect_carriers, universal_link from .dhl import track_dhl from .seventeen import track_17 log = logging.getLogger(__name__) CACHE_SECONDS = 120 _cache: dict[str, tuple[float, dict]] = {} async def track(number: str) -> dict: cached = _cache.get(number) if cached and time.monotonic() - cached[0] < CACHE_SECONDS: return cached[1] candidates = detect_carriers(number) base = {"number": number, "candidates": candidates, "universalLink": universal_link(number)} dhl_key = TRACKING.get("dhlApiKey") key_17 = TRACKING.get("seventeenTrackApiKey") errors = [] if dhl_key and any(c["id"] == "dhl" for c in candidates): try: result = await track_dhl(number, dhl_key) if result: return _store(number, {**base, **result}) except Exception as e: # noqa: BLE001 – Fehler anzeigen, nächsten Anbieter probieren log.warning("DHL-Abfrage fehlgeschlagen: %s", e) errors.append(f"DHL: {e}") if key_17: try: result = await track_17(number, key_17) data = {**base, **result} return _store(number, data) if result["status"] != "pending" else data except Exception as e: # noqa: BLE001 log.warning("17TRACK-Abfrage fehlgeschlagen: %s", e) errors.append(f"17TRACK: {e}") return {**base, "source": None, "status": "unknown", "configured": bool(dhl_key or key_17), "errors": errors} def _store(number: str, data: dict) -> dict: _cache[number] = (time.monotonic(), data) return data