Compare commits

..
2 Commits
Author SHA1 Message Date
Kaaninchen 21a279839d update favicon 2026-08-23 17:57:01 +02:00
Kaaninchen 1c006731a4 feat: priority list 2026-08-23 17:21:22 +02:00
8 changed files with 65 additions and 52 deletions
+24
View File
@@ -121,6 +121,30 @@ For every station inside of the `stations.json` you'll find an ID. You can add t
This is especially useful if you want to add a station whose name isn't unique and also used by other stations. The bot would falsely use the first station with the same name and consider it an exact match, even if you wanted a different one. This won't happen with the ID, as every ID is uniquely assigned to only one station. This is especially useful if you want to add a station whose name isn't unique and also used by other stations. The bot would falsely use the first station with the same name and consider it an exact match, even if you wanted a different one. This won't happen with the ID, as every ID is uniquely assigned to only one station.
##### priority
You can define priorities of transport modes while selecting a connection. Leave empty to disable
The list should be descending, with "1" as the most important transport mode. For example, let's say, the bot should always choose Trains and other longer distance public transport modes. If it can't find any, then it should resort to Metros/Subways/Suburbans. If these are also missing at that station, then it should just use Busses/Trams:
```json
"priority": {
"HIGHSPEED_RAIL": 1,
"LONG_DISTANCE": 1,
"NIGHT_RAIL": 1,
"REGIONAL_RAIL": 1,
"COACH": 1,
"FERRY": 1,
"METRO": 2,
"SUBURBAN": 2,
"SUBWAY": 2,
"BUS": 3,
"TRAM": 3
}
```
A transport mode that isn't in the priority list would immediately get assigned the value of "99", making it near impossible to get that connection. Except when there are no other connections available, of course.
You can find the MODE names either in the console log or the stations.json from [helper tool](#stations)
##### blacklist ##### blacklist
You can blacklist specific types of transport, the bot would then skip them while selecting a connection. You can get the type in your console (mode) You can blacklist specific types of transport, the bot would then skip them while selecting a connection. You can get the type in your console (mode)
```sh ```sh
+2
View File
@@ -14,6 +14,8 @@
"Helsinki" "Helsinki"
], ],
"IDs": [], "IDs": [],
"priority: "{
}",
"blacklist": [ "blacklist": [
"OTHER", "OTHER",
"RIDE_SHARING" "RIDE_SHARING"
+35 -47
View File
@@ -142,10 +142,12 @@ def get_random_stop_id() -> str | None:
return None return None
stop_ids_list = list(stop_ids.keys()) stop_ids_list = list(stop_ids.keys())
chosen_stop_id = random.choice(stop_ids_list)
if len(stop_ids_list) > 1: if len(stop_ids_list) > 1:
logger(f"No station associated as '{assigned_station}', choosing random from similar named stations") logger(f"No station associated as '{assigned_station}', choosing random from similar named stations")
logger(f"Run `python run main.py stations` to get exact station names") logger(f"Run `python run main.py stations` to get exact station names")
chosen_stop_id, chosen_station = random.choice(list(stop_ids.items())) logger(f"Selected station: {stop_ids[chosen_stop_id]}")
return chosen_stop_id return chosen_stop_id
def get_random_connection(stop_id: str) -> str | None: def get_random_connection(stop_id: str) -> str | None:
@@ -153,60 +155,46 @@ def get_random_connection(stop_id: str) -> str | None:
return None return None
now = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ") now = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
cursor = None params = {"stopId": stop_id, "n": 50, "time": now}
max_pages = 5
min_results = 5
trip_ids = []
all_stop_times = []
for _ in range(max_pages): try:
params = { response = requests.get(f"{endpoint}/api/v5/stoptimes", params=params, headers=headers)
"stopId": stop_id, response.raise_for_status()
"n": 20, data = response.json()
"time": now, except requests.RequestException as e:
} logger(e, "Error")
if cursor: return None
params["pageCursor"] = cursor
try: candidates = []
response = requests.get(f"{endpoint}/api/v5/stoptimes", params=params, headers=headers) for entry in data.get("stopTimes", []):
response.raise_for_status() if entry["mode"] in blacklist:
data = response.json() continue
except requests.RequestException as e: candidates.append(entry)
logger(e, "Error")
break
stop_times = data.get("stopTimes", []) if not candidates:
all_stop_times.extend(stop_times) logger("Couldn't find any connections", "error")
return None
for entry in stop_times: if config.connections.priority:
trip_id = entry["tripId"] best_priority = None
if entry["mode"] in blacklist: for entry in candidates:
continue priority = config.connections.priority.get(entry["mode"], 99)
else: if best_priority is None or priority < best_priority:
trip_ids.append(entry["tripId"]) best_priority = priority
if len(trip_ids) >= min_results: best_candidates = []
break for entry in candidates:
priority = config.connections.priority.get(entry["mode"], 99)
if priority == best_priority:
best_candidates.append(entry)
cursor = data.get("nextPageCursor") chosen = random.choice(best_candidates)
if not cursor: else:
break chosen = random.choice(candidates)
if not trip_ids:
logger("Couldn't find any connections", "error")
return None
trip_id = random.choice(trip_ids)
from_station = None
for entry in all_stop_times:
if entry.get("tripId") == trip_id:
from_station = entry.get("place", {}).get("name")
break
return { return {
"trip_id": trip_id, "trip_id": chosen["tripId"],
"from_station": from_station "from_station": chosen.get("place", {}).get("name"),
} }
def get_trip_details(random_connection: dict | None) -> dict | None: def get_trip_details(random_connection: dict | None) -> dict | None:
+2 -1
View File
@@ -1,5 +1,5 @@
import json import json
from dataclasses import dataclass, field from dataclasses import dataclass
from typing import Optional from typing import Optional
@dataclass @dataclass
@@ -15,6 +15,7 @@ class DiscordConfig:
class ConnectionsConfig: class ConnectionsConfig:
stations: list[str] stations: list[str]
IDs: list[str] IDs: list[str]
priority: dict
blacklist: list[str] blacklist: list[str]
min_duration: int min_duration: int
timezone: str timezone: str
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

@@ -1,2 +0,0 @@
SPDX-FileCopyrightText: 2024 Mathis Brüchert <[email protected]>
SPDX-License-Identifier: CC-BY-SA-4.0
+1 -1
View File
@@ -9,7 +9,7 @@ lang_embed = lang.embeds
def build_embed_footer(slogans): def build_embed_footer(slogans):
footer_notice = f"https://transitous.org/sources/ • Maps (C) CARTO (C) OpenStreetMap.org contributors" footer_notice = f"https://transitous.org/sources/ • Maps (C) CARTO (C) OpenStreetMap.org contributors"
icon = "https://raw.githubusercontent.com/kaaninchen/Gleiswechsel/refs/heads/main/src/data/assets/transitous-logo.png" icon = "https://api.transitous.org/favicon.png"
if slogans is not None: if slogans is not None:
footer_text = f"{random.choice(slogans)}{footer_notice}" footer_text = f"{random.choice(slogans)}{footer_notice}"