Zeitschleife anhand von Echtzeit Ankunftsuhrzeit hinzugefügt

Ein recht großer commit. Mit dabei ist ein logger, erweiterte Informationen zu den Zügen und eine Zeitschleife, welche sich anhand der echtzeit ankunftsdaten des Zuges richtet. Der Commit benötigt auf jeden fall testing
This commit is contained in:
Kaaninchen
2026-07-17 22:17:59 +02:00
parent f3ab8441ee
commit d8cfe7b0d7
3 changed files with 83 additions and 18 deletions
+17 -4
View File
@@ -1,29 +1,42 @@
import random import random
import discord import discord
from datetime import datetime from datetime import datetime, timedelta
import src.handlers as handlers import src.handlers as handlers
from src.utils import operator_infos, format_via_list from src.utils import operator_infos, format_via_list, logger
def format_timestamp(timestr): def format_timestamp(timestr):
parsed_time = datetime.strptime(timestr, "%H:%M") parsed_time = datetime.strptime(timestr, "%H:%M")
now = datetime.now()
final_datetime = datetime.now().replace( final_datetime = datetime.now().replace(
hour=parsed_time.hour, hour=parsed_time.hour,
minute=parsed_time.minute, minute=parsed_time.minute,
second=0, second=0,
microsecond=0 microsecond=0
) )
if final_datetime <= now:
final_datetime += timedelta(days=1)
return discord.utils.format_dt(final_datetime, style="t") return discord.utils.format_dt(final_datetime, style="t")
def format_iso_timestamp(isostr):
parsed_time = discord.utils.parse_time(isostr)
return discord.utils.format_dt(parsed_time, style="t")
def build_info_embed() -> discord.Embed | None: def build_info_embed() -> discord.Embed | None:
if handlers.current is None: if handlers.current is None:
return None return None
conn = handlers.current conn = handlers.current
info = handlers.train_info
arrival = format_iso_timestamp(info["arrival"])
departure = format_timestamp(conn['departure'])
operator = operator_infos(conn["train"]) operator = operator_infos(conn["train"])
embed = discord.Embed( embed = discord.Embed(
title=handlers.train_name, title=handlers.train_name,
description=f"Abfahrt von {conn['station']} um {format_timestamp(conn['departure'])}", description=f"Abfahrt von {conn['station']} um {departure}. Ankunft um {arrival}",
color=operator["color"] color=operator["color"]
) )
@@ -32,7 +45,7 @@ def build_info_embed() -> discord.Embed | None:
if operator["name"] == "Unbekannter Anbieter": if operator["name"] == "Unbekannter Anbieter":
anbieter = conn['train'].split()[0] anbieter = conn['train'].split()[0]
print(f"INFO: Unbekannter Anbieter für Typ {anbieter}") logger(f"INFO: Unbekannter Anbieter für Typ {anbieter}")
operator_name = f"{operator['name']} (Typ: {anbieter})" operator_name = f"{operator['name']} (Typ: {anbieter})"
else: else:
operator_name = operator["name"] operator_name = operator["name"]
+41 -12
View File
@@ -1,35 +1,64 @@
import discord import discord
import time from datetime import datetime, timedelta
import asyncio
from src.config import config from src.config import config
from src.utils import random_connection from src.utils import random_connection, get_train_info, logger
current = None current = None
_scheduled_task: asyncio.Task | None = None
async def rename_vc(bot: discord.Bot) -> bool: async def rename_vc(bot: discord.Bot, scheduled = False) -> bool:
global current, train_name global current, train_name, train_info, _scheduled_task
guild = bot.get_guild(int(config["server"])) guild = bot.get_guild(int(config["server"]))
if guild is None: if guild is None:
print(f"Es konnte kein Server mit der ID {config['server']} gefunden werden! Ist der Bot ein Member?") logger(f"Es konnte kein Server mit der ID {config['server']} gefunden werden! Ist der Bot ein Member?")
return False return False
channel = guild.get_channel(int(config["vc"])) channel = guild.get_channel(int(config["vc"]))
if not isinstance(channel, discord.VoiceChannel): if not isinstance(channel, discord.VoiceChannel):
print(f"Es konnte kein VC mit der ID {config['vc']} auf dem Server gefunden werden") logger(f"Es konnte kein VC mit der ID {config['vc']} auf dem Server gefunden werden")
return False return False
current = random_connection() current = random_connection()
train_type = current['train'].split()[0] train_type = current['train'].split()[0]
if train_type in ("IC", "ICE", "NJ"): if train_type in ("IC", "ICE", "NJ", "ES"):
train = current['train'] train = current['train']
train_ID = current['train'].split()[1]
else: else:
train = current['train'].split()[1] train = current['train'].split()[1]
train_ID = current['train_number']
train_info = get_train_info(station=current['station'], train_ID=train_ID, train_type=train_type)
train_name = f"{train} nach {current['destination']}" train_name = f"{train} nach {current['destination']}"
if not scheduled and _scheduled_task and not _scheduled_task.done():
_scheduled_task.cancel()
if train_info:
_scheduled_task = asyncio.create_task(_schedule_next_umstieg(bot, train_info["arrival"]))
print("-----------------------------------------") print("-----------------------------------------")
current_time = time.strftime('%X') logger(f"Umstieg: {train_name} (Typ {train_type}) von {current['station']}")
print(f"{current_time}: Umstieg: {train_name} (Typ {train_type}) von {current['station']}") logger(f"Wenn der Name nicht geändert wird bin ich im Cooldown")
print(f"{current_time}: Wenn hier keine Nachricht mehr kommt bin ich im Cooldown")
await channel.edit(name=f"{config['formatting']}{train_name}",) await channel.edit(name=f"{config['formatting']}{train_name}",)
print(f"{current_time}: Name geändert!") logger(f"Name geändert!")
return True
return True
async def _schedule_next_umstieg(bot, arrival_iso):
try:
arrival = datetime.fromisoformat(arrival_iso)
# wait_seconds = (arrival - datetime.now()).total_seconds()
wait_seconds = 30
if wait_seconds > 0:
remaining = str(timedelta(seconds=wait_seconds))
logger(f"In {remaining} gehts weiter!...")
await asyncio.sleep(wait_seconds)
logger("Zug angekommen, wähle neue Verbindung...")
await rename_vc(bot, scheduled=True)
except asyncio.CancelledError:
logger("Geplanter Umstieg wurde abgebrochen (manueller /umstieg dazwischen oder CTRL + C)")
raise
+25 -2
View File
@@ -1,5 +1,6 @@
import requests import requests
import random import random
from datetime import datetime
from src.config import config from src.config import config
from src.data.operators import OPERATORS from src.data.operators import OPERATORS
@@ -30,7 +31,8 @@ def random_connection():
"route": dep['route'], "route": dep['route'],
"departure": dep['scheduledDeparture'], "departure": dep['scheduledDeparture'],
"via": dep['via'], "via": dep['via'],
"station": station "station": station,
"train_number": dep['trainNumber']
} }
@@ -46,4 +48,25 @@ def format_via_list(via: list[str]):
return "" return ""
if len(via) == 1: if len(via) == 1:
return via[0] return via[0]
return ", ".join(via[:-1]) + " und " + via[-1] return ", ".join(via[:-1]) + " und " + via[-1]
def get_train_info(station, train_ID, train_type):
url = f"https://dbf.finalrewind.org/z/{train_type}%20{train_ID}/{station}.json"
try:
response = requests.get(url)
response.raise_for_status()
data = response.json()
except requests.RequestException:
return None
dep = data.get("departure", [])
arrival_iso = dep["route_post_diff"][-1]["sched_arr"]
return {
"arrival": arrival_iso,
"operators": dep["operators"]
}
def logger(msg):
current_time = datetime.now().strftime('%X')
print(f"{current_time}: {msg}")