From 512f1ea12b85d9921745ba14d8819639b3ac0cd6 Mon Sep 17 00:00:00 2001 From: Lemon4ksan Date: Mon, 13 Jan 2025 17:46:37 +0300 Subject: [PATCH] feat: Add help command. --- MusicBot/cogs/general.py | 96 +++++++++++++++++++++++++++++++++---- MusicBot/cogs/utils/find.py | 2 - MusicBot/cogs/voice.py | 13 +++-- 3 files changed, 94 insertions(+), 17 deletions(-) diff --git a/MusicBot/cogs/general.py b/MusicBot/cogs/general.py index e9b3da8..84d814f 100644 --- a/MusicBot/cogs/general.py +++ b/MusicBot/cogs/general.py @@ -1,4 +1,4 @@ -from typing import cast +from typing import cast, TypeAlias import discord from discord.ext.commands import Cog @@ -22,8 +22,76 @@ class General(Cog): self.bot = bot self.db = BaseUsersDatabase() - @discord.slash_command(description="Войти в Yandex Music с помощью токена.") - @discord.option("token", type=discord.SlashCommandOptionType.string) + account = discord.SlashCommandGroup("account", "Команды, связанные с аккаунтом.") + + @discord.slash_command(description="Получить информацию о командах YandexMusic.") + @discord.option( + "command", + description="Название команды.", + type=discord.SlashCommandOptionType.string, + default='all' + ) + async def help(self, ctx: discord.ApplicationContext, command: str) -> None: + response_message = None + embed = discord.Embed( + color=0xfed42b + ) + embed.description = '__Использование__\n' + embed.set_author(name='Помощь') + + if command == 'all': + embed.description = ("Данный бот позволяет вам слушать музыку из вашего аккаунта Yandex Music.\n" + "Зарегистрируйте свой токен с помощью /login. Его можно получить [здесь](https://github.com/MarshalX/yandex-music-api/discussions/513).\n" + "Для получения помощи для конкретной команды, введите /help <команда>.\n\n" + "**Для доп. помощи, зайдите на [сервер любителей Яндекс Музыки](https://discord.gg/gkmFDaPMeC).**") + embed.title = 'Помощь' + + embed.add_field( + name='__Основные команды__', + value=""" + `find` + `help` + `account` + `queue` + `track` + `voice` + """ + ) + + embed.set_author(name='YandexMusic') + embed.set_footer(text='©️ Bananchiki') + elif command == 'find': + embed.description += ("Вывести информацию о треке (по умолчанию), альбоме, авторе или плейлисте. Позволяет добавить музыку в очередь. " + "В названии можно уточнить автора или версию. Возвращается лучшее совпадение.\n```/find <название> <тип>```") + elif command == 'help': + embed.description += ("Вывести список всех команд.\n```/help```\n" + "Получить информацию о конкретной команде.\n```/help <команда>```") + elif command == 'account': + embed.description += ("Ввести токен от Яндекс Музыки. Его можно получить [здесь](https://github.com/MarshalX/yandex-music-api/discussions/513).\n" + "```/account login ```\n" + "Удалить токен из датабазы бота.\n```/account remove```") + elif command == 'queue': + embed.description += ("Получить очередь треков. По 25 элементов на страницу.\n```/queue get```\n" + "Очистить очередь треков и историю прослушивания. Требует согласия части слушателей.\n```/queue clear```\n" + "`Примечание`: Если вы один в голосовом канале или имеете роль администратора бота, голосование не требуется.") + elif command == 'track': + embed.description += ("`Примечание`: Следующие команды требуют согласия части слушателей. Если вы один в голосовом канале или имеете роль администратора бота, голосование не требуется.\n\n" + "Переключиться на следующий трек в очереди и добавить его в историю.\n```/track next```\n" + "Приостановить текущий трек.\n ```/track pause```\n" + "Возобновить текущий трек.\n ```/track resume```\n" + "Прервать проигрывание, удалить историю, очередь и текущий плеер.\n ```/track stop```") + elif command == 'voice': + embed.description += ("Присоединить бота в голосовой канал. Требует роли администратора.\n ```/voice join```\n" + "Заставить бота покинуть голосовой канал. Требует роли администратора.\n ```/voice leave```\n" + "Создать меню проигрывателя. Доступно только если вы единственный в голосовом канале.\n```/voice menu```") + else: + response_message = '❌ Неизвестная команда.' + embed = None + + await ctx.respond(response_message, embed=embed, ephemeral=True) + + @account.command(description="Ввести токен от Яндекс Музыки.") + @discord.option("token", type=discord.SlashCommandOptionType.string, description="Токен.") async def login(self, ctx: discord.ApplicationContext, token: str) -> None: try: client = await YMClient(token).init() @@ -35,23 +103,35 @@ class General(Cog): self.db.update(uid, {'ym_token': token}) await ctx.respond(f'Привет, {about['account']['first_name']}!', delete_after=15, ephemeral=True) + + @account.command(description="Удалить токен из датабазы бота.") + async def remove(self, ctx: discord.ApplicationContext) -> None: + self.db.update(ctx.user.id, {'ym_token': None}) + await ctx.respond(f'Токен был удалён.', delete_after=15, ephemeral=True) @discord.slash_command(description="Найти контент и отправить информацию о нём. Возвращается лучшее совпадение.") @discord.option( "name", - description="Название контента для поиска", + description="Название контента для поиска (По умолчанию трек).", type=discord.SlashCommandOptionType.string ) @discord.option( "content_type", - description="Тип искомого контента (artist, album, track, playlist).", + description="Тип искомого контента (track, album, artist, playlist).", type=discord.SlashCommandOptionType.string, - default='track' + choices=['Artist', 'Album', 'Track', 'Playlist'], + default='Track' ) - async def find(self, ctx: discord.ApplicationContext, name: str, content_type: str = 'track') -> None: - if content_type not in ('artist', 'album', 'track', 'playlist'): + async def find( + self, + ctx: discord.ApplicationContext, + name: str, + content_type: str = 'Track' + ) -> None: + if content_type not in ['Artist', 'Album', 'Track', 'Playlist']: await ctx.respond("❌ Недопустимый тип.", delete_after=15, ephemeral=True) return + content_type = content_type.lower() token = self.db.get_ym_token(ctx.user.id) if not token: diff --git a/MusicBot/cogs/utils/find.py b/MusicBot/cogs/utils/find.py index 905c3b0..1873a79 100644 --- a/MusicBot/cogs/utils/find.py +++ b/MusicBot/cogs/utils/find.py @@ -36,7 +36,6 @@ class PlayTrackButton(Button, VoiceExtension): await interaction.respond(response_message, delete_after=15) - class PlayAlbumButton(Button, VoiceExtension): def __init__(self, album: Album, **kwargs): @@ -71,7 +70,6 @@ class PlayAlbumButton(Button, VoiceExtension): else: await interaction.respond(response_message, delete_after=15) - class PlayArtistButton(Button, VoiceExtension): def __init__(self, artist: Artist, **kwargs): Button.__init__(self, **kwargs) diff --git a/MusicBot/cogs/voice.py b/MusicBot/cogs/voice.py index 88437a1..53ec34f 100644 --- a/MusicBot/cogs/voice.py +++ b/MusicBot/cogs/voice.py @@ -5,8 +5,7 @@ from discord.ext.commands import Cog from yandex_music import Track, ClientAsync -from MusicBot.cogs.utils.find import process_track -from MusicBot.cogs.utils.voice import VoiceExtension +from MusicBot.cogs.utils.voice import VoiceExtension, generate_player_embed from MusicBot.cogs.utils.player import Player def setup(bot: discord.Bot): @@ -18,7 +17,7 @@ class Voice(Cog, VoiceExtension): queue = discord.SlashCommandGroup("queue", "Команды, связанные с очередью треков.") track = discord.SlashCommandGroup("track", "Команды, связанные с текущим треком.") - @voice.command(name="menu", description="Переключить меню проигрывателя. Доступно только если вы единственный в голосовом канале.") + @voice.command(name="menu", description="Создать меню проигрывателя. Доступно только если вы единственный в голосовом канале.") async def menu(self, ctx: discord.ApplicationContext) -> None: if not await self.voice_check(ctx): return @@ -27,7 +26,7 @@ class Voice(Cog, VoiceExtension): embed = None if guild['current_track']: - embed = await process_track(Track.de_json(guild['current_track'], client=ClientAsync())) # type: ignore + embed = await generate_player_embed(Track.de_json(guild['current_track'], client=ClientAsync())) # type: ignore vc = self.get_voice_client(ctx) if vc and vc.is_paused(): embed.set_footer(text='Приостановлено') @@ -64,7 +63,7 @@ class Voice(Cog, VoiceExtension): await vc.disconnect(force=True) await ctx.respond("Отключение успешно!", delete_after=15, ephemeral=True) - @queue.command(description="Очистить очередь и историю треков.") + @queue.command(description="Очистить очередь треков и историю прослушивания.") async def clear(self, ctx: discord.ApplicationContext) -> None: if not await self.voice_check(ctx): return @@ -106,16 +105,16 @@ class Voice(Cog, VoiceExtension): else: await ctx.respond("Воспроизведение не на паузе.", delete_after=15, ephemeral=True) - @track.command(description="Остановить текущий трек и очистите очередь и историю.") + @track.command(description="Прервать проигрывание, удалить историю, очередь и текущий плеер.") async def stop(self, ctx: discord.ApplicationContext) -> None: if await self.voice_check(ctx): self.db.clear_history(ctx.guild.id) self.stop_playing(ctx) current_player = self.db.get_guild(ctx.guild.id)['current_player'] if current_player is not None: + self.db.update(ctx.guild.id, {'current_player': None, 'repeat': False, 'shuffle': False}) message = await ctx.fetch_message(current_player) await message.delete() - self.db.update(ctx.guild.id, {'current_player': None, 'repeat': False, 'shuffle': False}) await ctx.respond("Воспроизведение остановлено.", delete_after=15, ephemeral=True) @track.command(description="Переключиться на следующую песню в очереди.")