mirror of
https://github.com/deadcxap/YandexMusicDiscordBot.git
synced 2026-01-09 23:51:45 +03:00
feat: Add explicit settings functionality.
This commit is contained in:
@@ -7,8 +7,9 @@ from discord.ext.commands import Cog
|
||||
import yandex_music
|
||||
import yandex_music.exceptions
|
||||
from yandex_music import ClientAsync as YMClient
|
||||
from yandex_music import Track, Album, Artist, Playlist
|
||||
|
||||
from MusicBot.database import BaseUsersDatabase
|
||||
from MusicBot.database import BaseUsersDatabase, BaseGuildsDatabase
|
||||
from MusicBot.cogs.utils.find import (
|
||||
process_album, process_track, process_artist, process_playlist,
|
||||
ListenAlbum, ListenTrack, ListenArtist, ListenPlaylist
|
||||
@@ -22,7 +23,8 @@ class General(Cog):
|
||||
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
self.db = BaseUsersDatabase()
|
||||
self.db = BaseGuildsDatabase()
|
||||
self.users_db = BaseUsersDatabase()
|
||||
|
||||
account = discord.SlashCommandGroup("account", "Команды, связанные с аккаунтом.")
|
||||
|
||||
@@ -84,7 +86,7 @@ class General(Cog):
|
||||
"или имеете разрешение управления каналом.\n```/queue clear```\n")
|
||||
elif command == 'settings':
|
||||
embed.description += ("Получить текущие настройки.\n```/settings show```\n"
|
||||
"Разрешить или запретить воспроизведение Explicit треков.\n```/settings explicit```\n"
|
||||
"Разрешить или запретить воспроизведение Explicit треков и альбомов. Если автор или плейлист содержат Explicit треки, убираются кнопки для доступа к ним.\n```/settings explicit```\n"
|
||||
"Разрешить или запретить создание меню проигрывателя, даже если в канале больше одного человека.\n```/settings menu```\n"
|
||||
"Разрешить или запретить голосование.\n```/settings vote <тип голосования>```\n"
|
||||
"`Примечание`: Только пользователи с разрешением управления каналом могут менять настройки.")
|
||||
@@ -115,17 +117,17 @@ class General(Cog):
|
||||
about = cast(yandex_music.Status, client.me).to_dict()
|
||||
uid = ctx.author.id
|
||||
|
||||
self.db.update(uid, {'ym_token': token})
|
||||
self.users_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})
|
||||
self.users_db.update(ctx.user.id, {'ym_token': None})
|
||||
await ctx.respond(f'Токен был удалён.', delete_after=15, ephemeral=True)
|
||||
|
||||
@account.command(description="Получить плейлист «Мне нравится»")
|
||||
async def likes(self, ctx: discord.ApplicationContext) -> None:
|
||||
token = self.db.get_ym_token(ctx.user.id)
|
||||
token = self.users_db.get_ym_token(ctx.user.id)
|
||||
if not token:
|
||||
await ctx.respond('❌ Необходимо указать свой токен доступа с помощью команды /login.', delete_after=15, ephemeral=True)
|
||||
return
|
||||
@@ -145,7 +147,7 @@ class General(Cog):
|
||||
|
||||
@account.command(description="Получить ваши плейлисты.")
|
||||
async def playlists(self, ctx: discord.ApplicationContext) -> None:
|
||||
token = self.db.get_ym_token(ctx.user.id)
|
||||
token = self.users_db.get_ym_token(ctx.user.id)
|
||||
if not token:
|
||||
await ctx.respond('❌ Необходимо указать свой токен доступа с помощью команды /login.', delete_after=15, ephemeral=True)
|
||||
return
|
||||
@@ -157,7 +159,7 @@ class General(Cog):
|
||||
playlists: list[tuple[str, int]] = [
|
||||
(playlist.title if playlist.title else 'Без названия', playlist.track_count if playlist.track_count else 0) for playlist in playlists_list
|
||||
]
|
||||
self.db.update(ctx.user.id, {'playlists': playlists, 'playlists_page': 0})
|
||||
self.users_db.update(ctx.user.id, {'playlists': playlists, 'playlists_page': 0})
|
||||
embed = generate_playlist_embed(0, playlists)
|
||||
await ctx.respond(embed=embed, view=MyPlalists(ctx), ephemeral=True)
|
||||
|
||||
@@ -184,55 +186,86 @@ class General(Cog):
|
||||
await ctx.respond("❌ Недопустимый тип.", delete_after=15, ephemeral=True)
|
||||
return
|
||||
|
||||
token = self.db.get_ym_token(ctx.user.id)
|
||||
guild = self.db.get_guild(ctx.guild_id)
|
||||
token = self.users_db.get_ym_token(ctx.user.id)
|
||||
if not token:
|
||||
await ctx.respond("❌ Необходимо указать свой токен доступа с помощью комманды /login.", delete_after=15, ephemeral=True)
|
||||
await ctx.respond("❌ Необходимо указать свой токен доступа с помощью команды /login.", delete_after=15, ephemeral=True)
|
||||
return
|
||||
|
||||
try:
|
||||
client = await YMClient(token).init()
|
||||
except yandex_music.exceptions.UnauthorizedError:
|
||||
await ctx.respond("❌ Недействительный токен. Если это не так, попробуйте ещё раз.", delete_after=15, ephemeral=True)
|
||||
return
|
||||
|
||||
|
||||
if content_type == 'User Playlist':
|
||||
if not client.me or not client.me.account or not client.me.account.uid:
|
||||
await ctx.respond("❌ Не удалось получить информацию о пользователе.", delete_after=15, ephemeral=True)
|
||||
return
|
||||
|
||||
playlists = await client.users_playlists_list(client.me.account.uid)
|
||||
result = None
|
||||
for playlist in playlists:
|
||||
if playlist.title == name:
|
||||
result = playlist
|
||||
break
|
||||
else:
|
||||
result = next((playlist for playlist in playlists if playlist.title == name), None)
|
||||
if not result:
|
||||
await ctx.respond("❌ Плейлист не найден.", delete_after=15, ephemeral=True)
|
||||
return
|
||||
|
||||
tracks = await result.fetch_tracks_async()
|
||||
if not tracks:
|
||||
await ctx.respond("❌ Плейлист пуст.", delete_after=15, ephemeral=True)
|
||||
return
|
||||
|
||||
for track_short in tracks:
|
||||
track = cast(Track, track_short.track)
|
||||
if (track.explicit or track.content_warning) and not guild['allow_explicit']:
|
||||
await ctx.respond("❌ Explicit контент запрещён на этом сервере.", delete_after=15, ephemeral=True)
|
||||
return
|
||||
|
||||
embed = await process_playlist(result)
|
||||
await ctx.respond(embed=embed, view=ListenPlaylist(result))
|
||||
else:
|
||||
result = await client.search(name, True, content_type.lower())
|
||||
result = await client.search(name, True)
|
||||
|
||||
if not result:
|
||||
await ctx.respond("❌ Что-то пошло не так. Повторите попытку позже", delete_after=15, ephemeral=True)
|
||||
return
|
||||
|
||||
if content_type == 'Album' and result.albums:
|
||||
album = result.albums.results[0]
|
||||
embed = await process_album(album)
|
||||
await ctx.respond(embed=embed, view=ListenAlbum(album))
|
||||
elif content_type == 'Track' and result.tracks:
|
||||
track = result.tracks.results[0]
|
||||
album_id = cast(int, track.albums[0].id)
|
||||
embed = await process_track(track)
|
||||
await ctx.respond(embed=embed, view=ListenTrack(track, album_id))
|
||||
elif content_type == 'Artist' and result.artists:
|
||||
artist = result.artists.results[0]
|
||||
embed = await process_artist(artist)
|
||||
await ctx.respond(embed=embed, view=ListenArtist(artist))
|
||||
elif content_type == 'Playlist' and result.playlists:
|
||||
playlist = result.playlists.results[0]
|
||||
embed = await process_playlist(playlist)
|
||||
await ctx.respond(embed=embed, view=ListenPlaylist(playlist))
|
||||
content_map = {
|
||||
'Album': (result.albums, process_album, ListenAlbum),
|
||||
'Track': (result.tracks, process_track, ListenTrack),
|
||||
'Artist': (result.artists, process_artist, ListenArtist),
|
||||
'Playlist': (result.playlists, process_playlist, ListenPlaylist)
|
||||
}
|
||||
|
||||
if content_type in content_map:
|
||||
content: Album | Track | Artist | Playlist = content_map[content_type][0].results[0]
|
||||
embed: discord.Embed = await content_map[content_type][1](content)
|
||||
view = content_map[content_type][2](content)
|
||||
|
||||
if isinstance(content, (Track, Album)) and (content.explicit or content.content_warning) and not guild['allow_explicit']:
|
||||
await ctx.respond("❌ Explicit контент запрещён на этом сервере.", delete_after=15, ephemeral=True)
|
||||
return
|
||||
elif isinstance(content, Artist):
|
||||
tracks = await content.get_tracks_async()
|
||||
if not tracks:
|
||||
await ctx.respond("❌ Треки от этого исполнителя не найдены.", delete_after=15, ephemeral=True)
|
||||
return
|
||||
for track in tracks:
|
||||
if (track.explicit or track.content_warning) and not guild['allow_explicit']:
|
||||
view = None
|
||||
embed.set_footer(text="Воспроизведение недоступно, так как у автора присутствуют Explicit треки")
|
||||
break
|
||||
elif isinstance(content, Playlist):
|
||||
tracks = await content.fetch_tracks_async()
|
||||
if not tracks:
|
||||
await ctx.respond("❌ Треки в этом плейлисте не найдены.", delete_after=15, ephemeral=True)
|
||||
return
|
||||
for track_short in content.tracks:
|
||||
track = cast(Track, track_short.track)
|
||||
if (track.explicit or track.content_warning) and not guild['allow_explicit']:
|
||||
view = None
|
||||
embed.set_footer(text="Воспроизведение недоступно, так как у автора присутствуют Explicit треки")
|
||||
break
|
||||
|
||||
await ctx.respond(embed=embed, view=view)
|
||||
else:
|
||||
await ctx.respond("❌ По запросу ничего не найдено.", delete_after=15, ephemeral=True)
|
||||
|
||||
@@ -138,11 +138,11 @@ class PlayPlaylistButton(Button, VoiceExtension):
|
||||
await interaction.respond(response_message, delete_after=15)
|
||||
|
||||
class ListenTrack(View):
|
||||
|
||||
def __init__(self, track: Track, album_id: int, *items: Item, timeout: float | None = None, disable_on_timeout: bool = False):
|
||||
|
||||
def __init__(self, track: Track, *items: Item, timeout: float | None = None, disable_on_timeout: bool = False):
|
||||
super().__init__(*items, timeout=timeout, disable_on_timeout=disable_on_timeout)
|
||||
link_app = f"yandexmusic://album/{album_id}/track/{track.id}"
|
||||
link_web = f"https://music.yandex.ru/album/{album_id}/track/{track.id}"
|
||||
link_app = f"yandexmusic://album/{track.albums[0].id}/track/{track.id}"
|
||||
link_web = f"https://music.yandex.ru/album/{track.albums[0].id}/track/{track.id}"
|
||||
self.button1: Button = Button(label="Слушать в приложении", style=ButtonStyle.gray, url=link_app)
|
||||
self.button2: Button = Button(label="Слушать в браузере", style=ButtonStyle.gray, url=link_web)
|
||||
self.button3: PlayTrackButton = PlayTrackButton(track, label="Слушать в голосовом канале", style=ButtonStyle.gray)
|
||||
@@ -152,7 +152,7 @@ class ListenTrack(View):
|
||||
self.add_item(self.button3)
|
||||
|
||||
class ListenAlbum(View):
|
||||
|
||||
|
||||
def __init__(self, album: Album, *items: Item, timeout: float | None = None, disable_on_timeout: bool = False):
|
||||
super().__init__(*items, timeout=timeout, disable_on_timeout=disable_on_timeout)
|
||||
link_app = f"yandexmusic://album/{album.id}"
|
||||
@@ -166,7 +166,7 @@ class ListenAlbum(View):
|
||||
self.add_item(self.button3)
|
||||
|
||||
class ListenArtist(View):
|
||||
|
||||
|
||||
def __init__(self, artist: Artist, *items: Item, timeout: float | None = None, disable_on_timeout: bool = False):
|
||||
super().__init__(*items, timeout=timeout, disable_on_timeout=disable_on_timeout)
|
||||
link_app = f"yandexmusic://artist/{artist.id}"
|
||||
@@ -180,6 +180,7 @@ class ListenArtist(View):
|
||||
self.add_item(self.button3)
|
||||
|
||||
class ListenPlaylist(View):
|
||||
|
||||
def __init__(self, playlist: Playlist, *items: Item, timeout: float | None = None, disable_on_timeout: bool = False):
|
||||
super().__init__(*items, timeout=timeout, disable_on_timeout=disable_on_timeout)
|
||||
link_app = f"yandexmusic://playlist/{playlist.playlist_uuid}"
|
||||
|
||||
@@ -458,4 +458,3 @@ class VoiceExtension:
|
||||
return None
|
||||
await client.users_likes_tracks_remove(ym_track.id, client.me.account.uid)
|
||||
return 'TRACK REMOVED'
|
||||
|
||||
@@ -151,7 +151,7 @@ class Voice(Cog, VoiceExtension):
|
||||
embed = None
|
||||
|
||||
if len(channel.members) > 2 and not guild['always_allow_menu']:
|
||||
await ctx.respond("Вы не единственный в голосовом канале.", ephemeral=True)
|
||||
await ctx.respond("❌ Вы не единственный в голосовом канале.", ephemeral=True)
|
||||
return
|
||||
|
||||
if guild['current_track']:
|
||||
@@ -159,8 +159,8 @@ class Voice(Cog, VoiceExtension):
|
||||
Track.de_json(
|
||||
guild['current_track'],
|
||||
client=ClientAsync() # type: ignore # Async client can be used here.
|
||||
)
|
||||
)
|
||||
)
|
||||
vc = await self.get_voice_client(ctx)
|
||||
if vc and vc.is_paused():
|
||||
embed.set_footer(text='Приостановлено')
|
||||
|
||||
Reference in New Issue
Block a user