koleo-cli 0.2.137.2__tar.gz → 0.2.137.4__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.
Potentially problematic release.
This version of koleo-cli might be problematic. Click here for more details.
- {koleo_cli-0.2.137.2 → koleo_cli-0.2.137.4}/PKG-INFO +1 -1
- {koleo_cli-0.2.137.2 → koleo_cli-0.2.137.4}/koleo/api.py +11 -10
- {koleo_cli-0.2.137.2 → koleo_cli-0.2.137.4}/koleo/cli.py +101 -21
- {koleo_cli-0.2.137.2 → koleo_cli-0.2.137.4}/koleo/types.py +53 -0
- {koleo_cli-0.2.137.2 → koleo_cli-0.2.137.4}/koleo/utils.py +8 -1
- {koleo_cli-0.2.137.2 → koleo_cli-0.2.137.4}/koleo_cli.egg-info/PKG-INFO +1 -1
- {koleo_cli-0.2.137.2 → koleo_cli-0.2.137.4}/setup.py +1 -1
- {koleo_cli-0.2.137.2 → koleo_cli-0.2.137.4}/README.md +0 -0
- {koleo_cli-0.2.137.2 → koleo_cli-0.2.137.4}/koleo/__init__.py +0 -0
- {koleo_cli-0.2.137.2 → koleo_cli-0.2.137.4}/koleo/__main__.py +0 -0
- {koleo_cli-0.2.137.2 → koleo_cli-0.2.137.4}/koleo/storage.py +0 -0
- {koleo_cli-0.2.137.2 → koleo_cli-0.2.137.4}/koleo_cli.egg-info/SOURCES.txt +0 -0
- {koleo_cli-0.2.137.2 → koleo_cli-0.2.137.4}/koleo_cli.egg-info/dependency_links.txt +0 -0
- {koleo_cli-0.2.137.2 → koleo_cli-0.2.137.4}/koleo_cli.egg-info/entry_points.txt +0 -0
- {koleo_cli-0.2.137.2 → koleo_cli-0.2.137.4}/koleo_cli.egg-info/requires.txt +0 -0
- {koleo_cli-0.2.137.2 → koleo_cli-0.2.137.4}/koleo_cli.egg-info/top_level.txt +0 -0
- {koleo_cli-0.2.137.2 → koleo_cli-0.2.137.4}/pyproject.toml +0 -0
- {koleo_cli-0.2.137.2 → koleo_cli-0.2.137.4}/setup.cfg +0 -0
|
@@ -6,11 +6,6 @@ from requests import PreparedRequest, Response, Session
|
|
|
6
6
|
from koleo.types import *
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
9
|
class errors:
|
|
15
10
|
class KoleoAPIException(Exception):
|
|
16
11
|
status: int
|
|
@@ -86,7 +81,13 @@ class KoleoAPI:
|
|
|
86
81
|
|
|
87
82
|
def find_station(self, query: str, language: str = "pl") -> list[ExtendedStationInfo]:
|
|
88
83
|
# https://koleo.pl/ls?q=tere&language=pl
|
|
89
|
-
return self._get_json("/ls",
|
|
84
|
+
return self._get_json("/ls", params={"q": query, "language": language})["stations"]
|
|
85
|
+
|
|
86
|
+
def get_station_by_id(self, id: int) -> ExtendedBaseStationInfo:
|
|
87
|
+
# https://koleo.pl/api/v2/main/stations/by_id/24000
|
|
88
|
+
return self._get_json(
|
|
89
|
+
f"/api/v2/main/stations/by_id/{id}",
|
|
90
|
+
)
|
|
90
91
|
|
|
91
92
|
def get_station_by_slug(self, slug: str) -> ExtendedBaseStationInfo:
|
|
92
93
|
# https://koleo.pl/api/v2/main/stations/by_slug/inowroclaw
|
|
@@ -132,16 +133,16 @@ class KoleoAPI:
|
|
|
132
133
|
date: datetime,
|
|
133
134
|
direct: bool = False,
|
|
134
135
|
purchasable: bool = False,
|
|
135
|
-
) ->
|
|
136
|
+
) -> list[ConnectionDetail]:
|
|
136
137
|
params = {
|
|
137
138
|
"query[date]": date.strftime("%d-%m-%Y %H:%M:%S"),
|
|
138
139
|
"query[start_station]": start,
|
|
139
140
|
"query[end_station]": end,
|
|
140
|
-
"query[only_purchasable]":
|
|
141
|
-
"query[
|
|
141
|
+
"query[only_purchasable]": str(direct).lower(),
|
|
142
|
+
"query[only_direct]": str(direct).lower(),
|
|
142
143
|
"query[brand_ids][]": brand_ids,
|
|
143
144
|
}
|
|
144
|
-
return self._get_json("/api/v2/main/connections", params=params)
|
|
145
|
+
return self._get_json("/api/v2/main/connections", params=params)["connections"]
|
|
145
146
|
|
|
146
147
|
def get_brands(self) -> list[ApiBrand]:
|
|
147
148
|
# https://koleo.pl/api/v2/main/brands
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import re
|
|
1
2
|
from argparse import ArgumentParser
|
|
2
3
|
from datetime import datetime, timedelta
|
|
3
4
|
|
|
@@ -22,7 +23,15 @@ class CLI:
|
|
|
22
23
|
) -> None:
|
|
23
24
|
self._client = client
|
|
24
25
|
self._storage = storage
|
|
25
|
-
self.
|
|
26
|
+
self.no_color = no_color
|
|
27
|
+
self.console = Console(color_system="standard", no_color=no_color, highlight=False)
|
|
28
|
+
|
|
29
|
+
def print(self, text, *args, **kwargs):
|
|
30
|
+
if self.no_color:
|
|
31
|
+
result = re.sub(r'\[[^\]]*\]', '', text)
|
|
32
|
+
print(result)
|
|
33
|
+
else:
|
|
34
|
+
self.console.print(text, *args, **kwargs)
|
|
26
35
|
|
|
27
36
|
@property
|
|
28
37
|
def client(self) -> KoleoAPI:
|
|
@@ -44,9 +53,6 @@ class CLI:
|
|
|
44
53
|
def storage(self, storage: Storage):
|
|
45
54
|
self._storage = storage
|
|
46
55
|
|
|
47
|
-
def list_stations(self, name: str):
|
|
48
|
-
...
|
|
49
|
-
|
|
50
56
|
def get_departures(self, station_id: int, date: datetime):
|
|
51
57
|
cache_id = f"dep-{station_id}-{date.strftime("%Y-%m-%d")}"
|
|
52
58
|
trains = (
|
|
@@ -59,7 +65,7 @@ class CLI:
|
|
|
59
65
|
if datetime.fromisoformat(i["departure"]).timestamp() > date.timestamp() # type: ignore
|
|
60
66
|
]
|
|
61
67
|
table = self.trains_on_station_table(trains)
|
|
62
|
-
self.
|
|
68
|
+
self.print(table)
|
|
63
69
|
return table
|
|
64
70
|
|
|
65
71
|
def get_arrivals(self, station_id: int, date: datetime):
|
|
@@ -74,21 +80,32 @@ class CLI:
|
|
|
74
80
|
if datetime.fromisoformat(i["arrival"]).timestamp() > date.timestamp() # type: ignore
|
|
75
81
|
]
|
|
76
82
|
table = self.trains_on_station_table(trains, type=2)
|
|
77
|
-
self.
|
|
83
|
+
self.print(table)
|
|
78
84
|
return table
|
|
79
85
|
|
|
80
86
|
def full_departures(self, station: str, date: datetime):
|
|
81
87
|
st = self.get_station(station)
|
|
82
|
-
station_info = f"[bold blue]{st["name"]}[/bold blue] ID: {st["id"]}"
|
|
83
|
-
self.
|
|
88
|
+
station_info = f"[bold blue][link=https://koleo.pl/dworzec-pkp/{st["name_slug"]}/{date.strftime("%Y-%m-%d")}]{st["name"]} at {date.strftime("%d-%m %H:%M")}[/bold blue] ID: {st["id"]}[/link]"
|
|
89
|
+
self.print(station_info)
|
|
84
90
|
self.get_departures(st["id"], date)
|
|
85
91
|
|
|
86
92
|
def full_arrivals(self, station: str, date: datetime):
|
|
87
93
|
st = self.get_station(station)
|
|
88
|
-
station_info = f"[bold blue]{st["name"]}[/bold blue] ID: {st["id"]}"
|
|
89
|
-
self.
|
|
94
|
+
station_info = f"[bold blue][link=https://koleo.pl/dworzec-pkp/{st["name_slug"]}/{date.strftime("%Y-%m-%d")}]{st["name"]} at {date.strftime("%d-%m %H:%M")}[/bold blue] ID: {st["id"]}[/link]"
|
|
95
|
+
self.print(station_info)
|
|
90
96
|
self.get_arrivals(st["id"], date)
|
|
91
97
|
|
|
98
|
+
def find_station(self, query: str | None):
|
|
99
|
+
if query:
|
|
100
|
+
stations = self.client.find_station(query)
|
|
101
|
+
else:
|
|
102
|
+
stations = (
|
|
103
|
+
self.storage.get_cache("stations") or
|
|
104
|
+
self.storage.set_cache("stations", self.client.get_stations())
|
|
105
|
+
)
|
|
106
|
+
for st in stations:
|
|
107
|
+
self.print(f"[bold blue][link=https://koleo.pl/dworzec-pkp/{st["name_slug"]}]{st["name"]}[/bold blue] ID: {st["id"]}[/link]")
|
|
108
|
+
|
|
92
109
|
def train_info(self, brand: str, name: str, date: datetime):
|
|
93
110
|
brand = brand.upper().strip()
|
|
94
111
|
name = name.strip()
|
|
@@ -113,7 +130,7 @@ class CLI:
|
|
|
113
130
|
train_id = train_calendars["train_calendars"][0]["date_train_map"][date.strftime("%Y-%m-%d")]
|
|
114
131
|
train_details = self.client.get_train(train_id)
|
|
115
132
|
brand = next(iter(i for i in brands if i["id"] == train_details["train"]["brand_id"]), {}).get("logo_text", "")
|
|
116
|
-
parts = [f"{brand} {train_details["train"]["train_full_name"]}"]
|
|
133
|
+
parts = [f"[red]{brand}[/red] [bold blue]{train_details["train"]["train_full_name"]}[/bold blue]"]
|
|
117
134
|
route_start = arr_dep_to_dt(train_details["stops"][0]["departure"])
|
|
118
135
|
route_end = arr_dep_to_dt(train_details["stops"][-1]["arrival"])
|
|
119
136
|
if route_end.hour < route_start.hour or (route_end.hour==route_start.hour and route_end.minute < route_end.minute):
|
|
@@ -131,13 +148,13 @@ class CLI:
|
|
|
131
148
|
start = keys[0]
|
|
132
149
|
for i in range(1, len(keys)):
|
|
133
150
|
if vehicle_types[keys[i]] != vehicle_types[start]:
|
|
134
|
-
parts.append(f"
|
|
151
|
+
parts.append(f" {start} - {keys[i]}: [bold green]{vehicle_types[start]}[/bold green]")
|
|
135
152
|
start = keys[i]
|
|
136
|
-
parts.append(f"
|
|
137
|
-
self.
|
|
138
|
-
self.
|
|
153
|
+
parts.append(f" {start} - {keys[-1]}: [bold green]{vehicle_types[start]}[/bold green]")
|
|
154
|
+
self.print("\n".join(parts))
|
|
155
|
+
self.print(self.train_route_table(train_details))
|
|
139
156
|
|
|
140
|
-
def connections(self, start: str, end: str, date: datetime, brands: list[str], direct: bool
|
|
157
|
+
def connections(self, start: str, end: str, date: datetime, brands: list[str], direct: bool, purchasable: bool):
|
|
141
158
|
start_station = self.get_station(start)
|
|
142
159
|
end_station = self.get_station(end)
|
|
143
160
|
brands = [i.lower().strip() for i in brands]
|
|
@@ -147,7 +164,7 @@ class CLI:
|
|
|
147
164
|
else:
|
|
148
165
|
connection_brands = [i["id"] for i in api_brands if i["name"].lower().strip() in brands or i["logo_text"].lower().strip() in brands]
|
|
149
166
|
if not connection_brands:
|
|
150
|
-
self.
|
|
167
|
+
self.print(f'[bold red]No brands match: "{', '.join(brands)}"[/bold red]')
|
|
151
168
|
exit(2)
|
|
152
169
|
connections = self.client.get_connections(
|
|
153
170
|
start_station["name_slug"],
|
|
@@ -157,6 +174,59 @@ class CLI:
|
|
|
157
174
|
direct,
|
|
158
175
|
purchasable
|
|
159
176
|
)
|
|
177
|
+
parts = [f"[bold blue]{start_station["name"]} → {end_station["name"]} at {date.strftime("%H:%M %d-%m")}[/bold blue]"]
|
|
178
|
+
for i in connections:
|
|
179
|
+
arr = arr_dep_to_dt(i["arrival"])
|
|
180
|
+
dep = arr_dep_to_dt(i["departure"])
|
|
181
|
+
travel_time = (arr - dep).seconds
|
|
182
|
+
parts.append(f"[bold green][link=https://koleo.pl/travel-options/{i["id"]}]{dep.strftime("%H:%M")} - {arr.strftime("%H:%M")}[/bold green] {travel_time//3600}h{(travel_time % 3600)/60:.0f}m {i['distance']}km: [/link]")
|
|
183
|
+
if i["constriction_info"]:
|
|
184
|
+
for constriction in i["constriction_info"]:
|
|
185
|
+
parts.append(f" [bold red]- {constriction} [/bold red]")
|
|
186
|
+
if len(i["trains"]) == 1:
|
|
187
|
+
train = i["trains"][0]
|
|
188
|
+
stop = next(iter(i for i in train["stops"] if i["station_id"] == train["start_station_id"]), {})
|
|
189
|
+
stop_station = (
|
|
190
|
+
start_station if stop["station_id"] == start_station["id"] else
|
|
191
|
+
self.storage.get_cache(f"st-{stop['station_id']}")
|
|
192
|
+
or self.storage.set_cache(f"st-{stop['station_id']}", self.client.get_station_by_id(stop['station_id']))
|
|
193
|
+
)
|
|
194
|
+
platform = convert_platform_number(stop["platform"]) if stop["platform"] else ""
|
|
195
|
+
position_info = f"{platform}/{stop["track"]}" if stop["track"] else platform
|
|
196
|
+
brand = next(iter(i for i in api_brands if i["id"] == train["brand_id"]), {}).get("logo_text")
|
|
197
|
+
parts[-1]+=f" [red]{brand}[/red] {train["train_full_name"]}[purple] {stop_station['name']} {position_info}[/purple]"
|
|
198
|
+
else:
|
|
199
|
+
previous_arrival: datetime | None = None
|
|
200
|
+
for train in i["trains"]:
|
|
201
|
+
brand = next(iter(i for i in api_brands if i["id"] == train["brand_id"]), {}).get("logo_text")
|
|
202
|
+
|
|
203
|
+
fs = next(iter(i for i in train["stops"] if i["station_id"] == train["start_station_id"]), {})
|
|
204
|
+
fs_station = (
|
|
205
|
+
start_station if fs["station_id"] == start_station["id"] else
|
|
206
|
+
self.storage.get_cache(f"st-{fs['station_id']}")
|
|
207
|
+
or self.storage.set_cache(f"st-{fs['station_id']}", self.client.get_station_by_id(fs['station_id']))
|
|
208
|
+
)
|
|
209
|
+
fs_platform = convert_platform_number(fs["platform"]) if fs["platform"] else ""
|
|
210
|
+
fs_arr = arr_dep_to_dt(fs["arrival"])
|
|
211
|
+
fs_dep = arr_dep_to_dt(fs["departure"])
|
|
212
|
+
fs_info = f"[bold green]{fs_dep.strftime("%H:%M")} [/bold green][purple]{fs_station['name']} {f"{fs_platform}/{fs["track"]}" if fs["track"] else fs_platform}[/purple]"
|
|
213
|
+
|
|
214
|
+
ls = next(iter(i for i in train["stops"] if i["station_id"] == train["end_station_id"]), {})
|
|
215
|
+
ls_station = (
|
|
216
|
+
start_station if ls["station_id"] == start_station["id"] else
|
|
217
|
+
self.storage.get_cache(f"st-{ls['station_id']}")
|
|
218
|
+
or self.storage.set_cache(f"st-{ls['station_id']}", self.client.get_station_by_id(ls['station_id']))
|
|
219
|
+
)
|
|
220
|
+
ls_platform = convert_platform_number(ls["platform"]) if ls["platform"] else ""
|
|
221
|
+
ls_arr = arr_dep_to_dt(ls["arrival"])
|
|
222
|
+
ls_dep = arr_dep_to_dt(ls["departure"])
|
|
223
|
+
ls_info = f"[bold green]{ls_arr.strftime("%H:%M")} [/bold green][purple]{ls_station['name']} {f"{ls_platform}/{ls["track"]}" if ls["track"] else ls_platform}[/purple]"
|
|
224
|
+
connection_time = (fs_dep - previous_arrival).seconds if previous_arrival else ""
|
|
225
|
+
previous_arrival = ls_arr
|
|
226
|
+
if connection_time:
|
|
227
|
+
parts.append(f" {connection_time//3600}h{(connection_time % 3600)/60:.0f}m at [purple]{fs_station['name']}[/purple]")
|
|
228
|
+
parts.append(f" [red]{brand}[/red] {train["train_full_name"]} {fs_info} - {ls_info}")
|
|
229
|
+
self.print("\n".join(parts))
|
|
160
230
|
|
|
161
231
|
def trains_on_station_table(self, trains: list[TrainOnStationInfo], type: int = 1):
|
|
162
232
|
parts = []
|
|
@@ -168,7 +238,7 @@ class CLI:
|
|
|
168
238
|
platform = convert_platform_number(train["platform"]) if train["platform"] else ""
|
|
169
239
|
position_info = f"{platform}/{train["track"]}" if train["track"] else platform
|
|
170
240
|
parts.append(
|
|
171
|
-
f"[bold green]{time[11:16]}[/bold green] {brand} {train["train_full_name"]}[purple] {train["stations"][0]["name"]} {position_info}[/purple]"
|
|
241
|
+
f"[bold green]{time[11:16]}[/bold green] [red]{brand}[/red] {train["train_full_name"]}[purple] {train["stations"][0]["name"]} {position_info}[/purple]"
|
|
172
242
|
)
|
|
173
243
|
return "\n".join(parts)
|
|
174
244
|
|
|
@@ -190,7 +260,7 @@ class CLI:
|
|
|
190
260
|
f"st-{slug}", self.client.get_station_by_slug(slug)
|
|
191
261
|
)
|
|
192
262
|
except self.client.errors.KoleoNotFound:
|
|
193
|
-
self.
|
|
263
|
+
self.print(f'[bold red]Station not found: "{station}"[/bold red]')
|
|
194
264
|
exit(2)
|
|
195
265
|
|
|
196
266
|
def main():
|
|
@@ -251,9 +321,18 @@ def main():
|
|
|
251
321
|
)
|
|
252
322
|
train_route.set_defaults(func=cli.train_info, pass_=["brand", "name", "date"])
|
|
253
323
|
|
|
324
|
+
stations = subparsers.add_parser("stations", aliases=["s", "find", "f", "stacje", "ls"], help="Allows you to find stations by their name")
|
|
325
|
+
stations.add_argument(
|
|
326
|
+
"query",
|
|
327
|
+
help="The station name",
|
|
328
|
+
default=None,
|
|
329
|
+
nargs="?",
|
|
330
|
+
)
|
|
331
|
+
stations.set_defaults(func=cli.find_station, pass_=["query"])
|
|
332
|
+
|
|
254
333
|
connections = subparsers.add_parser(
|
|
255
334
|
"connections",
|
|
256
|
-
aliases=["do", "z", "szukaj", "path"
|
|
335
|
+
aliases=["do", "z", "szukaj", "path"],
|
|
257
336
|
help="Allows you to search for connections from a to b",
|
|
258
337
|
)
|
|
259
338
|
connections.add_argument("start", help="The starting station", type=str)
|
|
@@ -283,7 +362,7 @@ def main():
|
|
|
283
362
|
help="whether or not the result should only trains purchasable on koleo",
|
|
284
363
|
action="store_true", default=False
|
|
285
364
|
)
|
|
286
|
-
connections.set_defaults(func=cli.connections, pass_=["start", "end", "brands", "date", "direct" "purchasable"])
|
|
365
|
+
connections.set_defaults(func=cli.connections, pass_=["start", "end", "brands", "date", "direct", "purchasable"])
|
|
287
366
|
|
|
288
367
|
args = parser.parse_args()
|
|
289
368
|
|
|
@@ -291,6 +370,7 @@ def main():
|
|
|
291
370
|
client = KoleoAPI()
|
|
292
371
|
cli.client, cli.storage = client, storage
|
|
293
372
|
cli.console.no_color = args.nocolor
|
|
373
|
+
cli.no_color = args.nocolor
|
|
294
374
|
if hasattr(args, "station") and args.station is None:
|
|
295
375
|
args.station = storage.favourite_station
|
|
296
376
|
elif hasattr(args, "station") and args.save:
|
|
@@ -178,7 +178,60 @@ class TrainDetailResponse(t.TypedDict):
|
|
|
178
178
|
stops: list[TrainStop]
|
|
179
179
|
|
|
180
180
|
|
|
181
|
+
class ConnectionTrainStop(t.TypedDict):
|
|
182
|
+
arrival: TimeDict | str # WTF KOLEO!!!!
|
|
183
|
+
departure: TimeDict | str # WTF KOLEO!!!!
|
|
184
|
+
distance: int
|
|
185
|
+
in_path: bool
|
|
186
|
+
station_id: int
|
|
187
|
+
next_day: bool
|
|
188
|
+
position: int
|
|
189
|
+
train_nr: int
|
|
190
|
+
brand_id: int
|
|
191
|
+
entry_only: bool
|
|
192
|
+
exit_only: bool
|
|
193
|
+
platform: str
|
|
194
|
+
track: str
|
|
195
|
+
on_demand: bool
|
|
196
|
+
|
|
197
|
+
|
|
181
198
|
class ConnectiontrainDetail(TrainDetail):
|
|
199
|
+
arrival: TimeDict | str # WTF KOLEO!!!!
|
|
200
|
+
departure: TimeDict | str # WTF KOLEO!!!!
|
|
201
|
+
stops: list[ConnectionTrainStop]
|
|
202
|
+
bookable: bool
|
|
203
|
+
train_attribute_ids: list[int]
|
|
204
|
+
travel_time: int
|
|
205
|
+
direction: str
|
|
206
|
+
start_station_id: int
|
|
207
|
+
end_station_id: int
|
|
208
|
+
fixed_carriage_composition: bool
|
|
209
|
+
is_option_groups_available: bool
|
|
182
210
|
|
|
211
|
+
|
|
212
|
+
class ErrorDict(t.TypedDict):
|
|
213
|
+
type: str
|
|
214
|
+
value: str
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
class ConnectionDetail(t.TypedDict):
|
|
218
|
+
id: int
|
|
219
|
+
distance: int
|
|
220
|
+
purchasable: bool
|
|
221
|
+
purchasable_errors: list[ErrorDict]
|
|
222
|
+
travel_time: int
|
|
223
|
+
changes: int
|
|
224
|
+
needs_document: bool
|
|
225
|
+
brand_ids: list[int]
|
|
226
|
+
start_station_id: int
|
|
227
|
+
end_station_id: int
|
|
183
228
|
arrival: TimeDict | str # WTF KOLEO!!!!
|
|
184
229
|
departure: TimeDict | str # WTF KOLEO!!!!
|
|
230
|
+
bookable: bool
|
|
231
|
+
special_event_slug: str | None
|
|
232
|
+
is_advanced_travel_options: bool
|
|
233
|
+
is_child_birthday_required: bool
|
|
234
|
+
max_passengers_count: bool
|
|
235
|
+
constriction_info: list[str]
|
|
236
|
+
is_estimated_timetable_available: bool
|
|
237
|
+
trains: list[ConnectiontrainDetail]
|
|
@@ -16,6 +16,12 @@ def parse_datetime(s: str):
|
|
|
16
16
|
pass
|
|
17
17
|
if s[0] == "+":
|
|
18
18
|
return datetime.now().replace(hour=0, minute=0) + timedelta(days=int(s[1:]))
|
|
19
|
+
try:
|
|
20
|
+
now = datetime.now()
|
|
21
|
+
dt = datetime.strptime(s, "%d-%m %H:%M")
|
|
22
|
+
return dt.replace(year=now.year)
|
|
23
|
+
except ValueError:
|
|
24
|
+
pass
|
|
19
25
|
return datetime.combine(datetime.now(), datetime.strptime(s, "%H:%M").time())
|
|
20
26
|
|
|
21
27
|
|
|
@@ -58,8 +64,9 @@ NUMERAL_TO_ARABIC = {
|
|
|
58
64
|
"X": 10,
|
|
59
65
|
"XI": 11, # wtf poznań???
|
|
60
66
|
"XII": 12, # just to be safe
|
|
67
|
+
"BUS": "BUS"
|
|
61
68
|
}
|
|
62
69
|
|
|
63
70
|
|
|
64
|
-
def convert_platform_number(number: str) -> int | None:
|
|
71
|
+
def convert_platform_number(number: str) -> int | None | str:
|
|
65
72
|
return NUMERAL_TO_ARABIC.get(number)
|
|
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
|