- GuildMusicState zbiera stan jednego serwera w jedną strukturę. Dotąd było to dziewięć równoległych słowników indeksowanych guild_id (queues, currents, volumes, loop_currents, loop_playlists, last_channels, history, queue_indices, jump_flag), co wymagało pamiętania, że przy każdej zmianie trzeba ruszyć kilka z nich naraz. - LoopMode zastępuje parę booleanów loop_current/loop_playlist, których kombinacja "oba włączone" nie miała sensu, a mimo to była osiągalna. Wartości enuma (off/playlist/single) odpowiadają kontraktowi API panelu. - TrackEmbedFactory zbiera budowanie osadzeń Discorda, powielone dotąd w enqueue_track i play_next. - NotificationChannelResolver opisuje kolejność szukania kanału logów: zapamiętany -> z konfiguracji -> pierwszy zapisywalny na serwerze. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
44 lines
1.7 KiB
Python
44 lines
1.7 KiB
Python
from __future__ import annotations
|
|
|
|
import discord
|
|
|
|
from zyrarbot.audio.ytdl_source import YTDLSource
|
|
|
|
AUTHOR_ICON = "https://cdn-icons-png.flaticon.com/512/3844/3844724.png"
|
|
|
|
|
|
class TrackEmbedFactory:
|
|
"""Buduje osadzenia Discorda opisujące utwór dodany do kolejki lub odtwarzany."""
|
|
|
|
def queued(self, track: YTDLSource, *, position: int, from_web: bool) -> discord.Embed:
|
|
embed = self._base(track, discord.Color.blue())
|
|
source = "Dodano do kolejki z panelu Web" if from_web else "Dodano do kolejki"
|
|
embed.set_author(name=source, icon_url=AUTHOR_ICON)
|
|
embed.set_footer(text=f"Pozycja w kolejce: {position}")
|
|
return embed
|
|
|
|
def now_playing(self, track: YTDLSource, *, position: int, total: int) -> discord.Embed:
|
|
embed = self._base(track, discord.Color.green(), prefix="▶️")
|
|
embed.set_footer(text=f"Pozycja w kolejce: {position} / {total}")
|
|
return embed
|
|
|
|
def _base(self, track: YTDLSource, color: discord.Color, *, prefix: str = "🎵") -> discord.Embed:
|
|
title = discord.utils.escape_markdown(track.title or "Nieznany tytuł")
|
|
url = track.display_url
|
|
icon = "📁" if track.is_local else prefix
|
|
description = (
|
|
f"[Kliknij tutaj, aby otworzyć link]({url})"
|
|
if track.has_web_link
|
|
else "Plik lokalny / brak linku"
|
|
)
|
|
embed = discord.Embed(
|
|
title=f"{icon} {title}",
|
|
url=url if track.has_web_link else None,
|
|
description=description,
|
|
color=color,
|
|
)
|
|
if track.duration:
|
|
minutes, seconds = divmod(int(track.duration), 60)
|
|
embed.add_field(name="Czas trwania", value=f"{minutes}:{seconds:02d}", inline=True)
|
|
return embed
|