From 723df6bf993fd2795e68c3331637a11c70e81ebf Mon Sep 17 00:00:00 2001 From: Kaaninchen <124433727+kaaninchen@users.noreply.github.com> Date: Fri, 17 Jul 2026 01:19:24 +0200 Subject: [PATCH] a lot i forgot to do commits, how unprofessional... i restructured the bot and made the /info and /umstieg command. Bot's almost done, the only thing missing now is the loop --- main.py | 24 +++++++++++++++- src/commands.py | 22 ++++++++++++++ src/data/operators.py | 30 +++++++++++++++++++ src/data/status.py | 11 +++++++ src/embeds.py | 67 +++++++++++++++++++++++++++++++++++++++++++ src/state.py | 31 ++++++++++++++++++++ src/utils.py | 19 +++++++++++- 7 files changed, 202 insertions(+), 2 deletions(-) create mode 100644 src/data/operators.py create mode 100644 src/data/status.py create mode 100644 src/embeds.py create mode 100644 src/state.py diff --git a/main.py b/main.py index 2b7013f..5845207 100644 --- a/main.py +++ b/main.py @@ -1,12 +1,34 @@ import discord +import random +from discord.ext import tasks from config import config +from src.state import rename_vc +from src.commands import setup_commands +from src.embeds import build_error_embed +from src.data.status import discord_status + bot = discord.Bot(intents=discord.Intents.all()) +setup_commands(bot) + +@tasks.loop(minutes=1) +async def change_status(): + status = random.choice(discord_status) + print(status) + await bot.change_presence(activity=discord.Game(name=status)) @bot.event async def on_ready(): - await bot.change_presence(activity=discord.Game(name = "Casino")) print(f"{bot.user} ist online") + if not change_status.is_running(): + change_status.start() + await rename_vc(bot) + +@bot.event +async def on_application_command_error(ctx, error): + embed = build_error_embed(f"Ein Fehler ist aufgetreten: {error}") + await ctx.respond(embed=embed) + try: bot.run(config['token']) diff --git a/src/commands.py b/src/commands.py index e69de29..1799fae 100644 --- a/src/commands.py +++ b/src/commands.py @@ -0,0 +1,22 @@ +import discord +from src.state import rename_vc +from src.embeds import build_info_embed, build_error_embed + +def setup_commands(bot: discord.Bot): + @bot.slash_command(description="Steige in den nächsten Zug! Beachte das Discord Spam limit (2x in 10min)") + async def umstieg(ctx): + success = await rename_vc(bot) + if not success: + await ctx.respond("Kanal nicht gefunden") + return + + embed = build_info_embed() + await ctx.respond("Informationen zur neuen Fahrt:", embed=embed) + + @bot.slash_command(description="Informationen über die aktuelle Fahrt") + async def info(ctx): + embed = build_info_embed() + if embed is None: + await ctx.respond("Noch keine Verbindung gesetzt.") + return + await ctx.respond(embed=embed) diff --git a/src/data/operators.py b/src/data/operators.py new file mode 100644 index 0000000..507c6e7 --- /dev/null +++ b/src/data/operators.py @@ -0,0 +1,30 @@ +db_logo = "https://marketingportal.extranet.deutschebahn.com/resource/blob/13602522/c53f806b9df966e144010b276af72dd2/Bild_09-data.png" +db_slogans = ["Senk ju vor träwelling wis Deutsche Bahn.", "Bitte beachten Sie die umgekehrte Wagenreihung.", "Zurückbleiben bitte!", "Alle reden vom Wetter. Wir nicht.", "Die Bahn macht mobil.", "Grün abgefahren"] + +OPERATORS = { + # alles außer slogan ist ESSENZIELL für den Bot. + # Color ist Hex Color Code mit 0x am anfang. + "fallback": { + "name": "Unbekannter Anbieter", + "logo": "https://upload.wikimedia.org/wikipedia/commons/2/20/Bahn_aus_Zusatzzeichen_1024-15_A.png", + "color": 0x000000 + }, + "ICE": { + "name": "Deutsche Bahn", + "logo": db_logo, + "color": 0xEC0016, + "slogan": db_slogans + }, + "RB": { + "name": "DB Regio", + "logo": db_logo, + "color": 0xEC0016, + "slogan": db_slogans + }, + "RE": { + "name": "DB Regio", + "logo": db_logo, + "color": 0xEC0016, + "slogan": db_slogans + } +} \ No newline at end of file diff --git a/src/data/status.py b/src/data/status.py new file mode 100644 index 0000000..3e3d0d6 --- /dev/null +++ b/src/data/status.py @@ -0,0 +1,11 @@ +discord_status = [ + "Tschu-Tschu!", + "Heute ca. 15 Minuten später", + "Heute ohne Halt in Hamburg-Altona", + "Störung an der Weiche", + "Heute ohne Bordbistro", + "SEV ist eingerichtet", + "BahnBonus Status", + "Gleiswechsel!", + "Zug entgleist :(" +] \ No newline at end of file diff --git a/src/embeds.py b/src/embeds.py new file mode 100644 index 0000000..353f709 --- /dev/null +++ b/src/embeds.py @@ -0,0 +1,67 @@ +import random +import discord +from datetime import datetime +import src.state as state +from src.utils import operator_infos, format_via_list + +def format_timestamp(timestr): + parsed_time = datetime.strptime(timestr, "%H:%M") + final_datetime = datetime.now().replace( + hour=parsed_time.hour, + minute=parsed_time.minute, + second=0, + microsecond=0 + ) + return discord.utils.format_dt(final_datetime, style="t") + +def build_info_embed() -> discord.Embed | None: + if state.name is None: + return None + + operator = operator_infos(state.train) + + if len(state.via) == 0: + embed = discord.Embed( + title=state.name, + description=f"Abfahrt von {state.station} um {format_timestamp(state.departure)}", + color=operator["color"] + ) + else: + embed = discord.Embed( + title=state.name, + description=f"Abfahrt **{format_timestamp(state.departure)}** von **{state.station}**", + color=operator["color"] + ) + embed.add_field(name="Über", value=format_via_list(state.via), inline=False) + + embed.set_author(name=operator["name"]) + embed.set_thumbnail(url=operator["logo"]) + + route_lines = [] + for stop in state.route: + stop_name = stop["name"] + if stop_name == state.station: + route_lines.append(f"• **{stop_name}**") + else: + route_lines.append(f"• {stop_name}") + + embed.add_field(name="Route", value="\n".join(route_lines)) + + slogans = operator.get("slogan") + footer_text = ( + f"{random.choice(slogans)} • Daten großzügig bereitgestellt von dbf.finalrewind.org" + if slogans else + "Daten großzügig bereitgestellt von dbf.finalrewind.org" + ) + embed.set_footer(text=footer_text, icon_url="https://dbf.finalrewind.org/static/icons/icon-96x96.png") + + return embed + +def build_error_embed(errormsg) -> discord.Embed: + embed = discord.Embed( + title="Ein Fehler ist aufgetreten!", + description=errormsg, + color=discord.Colour.red() + ) + + return embed \ No newline at end of file diff --git a/src/state.py b/src/state.py new file mode 100644 index 0000000..9781aa8 --- /dev/null +++ b/src/state.py @@ -0,0 +1,31 @@ +import discord +from config import config +from src.utils import random_connection + +name = None +train = None +route = None +departure = None +via = None +station = None + +async def rename_vc(bot: discord.Bot) -> bool: + global name, train, route, departure, via, station + + guild = bot.get_guild(int(config["server"])) + if guild is None: + print(f"Guild {config['server']} not found! Is the bot a member?") + return False + + channel = guild.get_channel(int(config["vc"])) + if not isinstance(channel, discord.VoiceChannel): + print(f"Unable to find voice-Channel {config['vc']} on the server") + return False + + train, destination, route, departure, via, station = random_connection() + name = f"{train} nach {destination}" + + print(f"Info:{name} from {station}") + + await channel.edit(name=f"{config['formatting']}{name}") + return True \ No newline at end of file diff --git a/src/utils.py b/src/utils.py index 016b79d..57f9fe0 100644 --- a/src/utils.py +++ b/src/utils.py @@ -1,6 +1,7 @@ import requests import random from config import config +from src.data.operators import OPERATORS def random_connection(): while True: @@ -23,4 +24,20 @@ def random_connection(): continue dep = random.choice(departures) - return [dep['train'], dep['destination'], station] + return [dep['train'], dep['destination'], dep['route'], dep['scheduledDeparture'], dep['via'], station] + + +def operator_infos(train): + if not train: + return OPERATORS["Fallback"] + + train_type = train.split()[0] + + return OPERATORS.get(train_type, OPERATORS["fallback"]) + +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] \ No newline at end of file