python-openpublictransport 0.3.1__tar.gz → 0.3.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/PKG-INFO +1 -1
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/pyproject.toml +1 -1
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/models.py +7 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/parsers.py +12 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/hafas_mgate_base.py +7 -3
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/python_openpublictransport.egg-info/PKG-INFO +1 -1
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/python_openpublictransport.egg-info/SOURCES.txt +1 -0
- python_openpublictransport-0.3.3/tests/test_disruptions.py +101 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/tests/test_german_regional_providers.py +19 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/setup.cfg +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/__init__.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/const.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/data/uk_stations.json +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/exceptions.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/__init__.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/avv.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/bart.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/base.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/beg.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/bsvg.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/bvg.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/cta.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/dart.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/db.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/digitransit.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/ding.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/efa_base.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/entur.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/fptf_base.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/golemio.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/gvh.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/hafas_base.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/hongkong.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/hvv.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/hvv_gti.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/insa.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/irail.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/irishrail.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/kvv.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/mobiliteit_lu.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/mvv.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/nahsh.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/national_rail.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/nextbus_base.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/ns.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/nta.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/nvbw.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/nvv.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/nwl.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/oebb.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/otp.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/otp_base.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/otp_custom.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/rejseplanen.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/rmv.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/rvv.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/saarvv.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/sbb.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/sl.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/tfl.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/tfnsw.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/tpg.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/trafiklab.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/transitous.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/trias_base.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/trimet.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/ttc.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/vagfr.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/vao.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/vbn.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/vbn_hafas.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/vgn.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/vmt.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/vmv.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/vos.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/vrn.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/vrr.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/vsn.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/vvo.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/vvs.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/providers/wienerlinien.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/openpublictransport/py.typed +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/python_openpublictransport.egg-info/dependency_links.txt +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/python_openpublictransport.egg-info/requires.txt +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/src/python_openpublictransport.egg-info/top_level.txt +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/tests/test_cta.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/tests/test_digitransit.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/tests/test_efa_mimetype.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/tests/test_efa_platform.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/tests/test_entur.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/tests/test_golemio.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/tests/test_hafas_base.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/tests/test_hafas_mgate.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/tests/test_hongkong.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/tests/test_http_errors.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/tests/test_hvv_gti.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/tests/test_irail.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/tests/test_issue_fixes_0_3_1.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/tests/test_national_rail.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/tests/test_national_rail_parse.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/tests/test_national_rail_static.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/tests/test_provider_expansion.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/tests/test_sbb.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/tests/test_sl.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/tests/test_tfl.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/tests/test_tfnsw.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/tests/test_ttc.py +0 -0
- {python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/tests/test_wienerlinien.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "python-openpublictransport"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.3"
|
|
8
8
|
description = "Python library for public transport APIs (EFA, OTP2, TRIAS, FPTF, HAFAS, GTFS-RT)"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "MIT" }
|
|
@@ -36,6 +36,10 @@ class UnifiedDeparture:
|
|
|
36
36
|
description: Optional[str] = None
|
|
37
37
|
agency: Optional[str] = None
|
|
38
38
|
notices: Optional[list[str]] = None
|
|
39
|
+
# The subset of ``notices`` that reports an actual disruption, as opposed
|
|
40
|
+
# to routine information such as bicycle rules or on-board facilities.
|
|
41
|
+
# None means the provider does not tell them apart: every notice counts.
|
|
42
|
+
disruptions: Optional[list[str]] = None
|
|
39
43
|
planned_platform: Optional[str] = None
|
|
40
44
|
platform_changed: bool = False
|
|
41
45
|
# Human-readable form of `platform` when the provider offers one
|
|
@@ -63,6 +67,9 @@ class UnifiedDeparture:
|
|
|
63
67
|
result["agency"] = self.agency
|
|
64
68
|
if self.notices:
|
|
65
69
|
result["notices"] = self.notices
|
|
70
|
+
# Always present next to the notices, even when empty, so consumers
|
|
71
|
+
# can tell "no disruption" apart from an older payload without it.
|
|
72
|
+
result["disruptions"] = self.notices if self.disruptions is None else self.disruptions
|
|
66
73
|
if self.platform_name and self.platform_name != self.platform:
|
|
67
74
|
result["platform_name"] = self.platform_name
|
|
68
75
|
if self.platform_changed:
|
|
@@ -34,6 +34,13 @@ def rail_line_label(number: str, name: str) -> str:
|
|
|
34
34
|
return number
|
|
35
35
|
|
|
36
36
|
|
|
37
|
+
# EFA hint types that carry routine timetable or vehicle information ("bicycles
|
|
38
|
+
# limited", "wheelchair accessible", "on-board restaurant") rather than a
|
|
39
|
+
# disruption. Infos (lineInfo, stopBlocking, …) and real-time hints such as
|
|
40
|
+
# RTIncidentCall ("delay of a preceding train") are disruptions.
|
|
41
|
+
EFA_ROUTINE_HINT_TYPES = frozenset({"Timetable", "VehicleType"})
|
|
42
|
+
|
|
43
|
+
|
|
37
44
|
# Human-readable platform labels APIs prefix onto the bare track identifier:
|
|
38
45
|
# "Gleis 3", "Bstg. 12", "Steig B", "Platform 4", "Pl. 2", "Track 1".
|
|
39
46
|
_PLATFORM_LABEL_RE = re.compile(
|
|
@@ -140,16 +147,20 @@ def parse_departure_generic(
|
|
|
140
147
|
is_realtime = get_realtime_fn(stop, estimated_time_str, planned_time_str)
|
|
141
148
|
|
|
142
149
|
notices = []
|
|
150
|
+
disruptions = []
|
|
143
151
|
for info in stop.get("infos", []):
|
|
144
152
|
if isinstance(info, dict):
|
|
145
153
|
text = info.get("subtitle") or info.get("title") or info.get("content", "")
|
|
146
154
|
if text and isinstance(text, str):
|
|
147
155
|
notices.append(text.strip())
|
|
156
|
+
disruptions.append(text.strip())
|
|
148
157
|
for hint in stop.get("hints", []):
|
|
149
158
|
if isinstance(hint, dict):
|
|
150
159
|
text = hint.get("content") or hint.get("text", "")
|
|
151
160
|
if text and isinstance(text, str):
|
|
152
161
|
notices.append(text.strip())
|
|
162
|
+
if hint.get("type") not in EFA_ROUTINE_HINT_TYPES:
|
|
163
|
+
disruptions.append(text.strip())
|
|
153
164
|
|
|
154
165
|
planned_fn = get_planned_platform_fn or _default_planned_platform_fn
|
|
155
166
|
planned_platform = planned_fn(stop)
|
|
@@ -174,6 +185,7 @@ def parse_departure_generic(
|
|
|
174
185
|
description=description if description else None,
|
|
175
186
|
agency=agency if agency else None,
|
|
176
187
|
notices=notices if notices else None,
|
|
188
|
+
disruptions=disruptions if notices else None,
|
|
177
189
|
planned_platform=str(planned_platform).strip() if planned_platform and platform_changed else None,
|
|
178
190
|
platform_changed=platform_changed,
|
|
179
191
|
platform_name=str(platform_name).strip() or None,
|
|
@@ -327,11 +327,15 @@ class HafasMgateBaseProvider(BaseProvider):
|
|
|
327
327
|
destination_id: str,
|
|
328
328
|
departure_time: Optional[datetime] = None,
|
|
329
329
|
results: int = 4,
|
|
330
|
+
arrival_time: Optional[datetime] = None,
|
|
330
331
|
) -> List[Dict[str, Any]]:
|
|
331
332
|
"""Plan journeys between two stops with the mgate ``TripSearch`` service.
|
|
332
333
|
|
|
333
334
|
``departure_time`` is converted to the network's time zone; without it
|
|
334
|
-
the search starts now.
|
|
335
|
+
the search starts now. ``arrival_time`` switches to an "arrive by"
|
|
336
|
+
search instead (like hafas-client's ``arrival`` option, ``outFrwd``
|
|
337
|
+
false): the connections that arrive by then. It wins over
|
|
338
|
+
``departure_time``. Returns one dict per connection::
|
|
335
339
|
|
|
336
340
|
{"duration_minutes": int, "transfers": int, "legs": [leg, ...]}
|
|
337
341
|
|
|
@@ -342,7 +346,7 @@ class HafasMgateBaseProvider(BaseProvider):
|
|
|
342
346
|
(the unprefixed ones are real-time when the network reports it).
|
|
343
347
|
"""
|
|
344
348
|
tz = ZoneInfo(self.timezone)
|
|
345
|
-
when = (departure_time or datetime.now(tz)).astimezone(tz)
|
|
349
|
+
when = (arrival_time or departure_time or datetime.now(tz)).astimezone(tz)
|
|
346
350
|
svc = {
|
|
347
351
|
"meth": "TripSearch",
|
|
348
352
|
"req": {
|
|
@@ -350,7 +354,7 @@ class HafasMgateBaseProvider(BaseProvider):
|
|
|
350
354
|
"arrLocL": [self._location(destination_id)],
|
|
351
355
|
"outDate": when.strftime("%Y%m%d"),
|
|
352
356
|
"outTime": when.strftime("%H%M%S"),
|
|
353
|
-
"outFrwd":
|
|
357
|
+
"outFrwd": arrival_time is None,
|
|
354
358
|
"numF": results,
|
|
355
359
|
"getPasslist": False,
|
|
356
360
|
"getPolyline": False,
|
|
@@ -81,6 +81,7 @@ src/python_openpublictransport.egg-info/requires.txt
|
|
|
81
81
|
src/python_openpublictransport.egg-info/top_level.txt
|
|
82
82
|
tests/test_cta.py
|
|
83
83
|
tests/test_digitransit.py
|
|
84
|
+
tests/test_disruptions.py
|
|
84
85
|
tests/test_efa_mimetype.py
|
|
85
86
|
tests/test_efa_platform.py
|
|
86
87
|
tests/test_entur.py
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"""Tests for telling disruptions apart from routine notices.
|
|
2
|
+
|
|
3
|
+
EFA mixes routine timetable and vehicle information ("bicycles limited",
|
|
4
|
+
"wheelchair accessible vehicle", "on-board restaurant") with real disruptions
|
|
5
|
+
in the same ``hints`` list, so everything ended up in a red warning banner.
|
|
6
|
+
See https://github.com/NerdySoftPaw/openpublictransport-card/issues/15.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from datetime import datetime
|
|
10
|
+
from zoneinfo import ZoneInfo
|
|
11
|
+
|
|
12
|
+
from openpublictransport.models import UnifiedDeparture
|
|
13
|
+
from openpublictransport.providers.gvh import GVHProvider
|
|
14
|
+
|
|
15
|
+
TZ = ZoneInfo("Europe/Berlin")
|
|
16
|
+
NOW = datetime(2026, 10, 16, 20, 0, tzinfo=TZ)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _stop_event(hints=None, infos=None) -> dict:
|
|
20
|
+
"""A GVH departure from Hannover Hbf as the live API returns it."""
|
|
21
|
+
event = {
|
|
22
|
+
"location": {"id": "de:03241:31", "name": "Hauptbahnhof", "properties": {"platform": "8"}},
|
|
23
|
+
"departureTimePlanned": "2026-10-16T18:10:00Z",
|
|
24
|
+
"departureTimeEstimated": "2026-10-16T18:12:00Z",
|
|
25
|
+
"transportation": {
|
|
26
|
+
"name": "ICE 550 InterCityExpress",
|
|
27
|
+
"number": "550",
|
|
28
|
+
"destination": {"name": "Köln Hbf"},
|
|
29
|
+
"product": {"class": 0, "name": "ICE"},
|
|
30
|
+
},
|
|
31
|
+
}
|
|
32
|
+
if hints is not None:
|
|
33
|
+
event["hints"] = hints
|
|
34
|
+
if infos is not None:
|
|
35
|
+
event["infos"] = infos
|
|
36
|
+
return event
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def test_routine_hints_are_notices_but_not_disruptions():
|
|
40
|
+
"""Timetable and VehicleType hints stay notices without becoming disruptions."""
|
|
41
|
+
event = _stop_event(hints=[
|
|
42
|
+
{"content": "behindertengerechtes Fahrzeug", "providerCode": "13", "type": "VehicleType"},
|
|
43
|
+
{"content": "Bordrestaurant", "providerCode": "BR", "type": "Timetable"},
|
|
44
|
+
])
|
|
45
|
+
dep = GVHProvider(None).parse_departure(event, TZ, NOW)
|
|
46
|
+
|
|
47
|
+
assert dep.notices == ["behindertengerechtes Fahrzeug", "Bordrestaurant"]
|
|
48
|
+
assert dep.disruptions == []
|
|
49
|
+
result = dep.to_dict()
|
|
50
|
+
assert result["notices"] == ["behindertengerechtes Fahrzeug", "Bordrestaurant"]
|
|
51
|
+
assert result["disruptions"] == []
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def test_realtime_hints_and_infos_are_disruptions():
|
|
55
|
+
"""Real-time incident hints and infos are disruptions; routine hints are not."""
|
|
56
|
+
event = _stop_event(
|
|
57
|
+
hints=[
|
|
58
|
+
{"content": "Bordrestaurant", "providerCode": "BR", "type": "Timetable"},
|
|
59
|
+
{"content": "Technische Störung am Zug", "providerCode": "x", "type": "RTIncidentCall"},
|
|
60
|
+
],
|
|
61
|
+
infos=[{"type": "lineInfo", "priority": "normal", "title": "Bauarbeiten S1, S2, S5"}],
|
|
62
|
+
)
|
|
63
|
+
dep = GVHProvider(None).parse_departure(event, TZ, NOW)
|
|
64
|
+
|
|
65
|
+
assert dep.notices == ["Bauarbeiten S1, S2, S5", "Bordrestaurant", "Technische Störung am Zug"]
|
|
66
|
+
assert dep.disruptions == ["Bauarbeiten S1, S2, S5", "Technische Störung am Zug"]
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def test_hint_without_type_is_a_disruption():
|
|
70
|
+
"""An unknown or missing hint type is kept as a disruption, never hidden."""
|
|
71
|
+
dep = GVHProvider(None).parse_departure(_stop_event(hints=[{"content": "Ersatzverkehr"}]), TZ, NOW)
|
|
72
|
+
|
|
73
|
+
assert dep.disruptions == ["Ersatzverkehr"]
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def test_no_notices_no_keys():
|
|
77
|
+
"""Without notices, neither key appears in the attributes."""
|
|
78
|
+
dep = GVHProvider(None).parse_departure(_stop_event(), TZ, NOW)
|
|
79
|
+
|
|
80
|
+
assert dep.notices is None and dep.disruptions is None
|
|
81
|
+
assert "notices" not in dep.to_dict()
|
|
82
|
+
assert "disruptions" not in dep.to_dict()
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def test_unclassified_notices_all_count_as_disruptions():
|
|
86
|
+
"""Providers that do not classify their notices report all of them as disruptions."""
|
|
87
|
+
dep = UnifiedDeparture(
|
|
88
|
+
line="U1",
|
|
89
|
+
destination="Somewhere",
|
|
90
|
+
departure_time="20:10",
|
|
91
|
+
planned_time="20:10",
|
|
92
|
+
delay=0,
|
|
93
|
+
platform=None,
|
|
94
|
+
transportation_type="subway",
|
|
95
|
+
is_realtime=True,
|
|
96
|
+
minutes_until_departure=10,
|
|
97
|
+
departure_time_obj=NOW,
|
|
98
|
+
notices=["Cancelled"],
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
assert dep.to_dict()["disruptions"] == ["Cancelled"]
|
|
@@ -202,3 +202,22 @@ async def test_search_trips_with_extid_and_empty_result():
|
|
|
202
202
|
def test_german_category_labels(cat_out, cat_out_l, expected):
|
|
203
203
|
prod = {"prodCtx": {"catOut": cat_out, "catOutL": cat_out_l}}
|
|
204
204
|
assert VMTProvider(session=None)._transport_type(prod) == expected
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
async def test_search_trips_arrive_by():
|
|
208
|
+
provider = NAHSHProvider(session=None)
|
|
209
|
+
provider._request = AsyncMock(return_value={"svcResL": [{"res": {}}]})
|
|
210
|
+
|
|
211
|
+
await provider.search_trips("A=1@L=1@", "A=1@L=2@", arrival_time=datetime(2026, 10, 17, 6, 0, tzinfo=ZoneInfo("UTC")))
|
|
212
|
+
|
|
213
|
+
req = json.loads(provider._request.call_args.kwargs["data"])["svcReqL"][0]["req"]
|
|
214
|
+
assert req["outFrwd"] is False
|
|
215
|
+
# 06:00 UTC is 08:00 in Berlin
|
|
216
|
+
assert (req["outDate"], req["outTime"]) == ("20261017", "080000")
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
async def test_search_trips_departure_stays_forward():
|
|
220
|
+
provider = NAHSHProvider(session=None)
|
|
221
|
+
provider._request = AsyncMock(return_value={"svcResL": [{"res": {}}]})
|
|
222
|
+
await provider.search_trips("A=1@L=1@", "A=1@L=2@")
|
|
223
|
+
assert json.loads(provider._request.call_args.kwargs["data"])["svcReqL"][0]["req"]["outFrwd"] is True
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/tests/test_digitransit.py
RENAMED
|
File without changes
|
{python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/tests/test_efa_mimetype.py
RENAMED
|
File without changes
|
{python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/tests/test_efa_platform.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/tests/test_hafas_base.py
RENAMED
|
File without changes
|
{python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/tests/test_hafas_mgate.py
RENAMED
|
File without changes
|
{python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/tests/test_hongkong.py
RENAMED
|
File without changes
|
{python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/tests/test_http_errors.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/tests/test_national_rail.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_openpublictransport-0.3.1 → python_openpublictransport-0.3.3}/tests/test_wienerlinien.py
RENAMED
|
File without changes
|