Files
gleiswechsel/src/utils.py
T

149 lines
4.4 KiB
Python

import requests
import random
import os
import importlib
from datetime import datetime
from src.config import config
import src.data.operators as operators_module
import src.data.emojis as emojis
_operators_mtime = None
dbf = config.get("dbf", "https://dbf.finalrewind.org")
def _reload_operators_if_changed():
global _operators_mtime
path = operators_module.__file__
current_mtime = os.path.getmtime(path)
if _operators_mtime is None:
_operators_mtime = current_mtime
return
if current_mtime != _operators_mtime:
importlib.reload(operators_module)
_operators_mtime = current_mtime
logger("operators.py wurde automatisch neu geladen (Änderungen erkannt)")
def random_connection():
available_stations = config["stations"].copy()
while True:
if not available_stations:
logger("Keine validen Bahnhöfe. Schlag den richtigen Bahnhofsnamen auf {dbf} nach", "fatal")
station = random.choice(available_stations)
url = f"{dbf}/{station}.json"
blacklist = config.get("blacklist", [])
try:
response = requests.get(url)
response.raise_for_status()
data = response.json()
except requests.RequestException as e:
logger(f"Fehler beim aussuchen der Verbindung: {e}", "fatal")
return
if response.status_code == 300:
logger(f"Bahnhof '{station}' konnte nicht gefunden werden ({url})", "error")
available_stations.remove(station)
continue
departures = [
d for d in data.get("departures", [])
if d.get("scheduledDeparture") and d.get("destination") != station
and not d.get("train", "").startswith(tuple(blacklist))
]
if not departures:
continue
if not config['random']:
dep = departures[0]
else:
dep = random.choice(departures)
return {
"train": dep['train'],
"destination": dep['destination'],
"route": dep['route'],
"departure": dep['scheduledDeparture'],
"via": dep['via'],
"station": station,
"train_number": dep['trainNumber']
}
def get_train_info(station, train_ID, train_type):
url = f"{dbf}/z/{train_type}%20{train_ID}/{station}.json"
logger(f"Fetche {url}")
try:
response = requests.get(url)
response.raise_for_status()
data = response.json()
except requests.RequestException as e:
logger(f"ReqestException Fehler: {e}")
return None
dep = data.get("departure", [])
if not dep:
logger("Kein departure Feld gefunden", "error")
return None
route_post = dep.get("route_post_diff")
if not route_post:
logger("Kein route_post_diff Feld gefunden", "error")
return None
arrival_iso = route_post[-1].get("sched_arr")
if not arrival_iso:
logger("Keine Ankunftszeit gefunden", "error")
return None
return {
"arrival": arrival_iso,
"operators": dep.get("operators"),
}
def format_via_list(via: list[str]):
if not via:
return ""
if len(via) == 1:
return via[0]
return ", ".join(via[:-1]) + " und " + via[-1]
def resolve_operator(operators):
if not operators:
return None
for op in operators:
if op in operators_module.OPERATOR_ALIASES or op in operators_module.OPERATORS:
return op
return operators[0]
def operator_metadata(operator):
_reload_operators_if_changed()
if not operator:
return operators_module.OPERATORS["fallback"]
if operator in operators_module.OPERATOR_ALIASES:
return operators_module.OPERATOR_ALIASES[operator]
return operators_module.OPERATORS.get(operator, operators_module.OPERATORS["fallback"])
def get_channel_formatting(train_type):
formatting = config.get("formatting", "")
train_emoji = ""
if config.get("emojis", True):
train_emoji = emojis.train_types.get(train_type)
if train_emoji is None:
train_emoji = emojis.emoji_list.get("Fallback", "")
return f"{train_emoji}{formatting}"
def logger(msg, log_type="info"):
status = log_type.upper()
current_time = datetime.now().strftime('%X')
print(f"{current_time}: {status}: {msg}")
if status == "FATAL":
os._exit(1)