mirror of
https://github.com/kaaninchen/Gleiswechsel.git
synced 2026-09-17 16:52:47 +00:00
rewrite audio announcements feature to be simpler to setup
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 73 KiB |
@@ -187,6 +187,8 @@ I highly recommend keeping `"OTHER"` blacklisted, if the API doesn't know what t
|
||||
- `timezone` is timezone in the IANA timezone format. You can [look it up here](https://www.addevent.com/c/documentation/tools/time-zone-lookup)
|
||||
|
||||
##### announcements
|
||||
|
||||
##### `text_announcements:`
|
||||
The bot can send a text announcement in the voice chat at the start/end of a trip.
|
||||
At the end of a trip, it would send this embed:
|
||||
|
||||
@@ -196,37 +198,10 @@ It will also send the `/info` embed at the start of a new connection with inform
|
||||
|
||||
To reduce spam, the bot will only send announcements if someone is in the voice chat
|
||||
|
||||
##### voice
|
||||
⚠️ Requires `announcements` to be set to enabled
|
||||
|
||||
The bot can join the voice chat, play an audio file, and leave at various points of your trip. You have to have [FFmpeg](https://www.ffmpeg.org/) installed for this to work.
|
||||
|
||||
Place the audio file of your desired station in [src/data/announcements](src/data/announcements/). Then, define the stations name with the name of the audio file in either `end_stations` or `stops`. The path will be autocompleted to [src/data/announcements](src/data/announcements/). The station name has to be EXACT, if you're unsure then [get the name through the helper script](#stations)
|
||||
|
||||
`end_stations` is for audio files that should play at the end of your trip, and `stops` is for audio files that should play while the train is passing through your desired station. If you set the name of a station to `general`, then the bot will always play that file before the trip ends/a new stop has been reached.
|
||||
|
||||
I'm hoping that I didn't explain this too complicated. Here's an example to visualize this:
|
||||
|
||||

|
||||
|
||||
```json
|
||||
"announcements": {
|
||||
"enabled": true,
|
||||
"voice": [
|
||||
{
|
||||
"enabled": true,
|
||||
"end_stations": {
|
||||
"general": "general.aac",
|
||||
"Hannover Hbf": "hannover.aac"
|
||||
},
|
||||
"stops": {
|
||||
"Amsterdam, Noorderpark": "noorderpark.aac"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
```
|
||||
##### `voice_announcements:`
|
||||
The bot can join the voice chat, play an audio file, and disconnect from the voice chat, at various points of your trip. You have to have [FFmpeg](https://www.ffmpeg.org/) installed for this to work.
|
||||
|
||||
Place the audio file of your desired station in [src/data/announcements](src/data/announcements/) with the EXACT name of the station. The bot will automatically check if an audio file with the stations name exists, and if it does, play it.
|
||||
#### http
|
||||
|
||||
- `"user_agent"`: The user agent of the bot for the API. If you don't know what that is, then you shouldn't have to change that. Even if you do, you still probably don't have to
|
||||
|
||||
+2
-11
@@ -24,17 +24,8 @@
|
||||
"timezone": "Europe/Berlin"
|
||||
},
|
||||
"announcements": {
|
||||
"enabled": true,
|
||||
"voice": [
|
||||
{
|
||||
"enabled": false,
|
||||
"end_stations": {
|
||||
"general": "general.aac",
|
||||
},
|
||||
"stops": {
|
||||
}
|
||||
}
|
||||
]
|
||||
"text_announcements": true,
|
||||
"voice_announcements": false
|
||||
},
|
||||
"http": {
|
||||
"user_agent": "Gleiswechsel-Discord-Bot"
|
||||
|
||||
@@ -243,7 +243,7 @@ def get_trip_details(random_connection: dict | None) -> dict | None:
|
||||
arrival_dt = parse_iso(end_time)
|
||||
departure_dt = parse_iso(start_time)
|
||||
|
||||
train_name = get_train_name(display_name, mode)
|
||||
train_name = get_train_name(display_name, mode) # used by lang
|
||||
if train_from == from_station:
|
||||
long_name = long_name_lang.train_from()
|
||||
else:
|
||||
|
||||
+3
-12
@@ -21,16 +21,10 @@ class ConnectionsConfig:
|
||||
max_wait_time: Optional[int] = None
|
||||
max_duration: Optional[int] = None
|
||||
|
||||
@dataclass
|
||||
class VoiceAnnouncementConfig:
|
||||
enabled: bool
|
||||
end_stations: dict[str, str]
|
||||
stops: dict[str, str]
|
||||
|
||||
@dataclass
|
||||
class AnnouncementConfig:
|
||||
enabled: bool
|
||||
voice: list[VoiceAnnouncementConfig]
|
||||
text_announcements: bool
|
||||
voice_announcements: bool
|
||||
|
||||
@dataclass
|
||||
class HttpConfig:
|
||||
@@ -50,10 +44,7 @@ def _load_config() -> Config:
|
||||
return Config(
|
||||
discord=DiscordConfig(**raw["discord"]),
|
||||
connections=ConnectionsConfig(**raw["connections"]),
|
||||
announcements=AnnouncementConfig(
|
||||
enabled=raw["announcements"]["enabled"],
|
||||
voice=[VoiceAnnouncementConfig(**v) for v in raw["announcements"]["voice"]],
|
||||
),
|
||||
announcements=AnnouncementConfig(**raw["announcements"]),
|
||||
http=HttpConfig(**raw["http"]),
|
||||
)
|
||||
|
||||
|
||||
+10
-16
@@ -39,30 +39,23 @@ async def rename_vc(bot: discord.Bot, voice_channel, from_scheduler: bool = Fals
|
||||
formatting = channel_formatting(mode)
|
||||
await voice_channel.edit(name=f"{formatting}{long_name}")
|
||||
await voice_channel.set_status(None)
|
||||
start_next_stop_updates(bot, voice_channel)
|
||||
|
||||
start_next_stop_updates(voice_channel)
|
||||
|
||||
logger(f"Updated channel name!")
|
||||
|
||||
await announcer("transfer", voice_channel)
|
||||
|
||||
|
||||
_scheduled_task = asyncio.create_task(_schedule_next_transfer(bot, trip["arrival_dt"], voice_channel, trip["to"]))
|
||||
|
||||
async def announcer(announcement: str, voice_channel: discord.VoiceChannel, destination = None):
|
||||
from src.dc.embeds import build_info_embed, build_announcement_embed
|
||||
announcements_enabled = config.announcements.enabled
|
||||
voice_announcement_enabled = config.announcements.voice[0].enabled
|
||||
announcements_enabled = config.announcements.text_announcements
|
||||
|
||||
if announcements_enabled:
|
||||
if len(voice_channel.members) > 0:
|
||||
match announcement:
|
||||
case "end_of_connection":
|
||||
if voice_announcement_enabled:
|
||||
announcement_status = await voice_announcer(destination, voice_channel, "end_stations")
|
||||
if announcement_status:
|
||||
return
|
||||
embed = build_announcement_embed(lang.embeds.announcement.end_of_connection.message())
|
||||
embed = build_announcement_embed(lang.embeds.announcement.end_of_connection.message())
|
||||
case "transfer":
|
||||
embed = build_info_embed()
|
||||
case _:
|
||||
@@ -72,8 +65,8 @@ async def announcer(announcement: str, voice_channel: discord.VoiceChannel, dest
|
||||
if embed:
|
||||
await voice_channel.send(embed=embed)
|
||||
|
||||
async def voice_announcer(destination: str, voice_channel: discord.VoiceChannel, type_announcement: str) -> bool:
|
||||
sound_path = get_sound_path(destination=destination, type_announcement=type_announcement)
|
||||
async def voice_announcer(station: str, voice_channel: discord.VoiceChannel) -> bool:
|
||||
sound_path = get_sound_path(station=station)
|
||||
if sound_path is None:
|
||||
return False
|
||||
|
||||
@@ -121,7 +114,7 @@ async def _schedule_next_transfer(bot: discord.Bot, arrival_dt: datetime, voice_
|
||||
logger("Train arrived, searching for a new connection....")
|
||||
await rename_vc(bot, voice_channel, from_scheduler=True)
|
||||
|
||||
async def _update_next_loop(bot: discord.Bot, voice_channel: discord.VoiceChannel):
|
||||
async def _update_next_loop(voice_channel: discord.VoiceChannel):
|
||||
global trip
|
||||
try:
|
||||
if trip is None:
|
||||
@@ -145,7 +138,8 @@ async def _update_next_loop(bot: discord.Bot, voice_channel: discord.VoiceChanne
|
||||
status_text = f"{lang.embeds.info.next_stop()}: {next_stop_str}"
|
||||
await voice_channel.set_status(status_text, reason="Next stop status")
|
||||
|
||||
await voice_announcer(next_stop_str, voice_channel, type_announcement="stops")
|
||||
if config.announcements.voice_announcements:
|
||||
await voice_announcer(next_stop_str, voice_channel)
|
||||
|
||||
wait_seconds = (next_stop["arrival"] - datetime.now(LOCAL_TZ)).total_seconds()
|
||||
if wait_seconds > 0:
|
||||
@@ -154,10 +148,10 @@ async def _update_next_loop(bot: discord.Bot, voice_channel: discord.VoiceChanne
|
||||
except asyncio.CancelledError:
|
||||
raise
|
||||
|
||||
def start_next_stop_updates(bot: discord.bot, voice_channel: discord.VoiceChannel):
|
||||
def start_next_stop_updates(voice_channel: discord.VoiceChannel):
|
||||
global _next_stop_task
|
||||
|
||||
if _next_stop_task is not None and not _next_stop_task.done():
|
||||
_next_stop_task.cancel()
|
||||
|
||||
_next_stop_task = asyncio.create_task(_update_next_loop(bot, voice_channel))
|
||||
_next_stop_task = asyncio.create_task(_update_next_loop(voice_channel))
|
||||
+7
-24
@@ -123,31 +123,14 @@ def get_operator_metadata(agency: str, route_color: str, mode: str) -> dict:
|
||||
"slogans": slogans
|
||||
}
|
||||
|
||||
def get_sound_path(destination, type_announcement: str) -> str | None:
|
||||
if type_announcement == "end_stations":
|
||||
voice_stations = config.announcements.voice[0].end_stations
|
||||
elif type_announcement == "stops":
|
||||
voice_stations = config.announcements.voice[0].stops
|
||||
def get_sound_path(station: str) -> str | None:
|
||||
announcement_dir = Path("src/data/announcements")
|
||||
|
||||
if destination in voice_stations:
|
||||
announcement_for = destination
|
||||
else:
|
||||
general_sound_enabled = voice_stations.get("general", "")
|
||||
if not general_sound_enabled:
|
||||
return None
|
||||
announcement_for = "general"
|
||||
|
||||
if voice_stations.values() == list:
|
||||
sound_file = random.choice(voice_stations.get(announcement_for))
|
||||
else:
|
||||
sound_file = voice_stations.get(announcement_for)
|
||||
|
||||
sound_path = f"src/data/announcements/{sound_file}"
|
||||
if Path(sound_path).is_file() is False:
|
||||
logger(f"Couldn't find {sound_path}", "error")
|
||||
return None
|
||||
|
||||
return sound_path
|
||||
for file in announcement_dir.iterdir():
|
||||
if file.is_file():
|
||||
if station.lower() in file.stem.lower():
|
||||
sound_file = file.resolve()
|
||||
return sound_file
|
||||
|
||||
def get_next_station(stops: dict, train_from: str) -> dict | None:
|
||||
now = datetime.now(LOCAL_TZ)
|
||||
|
||||
Reference in New Issue
Block a user