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 discord
from datetime import datetime
from datetime import datetime, timedelta
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):
parsed_time = datetime.strptime(timestr, "%H:%M")
now = datetime.now()
final_datetime = datetime.now().replace(
hour=parsed_time.hour,
minute=parsed_time.minute,
second=0,
microsecond=0
)
if final_datetime <= now:
final_datetime += timedelta(days=1)
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:
if handlers.current is None:
return None
conn = handlers.current
info = handlers.train_info
arrival = format_iso_timestamp(info["arrival"])
departure = format_timestamp(conn['departure'])
operator = operator_infos(conn["train"])
embed = discord.Embed(
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"]
)
@@ -32,7 +45,7 @@ def build_info_embed() -> discord.Embed | None:
if operator["name"] == "Unbekannter Anbieter":
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})"
else:
operator_name = operator["name"]
+41 -12
View File
@@ -1,35 +1,64 @@
import discord
import time
from datetime import datetime, timedelta
import asyncio
from src.config import config
from src.utils import random_connection
from src.utils import random_connection, get_train_info, logger
current = None
_scheduled_task: asyncio.Task | None = None
async def rename_vc(bot: discord.Bot) -> bool:
global current, train_name
async def rename_vc(bot: discord.Bot, scheduled = False) -> bool:
global current, train_name, train_info, _scheduled_task
guild = bot.get_guild(int(config["server"]))
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
channel = guild.get_channel(int(config["vc"]))
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
current = random_connection()
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_ID = current['train'].split()[1]
else:
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']}"
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("-----------------------------------------")
current_time = time.strftime('%X')
print(f"{current_time}: Umstieg: {train_name} (Typ {train_type}) von {current['station']}")
print(f"{current_time}: Wenn hier keine Nachricht mehr kommt bin ich im Cooldown")
logger(f"Umstieg: {train_name} (Typ {train_type}) von {current['station']}")
logger(f"Wenn der Name nicht geändert wird bin ich im Cooldown")
await channel.edit(name=f"{config['formatting']}{train_name}",)
print(f"{current_time}: Name geändert!")
return True
logger(f"Name geändert!")
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 random
from datetime import datetime
from src.config import config
from src.data.operators import OPERATORS
@@ -30,7 +31,8 @@ def random_connection():
"route": dep['route'],
"departure": dep['scheduledDeparture'],
"via": dep['via'],
"station": station
"station": station,
"train_number": dep['trainNumber']
}
@@ -46,4 +48,25 @@ def format_via_list(via: list[str]):
return ""
if len(via) == 1:
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}")