"""GTFS-RT Trip Updates von opentransportdata.swiss holen und auf das Nötigste eindampfen.""" import httpx from google.transit import gtfs_realtime_pb2 as pb from . import config as C CANCELED = pb.TripDescriptor.CANCELED def parse(data: bytes, known_trips: dict): """-> (feed_version, {(trip_id, start_date): (ausgefallen, [(seq, ank, ank_absolut, abf, abf_absolut), ...])}) ank/abf sind Verspätung in s, oder Unix-Zeit wenn *_absolut; None = keine Angabe.""" feed = pb.FeedMessage() feed.ParseFromString(data) out = {} for e in feed.entity: if not e.HasField("trip_update"): continue tu = e.trip_update if tu.trip.trip_id not in known_trips: continue # nicht Bahn upd = [] for s in tu.stop_time_update: ev = [] for name in ("arrival", "departure"): if s.HasField(name): x = getattr(s, name) ev += [x.time, True] if x.HasField("time") else [x.delay, False] if x.HasField("delay") else [None, False] else: ev += [None, False] upd.append((s.stop_sequence, *ev)) out[(tu.trip.trip_id, tu.trip.start_date)] = (tu.trip.schedule_relationship == CANCELED, upd) version = feed.header.feed_version if feed.header.HasField("feed_version") else None return version, out def fetch(url: str, key: str = "") -> bytes: headers = {"User-Agent": C.USER_AGENT} if key: headers["Authorization"] = f"Bearer {key}" r = httpx.get(url, follow_redirects=True, timeout=30, headers=headers) r.raise_for_status() return r.content