Optimized code
This commit is contained in:
@@ -42,10 +42,12 @@ class Listeners(commands.Cog):
|
||||
await self.bot.wait_until_ready()
|
||||
for n in func.settings.nodes.values():
|
||||
try:
|
||||
await self.voicelink.create_node(bot=self.bot,
|
||||
spotify_client_id=func.tokens.spotify_client_id,
|
||||
spotify_client_secret=func.tokens.spotify_client_secret,
|
||||
**n)
|
||||
await self.voicelink.create_node(
|
||||
bot=self.bot,
|
||||
spotify_client_id=func.tokens.spotify_client_id,
|
||||
spotify_client_secret=func.tokens.spotify_client_secret,
|
||||
**n
|
||||
)
|
||||
except Exception as e:
|
||||
print(f'Node {n["identifier"]} is not able to connect! - Reason: {e}')
|
||||
|
||||
|
||||
@@ -28,9 +28,9 @@ from discord import app_commands
|
||||
from discord.ext import commands
|
||||
from function import (
|
||||
time as ctime,
|
||||
get_playlist,
|
||||
get_user,
|
||||
update_user,
|
||||
check_roles,
|
||||
update_playlist,
|
||||
get_lang,
|
||||
settings,
|
||||
get_aliases,
|
||||
@@ -46,13 +46,14 @@ def assign_playlistId(existed: list) -> str:
|
||||
return str(i)
|
||||
|
||||
async def check_playlist_perms(user_id: int, author_id: int, d_id: str) -> dict:
|
||||
playlist = await get_playlist(author_id, 'playlist', d_id)
|
||||
playlist = await get_user(author_id, 'playlist')
|
||||
playlist = playlist.get(d_id)
|
||||
if not playlist or user_id not in playlist['perms']['read']:
|
||||
return {}
|
||||
return playlist
|
||||
|
||||
async def check_playlist(ctx: commands.Context, name: str = None, full: bool = False, share: bool = True) -> dict:
|
||||
user = await get_playlist(ctx.author.id, 'playlist')
|
||||
user = await get_user(ctx.author.id, 'playlist')
|
||||
|
||||
await ctx.defer()
|
||||
if full:
|
||||
@@ -91,7 +92,7 @@ class Playlists(commands.Cog, name="playlist"):
|
||||
self.description = "This is the Vocard playlist system. You can save your favorites and use Vocard to play on any server."
|
||||
|
||||
async def playlist_autocomplete(self, interaction: discord.Interaction, current: str) -> list:
|
||||
playlists_raw: dict[str, dict] = await get_playlist(interaction.user.id, 'playlist')
|
||||
playlists_raw: dict[str, dict] = await get_user(interaction.user.id, 'playlist')
|
||||
playlists = [value['name'] for value in playlists_raw.values()] if playlists_raw else []
|
||||
if current:
|
||||
return [app_commands.Choice(name=p, value=p) for p in playlists if current in p]
|
||||
@@ -171,7 +172,7 @@ class Playlists(commands.Cog, name="playlist"):
|
||||
if share := playlist['type'] == 'share':
|
||||
playlist = await check_playlist_perms(ctx.author.id, playlist['user'], playlist['referId'])
|
||||
if not playlist:
|
||||
await update_playlist(ctx.author.id, {"$unset": {f"playlist.{data}": 1}})
|
||||
await update_user(ctx.author.id, {"$unset": {f"playlist.{data}": 1}})
|
||||
continue
|
||||
|
||||
if playlist['type'] == 'link':
|
||||
@@ -188,18 +189,26 @@ class Playlists(commands.Cog, name="playlist"):
|
||||
results.append({'emoji': ('🔒' if max_p < index else ('🤝' if share else '❤️')), 'id': data, 'time': ctime(time), 'name': user[data]['name'], 'tracks': playlist['tracks'], 'perms': playlist['perms'], 'owner': user[data].get('user', None), 'type': user[data]['type']})
|
||||
|
||||
except:
|
||||
results.append({'emoji': '⛔', 'id': data, 'time': '00:00', 'name': 'Error', 'tracks': [], 'type': 'error'})
|
||||
results.append({'emoji': '⛔', 'id': data, 'time': '--:--', 'name': 'Error', 'tracks': [], 'type': 'error'})
|
||||
|
||||
title = get_lang(ctx.guild.id, 'playlistViewHeaders')
|
||||
title = get_lang(ctx.guild.id, 'playlistViewHeaders').split(",")
|
||||
|
||||
embed = discord.Embed(
|
||||
title=get_lang(ctx.guild.id, 'playlistViewTitle').format(ctx.author.display_name),
|
||||
description=f'```{title[0]:>0} {title[1]:>4} {title[2]:>10} {title[3]:>10} {title[4]:>10}\n' + '\n'.join(f"""{info['emoji']} {info['id']:>4}. {f'''[{info["time"]}]''':>10} {info['name']:>10} {f'''{len(info['tracks'])}/{max_t}''':>10}""" for info in results) + '```',
|
||||
description='```prolog\n %4s %10s %10s %10s\n' % tuple(title),
|
||||
color=settings.embed_color
|
||||
)
|
||||
|
||||
embed.add_field(name=get_lang(ctx.guild.id, 'playlistMaxP'), value=f"➥ {len(user)}/{max_p}", inline=True)
|
||||
embed.add_field(name=get_lang(ctx.guild.id, 'playlistMaxT'), value=f"➥ {max_t}", inline=True)
|
||||
for index in range(max_p):
|
||||
try:
|
||||
info = results[index]
|
||||
track_info = (info['emoji'], info['id'], f"[{info['time']}]", info['name'], f"{len(info['tracks'])}/{max_t}")
|
||||
except IndexError:
|
||||
track_info = ("🎵", "-"*3, "[--:--]", "-"*6, f"-/{max_t}")
|
||||
|
||||
embed.description += '%0s %3s. %10s %10s %10s\n' % track_info
|
||||
|
||||
embed.description += "```"
|
||||
embed.set_footer(text=get_lang(ctx.guild.id, 'playlistFooter'))
|
||||
|
||||
view = PlaylistView(embed, results, ctx.author)
|
||||
@@ -231,7 +240,7 @@ class Playlists(commands.Cog, name="playlist"):
|
||||
return await ctx.send(get_lang(ctx.guild.id, 'playlistNotInvaildUrl'), ephemeral=True)
|
||||
|
||||
data = {'uri': link, 'perms': {'read': []}, 'name': name, 'type': 'link'} if link else {'tracks': [], 'perms': {'read': [], 'write': [], 'remove': []}, 'name': name, 'type': 'playlist'}
|
||||
await update_playlist(ctx.author.id, {"$set": {f"playlist.{assign_playlistId([data for data in user])}": data}})
|
||||
await update_user(ctx.author.id, {"$set": {f"playlist.{assign_playlistId([data for data in user])}": data}})
|
||||
await ctx.send(get_lang(ctx.guild.id, 'playlistCreated').format(name))
|
||||
|
||||
@playlist.command(name="delete", aliases=get_aliases("delete"))
|
||||
@@ -247,9 +256,9 @@ class Playlists(commands.Cog, name="playlist"):
|
||||
return await ctx.send(get_lang(ctx.guild.id, 'playlistDeleteError'), ephemeral=True)
|
||||
|
||||
if result['playlist']['type'] == 'share':
|
||||
await update_playlist(result['playlist']['user'], {"$pull": {f"playlist.{result['playlist']['referId']}.perms.read": ctx.author.id}})
|
||||
await update_user(result['playlist']['user'], {"$pull": {f"playlist.{result['playlist']['referId']}.perms.read": ctx.author.id}})
|
||||
|
||||
await update_playlist(ctx.author.id, {"$unset": {f"playlist.{result['id']}": 1}})
|
||||
await update_user(ctx.author.id, {"$unset": {f"playlist.{result['id']}": 1}})
|
||||
return await ctx.send(get_lang(ctx.guild.id, 'playlistRemove').format(result['playlist']['name']))
|
||||
|
||||
@playlist.command(name="share", aliases=get_aliases("share"))
|
||||
@@ -274,7 +283,7 @@ class Playlists(commands.Cog, name="playlist"):
|
||||
if member.id in result['playlist']['perms']['read']:
|
||||
return await ctx.send(get_lang(ctx.guild.id, 'playlistShare').format(member), ephemeral=True)
|
||||
|
||||
receiver = await get_playlist(member.id)
|
||||
receiver = await get_user(member.id)
|
||||
if not receiver:
|
||||
return await ctx.send(get_lang(ctx.guild.id, 'noPlaylistAcc').format(member))
|
||||
for mail in receiver['inbox']:
|
||||
@@ -283,7 +292,7 @@ class Playlists(commands.Cog, name="playlist"):
|
||||
if len(receiver['inbox']) >= 10:
|
||||
return await ctx.send(get_lang(ctx.guild.id, 'inboxFull').format(member), ephemeral=True)
|
||||
|
||||
await update_playlist(
|
||||
await update_user(
|
||||
member.id,
|
||||
{"$push": {"inbox": {
|
||||
'sender': ctx.author.id,
|
||||
@@ -320,14 +329,14 @@ class Playlists(commands.Cog, name="playlist"):
|
||||
if not found:
|
||||
return await ctx.send(get_lang(ctx.guild.id, 'playlistNotFound').format(name), ephemeral=True)
|
||||
|
||||
await update_playlist(ctx.author.id, {"$set": {f'playlist.{id}.name': newname}})
|
||||
await update_user(ctx.author.id, {"$set": {f'playlist.{id}.name': newname}})
|
||||
await ctx.send(get_lang(ctx.guild.id, 'playlistRenamed').format(name, newname))
|
||||
|
||||
@playlist.command(name="inbox", aliases=get_aliases("inbox"))
|
||||
@commands.dynamic_cooldown(cooldown_check, commands.BucketType.guild)
|
||||
async def inbox(self, ctx: commands.Context) -> None:
|
||||
"Show your playlist invitation."
|
||||
user = await get_playlist(ctx.author.id)
|
||||
user = await get_user(ctx.author.id)
|
||||
rank, max_p, max_t = check_roles()
|
||||
|
||||
if not user['inbox']:
|
||||
@@ -344,7 +353,7 @@ class Playlists(commands.Cog, name="playlist"):
|
||||
update_data, dId = {}, {dId for dId in user["playlist"]}
|
||||
for data in view.newplaylist[:(max_p - len(user['playlist']))]:
|
||||
addId = assign_playlistId(dId)
|
||||
await update_playlist(data['sender'], {"$push": {f"playlist.{data['referId']}.perms.read": ctx.author.id}})
|
||||
await update_user(data['sender'], {"$push": {f"playlist.{data['referId']}.perms.read": ctx.author.id}})
|
||||
update_data[f'playlist.{addId}'] = {
|
||||
'user': data['sender'], 'referId': data['referId'],
|
||||
'name': f"Share{data['time'].strftime('%M%S')}", 'type': 'share'
|
||||
@@ -353,7 +362,7 @@ class Playlists(commands.Cog, name="playlist"):
|
||||
dId.add(addId)
|
||||
|
||||
if update_data:
|
||||
await update_playlist(ctx.author.id, {"$set": update_data})
|
||||
await update_user(ctx.author.id, {"$set": update_data})
|
||||
|
||||
@playlist.command(name="add", aliases=get_aliases("add"))
|
||||
@commands.dynamic_cooldown(cooldown_check, commands.BucketType.guild)
|
||||
@@ -384,7 +393,7 @@ class Playlists(commands.Cog, name="playlist"):
|
||||
if results[0].is_stream:
|
||||
return await ctx.send(get_lang(ctx.guild.id, 'playlistStream'), ephemeral=True)
|
||||
|
||||
await update_playlist(ctx.author.id, {"$push": {f'playlist.{result["id"]}.tracks': results[0].track_id}})
|
||||
await update_user(ctx.author.id, {"$push": {f'playlist.{result["id"]}.tracks': results[0].track_id}})
|
||||
await ctx.send(get_lang(ctx.guild.id, 'playlistAdded').format(results[0].title, ctx.author, result['playlist']['name']))
|
||||
|
||||
@playlist.command(name="remove", aliases=get_aliases("remove"))
|
||||
@@ -404,7 +413,7 @@ class Playlists(commands.Cog, name="playlist"):
|
||||
if not 0 < position <= len(result['playlist']['tracks']):
|
||||
return await ctx.send(get_lang(ctx.guild.id, 'playlistPositionNotFound').format(position, name))
|
||||
|
||||
await update_playlist(ctx.author.id, {"$pull": {f'playlist.{result["id"]}.tracks': result['playlist']['tracks'][position - 1]}})
|
||||
await update_user(ctx.author.id, {"$pull": {f'playlist.{result["id"]}.tracks': result['playlist']['tracks'][position - 1]}})
|
||||
|
||||
track = voicelink.decode(result['playlist']['tracks'][position - 1])
|
||||
await ctx.send(get_lang(ctx.guild.id, 'playlistRemoved').format(track.get("title"), ctx.author, name))
|
||||
@@ -421,7 +430,7 @@ class Playlists(commands.Cog, name="playlist"):
|
||||
if result['playlist']['type'] in ['link', 'share']:
|
||||
return await ctx.send(get_lang(ctx.guild.id, 'playlistNotAllow'), ephemeral=True)
|
||||
|
||||
await update_playlist(ctx.author.id, {"$set": {f'playlist.{result["id"]}.tracks': []}})
|
||||
await update_user(ctx.author.id, {"$set": {f'playlist.{result["id"]}.tracks': []}})
|
||||
await ctx.send(get_lang(ctx.guild.id, 'playlistClear').format(name))
|
||||
|
||||
@playlist.command(name="export", aliases=get_aliases("export"))
|
||||
@@ -492,7 +501,7 @@ class Playlists(commands.Cog, name="playlist"):
|
||||
track_ids = track_ids.decode().split(",")
|
||||
|
||||
data = {'tracks': track_ids, 'perms': {'read': [], 'write': [], 'remove': []}, 'name': name, 'type': 'playlist'}
|
||||
await update_playlist(ctx.author.id, {"$set": {f"playlist.{assign_playlistId([data for data in user])}": data}})
|
||||
await update_user(ctx.author.id, {"$set": {f"playlist.{assign_playlistId([data for data in user])}": data}})
|
||||
await ctx.send(get_lang(ctx.guild.id, 'playlistCreated').format(name))
|
||||
|
||||
except:
|
||||
|
||||
@@ -111,7 +111,7 @@ class Task(commands.Cog):
|
||||
@tasks.loop(hours=12.0)
|
||||
async def cache_cleaner(self):
|
||||
func.SETTINGS_BUFFER.clear()
|
||||
func.PLAYLISTS_BUFFER.clear()
|
||||
func.USERS_BUFFER.clear()
|
||||
|
||||
errorFile = func.gen_report()
|
||||
if errorFile:
|
||||
|
||||
38
function.py
38
function.py
@@ -23,15 +23,15 @@ settings: Settings
|
||||
|
||||
MONGO_DB: AsyncIOMotorClient
|
||||
SETTINGS_DB: AsyncIOMotorCollection
|
||||
PLAYLISTS_DB: AsyncIOMotorCollection
|
||||
USERS_DB: AsyncIOMotorCollection
|
||||
|
||||
ERROR_LOGS: dict[int, dict[int, str]] = {} #Stores error that not a Voicelink Exception
|
||||
LANGS: dict[str, dict[str, str]] = {} #Stores all the languages in ./langs
|
||||
LOCAL_LANGS: dict[str, dict[str, str]] = {} #Stores all the localization languages in ./local_langs
|
||||
SETTINGS_BUFFER: dict[int, dict[str, Any]] = {} #Cache guild language
|
||||
LOCAL_LANGS: dict[str, dict[str, str]] = {} #Stores all the localization languages in ./local_langs
|
||||
PLAYLISTS_BUFFER: dict[str, dict] = {}
|
||||
USERS_BUFFER: dict[str, dict] = {}
|
||||
|
||||
PLAYLIST_BASE: dict[str, Any] = {
|
||||
USERS_BASE: dict[str, Any] = {
|
||||
'playlist': {
|
||||
'200': {
|
||||
'tracks':[],
|
||||
@@ -40,6 +40,7 @@ PLAYLIST_BASE: dict[str, Any] = {
|
||||
'type':'playlist'
|
||||
}
|
||||
},
|
||||
'history': [],
|
||||
'inbox':[]
|
||||
}
|
||||
|
||||
@@ -183,24 +184,21 @@ async def update_settings(guild_id: int, data: dict[str, dict[str, Any]]) -> boo
|
||||
settings = await get_settings(guild_id)
|
||||
return await update_db(SETTINGS_DB, settings, {"_id": guild_id}, data)
|
||||
|
||||
async def get_playlist(user_id: int, d_type: Optional[str] = None, d_id: Optional[str] = None, need_copy: bool = True) -> Dict[str, Any]:
|
||||
playlist = PLAYLISTS_BUFFER.get(user_id)
|
||||
if not playlist:
|
||||
playlist = await PLAYLISTS_DB.find_one({"_id": user_id})
|
||||
if not playlist:
|
||||
playlist = {"_id": user_id, **PLAYLIST_BASE}
|
||||
await PLAYLISTS_DB.insert_one(playlist)
|
||||
async def get_user(user_id: int, d_type: Optional[str] = None, need_copy: bool = True) -> Dict[str, Any]:
|
||||
user = USERS_BUFFER.get(user_id)
|
||||
if not user:
|
||||
user = await USERS_DB.find_one({"_id": user_id})
|
||||
if not user:
|
||||
user = {"_id": user_id, **USERS_BASE}
|
||||
await USERS_DB.insert_one(user)
|
||||
|
||||
PLAYLISTS_BUFFER[user_id] = playlist
|
||||
USERS_BUFFER[user_id] = user
|
||||
|
||||
if d_type:
|
||||
if d_id and d_type == "playlist":
|
||||
playlist = playlist[d_type].get(d_id)
|
||||
else:
|
||||
playlist = playlist.get(d_type)
|
||||
user = user.setdefault(d_type, copy.deepcopy(USERS_BASE.get(d_type)))
|
||||
|
||||
return copy.deepcopy(playlist) if need_copy else playlist
|
||||
return copy.deepcopy(user) if need_copy else user
|
||||
|
||||
async def update_playlist(user_id:int, data:dict) -> None:
|
||||
playlist = await get_playlist(user_id, need_copy=False)
|
||||
return await update_db(PLAYLISTS_DB, playlist, {"_id": user_id}, data)
|
||||
async def update_user(user_id:int, data:dict) -> bool:
|
||||
playlist = await get_user(user_id, need_copy=False)
|
||||
return await update_db(USERS_DB, playlist, {"_id": user_id}, data)
|
||||
@@ -45,9 +45,7 @@
|
||||
"FilterTagAlreadyInUse": "此聲音效果已在使用中!請使用 /cleareffect <Tag> 移除它。",
|
||||
|
||||
"playlistViewTitle": "📜 所有 {0} 的播放清單",
|
||||
"playlistViewHeaders": [" ", "ID:", "時間:", "名稱:", "曲目數:"],
|
||||
"playlistMaxP": "最大播放清單:",
|
||||
"playlistMaxT": "最大曲目數:",
|
||||
"playlistViewHeaders": "ID:,時間:,名稱:,曲目數:",
|
||||
"playlistFooter": "輸入 /playlist play [播放清單] 加入此播放清單至隊列中。",
|
||||
"playlistNotFound": "找不到播放清單 [`{0}`]。輸入 /playlist view 查看所有播放清單。",
|
||||
"playlistNotAccess": "抱歉!你無權訪問此播放清單!",
|
||||
|
||||
@@ -45,9 +45,7 @@
|
||||
"FilterTagAlreadyInUse": "Diese Soundeffekte sind bereits im Einsatz! Bitte verwenden Sie /cleareffect <Tag>, um sie zu entfernen.",
|
||||
|
||||
"playlistViewTitle": "📜 Alle Playlists von {0}",
|
||||
"playlistViewHeaders": [" ", "ID:", "Zeit:", "Name:", "Spuren:"],
|
||||
"playlistMaxP": "Maximale Wiedergabeliste:",
|
||||
"playlistMaxT": "Max. Spuren:",
|
||||
"playlistViewHeaders": "ID:,Zeit:,Name:,Spuren:",
|
||||
"playlistFooter": "Geben Sie /playlist play [playlist] ein, um die Playlist in die Warteschlange einzufügen.",
|
||||
"playlistNotFound": "Wiedergabeliste [`{0}`] nicht gefunden. Geben Sie /playlist view ein, um Ihre gesamte Wiedergabeliste anzuzeigen.",
|
||||
"playlistNotAccess": "Es tut uns leid! Du bist nicht berechtigt, auf diese Playlist zuzugreifen!",
|
||||
|
||||
@@ -45,9 +45,7 @@
|
||||
"FilterTagAlreadyInUse": "This sound effects has already in use! Please use /cleareffect <Tag> to remove it.",
|
||||
|
||||
"playlistViewTitle": "📜 All {0}'s Playlists",
|
||||
"playlistViewHeaders": [" ", "ID:", "Time:", "Name:", "Tracks:"],
|
||||
"playlistMaxP": "Max Playlist:",
|
||||
"playlistMaxT": "Max Tracks:",
|
||||
"playlistViewHeaders": "ID:,Time:,Name:,Tracks:",
|
||||
"playlistFooter": "Type /playlist play [playlist] to add the playlist the into queue.",
|
||||
"playlistNotFound": "Playlist [`{0}`] not found. Type /playlist view to view all your playlist.",
|
||||
"playlistNotAccess": "Sorry! You are not allowed to access this playlist!",
|
||||
|
||||
@@ -45,9 +45,7 @@
|
||||
"FilterTagAlreadyInUse": "¡Este efecto de sonido ya está en uso! Utilice /cleareffect <Tag> para eliminarlo.",
|
||||
|
||||
"playlistViewTitle": "📜 Todas las listas de reproducción de {0}",
|
||||
"playlistViewHeaders": [" ", "ID:", "Tiempo:", "Nombre:", "Pistas:"],
|
||||
"playlistMaxP": "Máximo de lista de reproducción:",
|
||||
"playlistMaxT": "Máximo de pistas:",
|
||||
"playlistViewHeaders": "ID:,Tiempo:,Nombre:,Pistas:",
|
||||
"playlistFooter": "Escriba /playlist play [playlist] para agregar la lista de reproducción a la cola.",
|
||||
"playlistNotFound": "Lista de reproducción [`{0}`] no encontrada. Escriba /playlist view para ver todas sus listas de reproducción.",
|
||||
"playlistNotAccess": "¡Lo siento! No está autorizado para acceder a esta lista de reproducción.",
|
||||
|
||||
@@ -45,9 +45,7 @@
|
||||
"FilterTagAlreadyInUse": "このサウンドエフェクトはすでに使用されています!削除するには/cleareffect <Tag>を使用してください。",
|
||||
|
||||
"playlistViewTitle": "📜 {0}のすべてのプレイリスト",
|
||||
"playlistViewHeaders": [" ", "ID:", "時間:", "名前:", "トラック:"],
|
||||
"playlistMaxP": "最大プレイリスト:",
|
||||
"playlistMaxT": "最大トラック:",
|
||||
"playlistViewHeaders": "ID:,時間:,名前:,トラック:",
|
||||
"playlistFooter": "プレイリストをキューに追加するには、/playlist play [playlist]を入力してください。",
|
||||
"playlistNotFound": "プレイリスト[{0}]が見つかりません。すべてのプレイリストを表示するには、/playlist viewを入力してください。",
|
||||
"playlistNotAccess": "申し訳ありません!このプレイリストにアクセスすることはできません!",
|
||||
|
||||
@@ -45,9 +45,7 @@
|
||||
"FilterTagAlreadyInUse": "이 필터는 이미 사용 중입니다! 삭제하려면 /cleareffect <Tag>를 사용하십시오.",
|
||||
|
||||
"playlistViewTitle": "📜 {0}의 모든 재생 목록",
|
||||
"playlistViewHeaders": [" ", "ID:", "시간:", "이름:", "트랙:"],
|
||||
"playlistMaxP": "최대 재생 목록:",
|
||||
"playlistMaxT": "최대 트랙:",
|
||||
"playlistViewHeaders": "ID:,시간:,이름:,트랙:",
|
||||
"playlistFooter": "/playlist play [재생 목록]을 입력하여 재생 목록을 대기열에 추가하세요.",
|
||||
"playlistNotFound": "재생 목록 [{0}]을(를) 찾을 수 없습니다. 모든 재생 목록을 보려면 /playlist view를 입력하세요.",
|
||||
"playlistNotAccess": "죄송합니다! 이 재생 목록에 액세스할 수 없습니다!",
|
||||
|
||||
@@ -45,9 +45,7 @@
|
||||
"FilterTagAlreadyInUse": "Этот звуковой эффект уже используется! Пожалуйста, используйте /cleareffect <Тег>, чтобы удалить его.",
|
||||
|
||||
"playlistViewTitle": "📜 Все плейлисты пользователя {0}",
|
||||
"playlistViewHeaders": [" ", "ID:", "Время:", "Название:", "Треки:"],
|
||||
"playlistMaxP": "Максимальное количество плейлистов:",
|
||||
"playlistMaxT": "Максимальное количество треков:",
|
||||
"playlistViewHeaders": "ID:,Время:,Название:,Треки:",
|
||||
"playlistFooter": "Введите /playlist play [плейлист], чтобы добавить плейлист в очередь.",
|
||||
"playlistNotFound": "Плейлист [`{0}`] не найден. Введите /playlist view, чтобы посмотреть все ваши плейлисты.",
|
||||
"playlistNotAccess": "Извините! У вас нет доступа к этому плейлисту!",
|
||||
|
||||
@@ -45,9 +45,7 @@
|
||||
"FilterTagAlreadyInUse": "Цей звуковий ефект уже використовується! Будь ласка, використовуйте /cleareffect <Тег>, щоб видалити його.",
|
||||
|
||||
"playlistViewTitle": "📜 Усі плейлисти користувача {0}",
|
||||
"playlistViewHeaders": [" ", "ID:", "Час:", "Назва:", "Треки:"],
|
||||
"playlistMaxP": "Максимальна кількість плейлистів:",
|
||||
"playlistMaxT": "Максимальное количество треков:",
|
||||
"playlistViewHeaders": "ID:,Час:,Назва:,Треки:",
|
||||
"playlistFooter": "Введите /playlist play [плейлист], чтобы добавить плейлист в очередь.",
|
||||
"playlistNotFound": "Плейлист [`{0}`] не знайдено. Введіть /playlist view, щоб подивитися всі ваші плейлисти.",
|
||||
"playlistNotAccess": "Вибачте! У вас немає доступу до цього плейлиста!",
|
||||
|
||||
3
main.py
3
main.py
@@ -61,7 +61,7 @@ class Vocard(commands.Bot):
|
||||
raise Exception("Not able to connect MongoDB! Reason:", e)
|
||||
|
||||
func.SETTINGS_DB = func.MONGO_DB[db_name]["Settings"]
|
||||
func.PLAYLISTS_DB = func.MONGO_DB[db_name]["Playlist"]
|
||||
func.USERS_DB = func.MONGO_DB[db_name]["Users"]
|
||||
|
||||
async def setup_hook(self) -> None:
|
||||
func.langs_setup()
|
||||
@@ -150,6 +150,7 @@ func.settings = Settings(func.open_json("settings.json"))
|
||||
# Setup the bot object
|
||||
intents = discord.Intents.default()
|
||||
intents.message_content = True if func.settings.bot_prefix else False
|
||||
intents.members = True
|
||||
member_cache = discord.MemberCacheFlags(
|
||||
voice=True,
|
||||
joined=False
|
||||
|
||||
@@ -2,7 +2,7 @@ import requests, zipfile, os, shutil, argparse
|
||||
from io import BytesIO
|
||||
|
||||
ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
__version__ = "v2.6.8b2"
|
||||
__version__ = "v2.6.8b3"
|
||||
|
||||
GITHUB_API_URL = "https://api.github.com/repos/ChocoMeow/Vocard/releases/latest"
|
||||
VOCARD_URL = "https://github.com/ChocoMeow/Vocard/archive/"
|
||||
|
||||
@@ -28,8 +28,8 @@ import function as func
|
||||
from discord.ext import commands
|
||||
from . import ButtonOnCooldown
|
||||
from function import (
|
||||
get_playlist,
|
||||
update_playlist,
|
||||
get_user,
|
||||
update_user,
|
||||
check_roles
|
||||
)
|
||||
|
||||
@@ -198,14 +198,14 @@ class Add(ControlButton):
|
||||
return await self.send(interaction, self.player.get_msg("noTrackPlaying"))
|
||||
if track.is_stream:
|
||||
return await self.send(interaction, self.player.get_msg("playlistAddError"))
|
||||
user = await get_playlist(interaction.user.id, 'playlist')
|
||||
user = await get_user(interaction.user.id, 'playlist')
|
||||
rank, max_p, max_t = check_roles()
|
||||
if len(user['200']['tracks']) >= max_t:
|
||||
return await self.send(interaction, self.player.get_msg("playlistlimited").format(max_t), ephemeral=True)
|
||||
|
||||
if track.track_id in user['200']['tracks']:
|
||||
return await self.send(interaction, self.player.get_msg("playlistrepeated"), ephemeral=True)
|
||||
respond = await update_playlist(interaction.user.id, {'playlist.200.tracks': track.track_id}, mode="push")
|
||||
respond = await update_user(interaction.user.id, {"$push": {'playlist.200.tracks': track.track_id}})
|
||||
if respond:
|
||||
await self.send(interaction, self.player.get_msg("playlistAdded").format(track.title, interaction.user.mention, user['200']['name']), ephemeral=True)
|
||||
else:
|
||||
|
||||
@@ -37,6 +37,7 @@ class Select_playlist(discord.ui.Select):
|
||||
|
||||
super().__init__(
|
||||
placeholder="Select a playlist to view ..",
|
||||
custom_id="selector",
|
||||
options=[discord.SelectOption(emoji='🌎', label='All Playlist')] +
|
||||
[
|
||||
discord.SelectOption(emoji=playlist['emoji'], label=f'{index}. {playlist["name"]}', description=f"{playlist['time']} · {playlist['type']}")
|
||||
@@ -47,12 +48,14 @@ class Select_playlist(discord.ui.Select):
|
||||
async def callback(self, interaction: discord.Interaction) -> None:
|
||||
if self.values[0] == 'All Playlist':
|
||||
self.view.current = None
|
||||
return await interaction.response.edit_message(embed=self.view.viewEmbed)
|
||||
self.view.toggle_btn(True)
|
||||
return await interaction.response.edit_message(embed=self.view.viewEmbed, view=self.view)
|
||||
|
||||
self.view.current = self.view.results[int(self.values[0].split(". ")[0]) - 1]
|
||||
self.view.page = ceil(len(self.view.current['tracks']) / 7)
|
||||
self.view.current_page = 1
|
||||
await interaction.response.edit_message(embed=self.view.build_embed())
|
||||
self.view.toggle_btn(False)
|
||||
await interaction.response.edit_message(embed=self.view.build_embed(), view=self.view)
|
||||
|
||||
class PlaylistView(discord.ui.View):
|
||||
def __init__(
|
||||
@@ -80,6 +83,11 @@ class PlaylistView(discord.ui.View):
|
||||
async def on_error(self, error, item, interaction) -> None:
|
||||
return
|
||||
|
||||
def toggle_btn(self, action: bool) -> None:
|
||||
for child in self.children:
|
||||
if child.custom_id not in ("delete", "selector"):
|
||||
child.disabled = action
|
||||
|
||||
def build_embed(self) -> discord.Embed:
|
||||
offset: int = self.current_page * 7
|
||||
tracks: list[Track] = self.current['tracks'][(offset-7):offset]
|
||||
@@ -117,7 +125,7 @@ class PlaylistView(discord.ui.View):
|
||||
except:
|
||||
pass
|
||||
|
||||
@discord.ui.button(label='<<', style=discord.ButtonStyle.grey)
|
||||
@discord.ui.button(label='<<', style=discord.ButtonStyle.grey, disabled=True)
|
||||
async def fast_back_button(self, interaction: discord.Interaction, button: discord.ui.Button) -> None:
|
||||
if not self.current:
|
||||
return
|
||||
@@ -126,7 +134,7 @@ class PlaylistView(discord.ui.View):
|
||||
return await interaction.response.edit_message(embed=self.build_embed())
|
||||
await interaction.response.defer()
|
||||
|
||||
@discord.ui.button(label='Back', style=discord.ButtonStyle.blurple)
|
||||
@discord.ui.button(label='Back', style=discord.ButtonStyle.blurple, disabled=True)
|
||||
async def back_button(self, interaction: discord.Interaction, button: discord.ui.Button) -> None:
|
||||
if not self.current:
|
||||
return
|
||||
@@ -135,7 +143,7 @@ class PlaylistView(discord.ui.View):
|
||||
return await interaction.response.edit_message(embed=self.build_embed())
|
||||
await interaction.response.defer()
|
||||
|
||||
@discord.ui.button(label='Next', style=discord.ButtonStyle.blurple)
|
||||
@discord.ui.button(label='Next', style=discord.ButtonStyle.blurple, disabled=True)
|
||||
async def next_button(self, interaction: discord.Interaction, button: discord.ui.Button) -> None:
|
||||
if not self.current:
|
||||
return
|
||||
@@ -144,7 +152,7 @@ class PlaylistView(discord.ui.View):
|
||||
return await interaction.response.edit_message(embed=self.build_embed())
|
||||
await interaction.response.defer()
|
||||
|
||||
@discord.ui.button(label='>>', style=discord.ButtonStyle.grey)
|
||||
@discord.ui.button(label='>>', style=discord.ButtonStyle.grey, disabled=True)
|
||||
async def fast_next_button(self, interaction: discord.Interaction, button: discord.ui.Button) -> None:
|
||||
if not self.current:
|
||||
return
|
||||
@@ -153,7 +161,7 @@ class PlaylistView(discord.ui.View):
|
||||
return await interaction.response.edit_message(embed=self.build_embed())
|
||||
await interaction.response.defer()
|
||||
|
||||
@discord.ui.button(emoji='🗑️', style=discord.ButtonStyle.red)
|
||||
@discord.ui.button(emoji='🗑️', custom_id="delete", style=discord.ButtonStyle.red)
|
||||
async def stop_button(self, interaction: discord.Interaction, button: discord.ui.Button) -> None:
|
||||
await self.response.delete()
|
||||
self.stop()
|
||||
@@ -31,11 +31,11 @@ class LoopType(Enum):
|
||||
LoopType.queue: 3
|
||||
|
||||
"""
|
||||
|
||||
|
||||
off = auto()
|
||||
track = auto()
|
||||
queue = auto()
|
||||
|
||||
|
||||
class SearchType(Enum):
|
||||
"""The enum for the different search types for Voicelink.
|
||||
This feature is exclusively for the Spotify search feature of Voicelink.
|
||||
@@ -50,6 +50,7 @@ class SearchType(Enum):
|
||||
SearchType.scsearch searches using SoundCloud,
|
||||
which is an alternative to YouTube or YouTube Music.
|
||||
"""
|
||||
|
||||
ytsearch = "ytsearch"
|
||||
ytmsearch = "ytmsearch"
|
||||
scsearch = "scsearch"
|
||||
|
||||
@@ -25,6 +25,7 @@ import collections
|
||||
from .exceptions import FilterInvalidArgument, FilterTagAlreadyInUse, FilterTagInvalid
|
||||
|
||||
from typing import (
|
||||
Dict,
|
||||
List
|
||||
)
|
||||
|
||||
@@ -36,7 +37,7 @@ class Filter:
|
||||
these filters will not work.
|
||||
"""
|
||||
def __init__(self):
|
||||
self.payload = None
|
||||
self.payload: Dict[str, List] = None
|
||||
self.tag: str = None
|
||||
|
||||
class Filters:
|
||||
@@ -68,7 +69,7 @@ class Filters:
|
||||
payload.update(filter.payload)
|
||||
return payload
|
||||
|
||||
def get_filters(self) -> list:
|
||||
def get_filters(self) -> List[Filter]:
|
||||
return self._filters
|
||||
|
||||
class Equalizer(Filter):
|
||||
@@ -185,9 +186,13 @@ class Timescale(Filter):
|
||||
self.rate = rate
|
||||
self.tag = tag
|
||||
|
||||
self.payload = {"timescale": {"speed": self.speed,
|
||||
"pitch": self.pitch,
|
||||
"rate": self.rate}}
|
||||
self.payload = {
|
||||
"timescale": {
|
||||
"speed": self.speed,
|
||||
"pitch": self.pitch,
|
||||
"rate": self.rate
|
||||
}
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def vaporwave(cls):
|
||||
@@ -235,10 +240,14 @@ class Karaoke(Filter):
|
||||
self.filter_width = filter_width
|
||||
self.tag = tag
|
||||
|
||||
self.payload = {"karaoke": {"level": self.level,
|
||||
"monoLevel": self.mono_level,
|
||||
"filterBand": self.filter_band,
|
||||
"filterWidth": self.filter_width}}
|
||||
self.payload = {
|
||||
"karaoke": {
|
||||
"level": self.level,
|
||||
"monoLevel": self.mono_level,
|
||||
"filterBand": self.filter_band,
|
||||
"filterWidth": self.filter_width
|
||||
}
|
||||
}
|
||||
|
||||
def __repr__(self):
|
||||
return (
|
||||
@@ -262,18 +271,20 @@ class Tremolo(Filter):
|
||||
super().__init__()
|
||||
|
||||
if frequency < 0:
|
||||
raise FilterInvalidArgument(
|
||||
"Tremolo frequency must be more than 0.")
|
||||
raise FilterInvalidArgument("Tremolo frequency must be more than 0.")
|
||||
if depth < 0 or depth > 1:
|
||||
raise FilterInvalidArgument(
|
||||
"Tremolo depth must be between 0 and 1.")
|
||||
raise FilterInvalidArgument("Tremolo depth must be between 0 and 1.")
|
||||
|
||||
self.frequency = frequency
|
||||
self.depth = depth
|
||||
self.tag = tag
|
||||
|
||||
self.payload = {"tremolo": {"frequency": self.frequency,
|
||||
"depth": self.depth}}
|
||||
self.payload = {
|
||||
"tremolo": {
|
||||
"frequency": self.frequency,
|
||||
"depth": self.depth
|
||||
}
|
||||
}
|
||||
|
||||
def __repr__(self):
|
||||
return f"<Voicelink.TremoloFilter tag={self.tag} frequency={self.frequency} depth={self.depth}>"
|
||||
@@ -294,18 +305,20 @@ class Vibrato(Filter):
|
||||
|
||||
super().__init__()
|
||||
if frequency < 0 or frequency > 14:
|
||||
raise FilterInvalidArgument(
|
||||
"Vibrato frequency must be between 0 and 14.")
|
||||
raise FilterInvalidArgument("Vibrato frequency must be between 0 and 14.")
|
||||
if depth < 0 or depth > 1:
|
||||
raise FilterInvalidArgument(
|
||||
"Vibrato depth must be between 0 and 1.")
|
||||
raise FilterInvalidArgument("Vibrato depth must be between 0 and 1.")
|
||||
|
||||
self.frequency = frequency
|
||||
self.depth = depth
|
||||
self.tag = tag
|
||||
|
||||
self.payload = {"vibrato": {"frequency": self.frequency,
|
||||
"depth": self.depth}}
|
||||
self.payload = {
|
||||
"vibrato": {
|
||||
"frequency": self.frequency,
|
||||
"depth": self.depth
|
||||
}
|
||||
}
|
||||
|
||||
def __repr__(self):
|
||||
return f"<Voicelink.VibratoFilter tag={self.tag} frequency={self.frequency} depth={self.depth}>"
|
||||
@@ -348,17 +361,13 @@ class ChannelMix(Filter):
|
||||
super().__init__()
|
||||
|
||||
if 0 > left_to_left > 1:
|
||||
raise ValueError(
|
||||
"'left_to_left' value must be more than or equal to 0 or less than or equal to 1.")
|
||||
raise ValueError("'left_to_left' value must be more than or equal to 0 or less than or equal to 1.")
|
||||
if 0 > right_to_right > 1:
|
||||
raise ValueError(
|
||||
"'right_to_right' value must be more than or equal to 0 or less than or equal to 1.")
|
||||
raise ValueError("'right_to_right' value must be more than or equal to 0 or less than or equal to 1.")
|
||||
if 0 > left_to_right > 1:
|
||||
raise ValueError(
|
||||
"'left_to_right' value must be more than or equal to 0 or less than or equal to 1.")
|
||||
raise ValueError("'left_to_right' value must be more than or equal to 0 or less than or equal to 1.")
|
||||
if 0 > right_to_left > 1:
|
||||
raise ValueError(
|
||||
"'right_to_left' value must be more than or equal to 0 or less than or equal to 1.")
|
||||
raise ValueError("'right_to_left' value must be more than or equal to 0 or less than or equal to 1.")
|
||||
|
||||
self.left_to_left = left_to_left
|
||||
self.left_to_right = left_to_right
|
||||
@@ -366,17 +375,19 @@ class ChannelMix(Filter):
|
||||
self.right_to_right = right_to_right
|
||||
self.tag = tag
|
||||
|
||||
self.payload = {"channelMix": {"leftToLeft": self.left_to_left,
|
||||
"leftToRight": self.left_to_right,
|
||||
"rightToLeft": self.right_to_left,
|
||||
"rightToRight": self.right_to_right}
|
||||
}
|
||||
|
||||
self.payload = {
|
||||
"channelMix": {
|
||||
"leftToLeft": self.left_to_left,
|
||||
"leftToRight": self.left_to_right,
|
||||
"rightToLeft": self.right_to_left,
|
||||
"rightToRight": self.right_to_right
|
||||
}
|
||||
}
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return (
|
||||
f"<Voicelink.ChannelMix tag={self.tag} left_to_left={self.left_to_left} left_to_right={self.left_to_right} "
|
||||
f"right_to_left={self.right_to_left} right_to_right={self.right_to_right}>"
|
||||
f"<Voicelink.ChannelMix tag={self.tag} left_to_left={self.left_to_left} left_to_right={self.left_to_right} "
|
||||
f"right_to_left={self.right_to_left} right_to_right={self.right_to_right}>"
|
||||
)
|
||||
|
||||
class Distortion(Filter):
|
||||
@@ -409,22 +420,24 @@ class Distortion(Filter):
|
||||
self.scale = scale
|
||||
self.tag = tag
|
||||
|
||||
self.payload = {"distortion": {
|
||||
"sinOffset": self.sin_offset,
|
||||
"sinScale": self.sin_scale,
|
||||
"cosOffset": self.cos_offset,
|
||||
"cosScale": self.cos_scale,
|
||||
"tanOffset": self.tan_offset,
|
||||
"tanScale": self.tan_scale,
|
||||
"offset": self.offset,
|
||||
"scale": self.scale
|
||||
}}
|
||||
self.payload = {
|
||||
"distortion": {
|
||||
"sinOffset": self.sin_offset,
|
||||
"sinScale": self.sin_scale,
|
||||
"cosOffset": self.cos_offset,
|
||||
"cosScale": self.cos_scale,
|
||||
"tanOffset": self.tan_offset,
|
||||
"tanScale": self.tan_scale,
|
||||
"offset": self.offset,
|
||||
"scale": self.scale
|
||||
}
|
||||
}
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return (
|
||||
f"<Voicelink.Distortion tag={self.tag} sin_offset={self.sin_offset} sin_scale={self.sin_scale}> "
|
||||
f"cos_offset={self.cos_offset} cos_scale={self.cos_scale} tan_offset={self.tan_offset} "
|
||||
f"tan_scale={self.tan_scale} offset={self.offset} scale={self.scale}"
|
||||
f"<Voicelink.Distortion tag={self.tag} sin_offset={self.sin_offset} sin_scale={self.sin_scale}> "
|
||||
f"cos_offset={self.cos_offset} cos_scale={self.cos_scale} tan_offset={self.tan_offset} "
|
||||
f"tan_scale={self.tan_scale} offset={self.offset} scale={self.scale}"
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -33,9 +33,11 @@ from function import (
|
||||
time as ctime
|
||||
)
|
||||
|
||||
from .spotify import Playlist as spPlaylist
|
||||
from .formatter import encode
|
||||
|
||||
YOUTUBE_REGEX = re.compile(r'(https?://)?(www\.)?youtube\.(com|nl)/watch\?v=([-\w]+)')
|
||||
|
||||
class Track:
|
||||
"""The base track object. Returns critical track information needed for parsing by Lavalink.
|
||||
You can also pass in commands.Context to get a discord.py Context object in your track.
|
||||
@@ -154,16 +156,16 @@ class Playlist:
|
||||
tracks: list,
|
||||
requester: Member = None,
|
||||
spotify: bool = False,
|
||||
spotify_playlist = None
|
||||
spotify_playlist: Optional[spPlaylist] = None
|
||||
):
|
||||
self.playlist_info = playlist_info
|
||||
self.tracks_raw = tracks
|
||||
self.spotify = spotify
|
||||
self.name = playlist_info.get("name")
|
||||
self.spotify_playlist = spotify_playlist
|
||||
self.playlist_info: dict = playlist_info
|
||||
self.tracks_raw: list[Track] = tracks
|
||||
self.spotify: bool = spotify
|
||||
self.name: str = playlist_info.get("name")
|
||||
self.spotify_playlist: Optional[spPlaylist] = spotify_playlist
|
||||
|
||||
self._thumbnail = None
|
||||
self._uri = None
|
||||
self._thumbnail: str = None
|
||||
self._uri: str = None
|
||||
|
||||
if self.spotify:
|
||||
self.tracks = tracks
|
||||
|
||||
@@ -201,7 +201,7 @@ class Player(VoiceProtocol):
|
||||
return self._volume
|
||||
|
||||
@property
|
||||
def filters(self) -> Filter:
|
||||
def filters(self) -> Filters:
|
||||
"""Property which returns the helper class for interacting with filters"""
|
||||
return self._filters
|
||||
|
||||
|
||||
@@ -30,7 +30,8 @@ async def connect_channel(member: Member, bot: commands.Bot):
|
||||
|
||||
channel = member.voice.channel
|
||||
try:
|
||||
player: Player = await channel.connect(cls=Player(bot, channel, TempCtx(member, channel)))
|
||||
settings = await func.get_settings(channel.guild.id)
|
||||
player: Player = await channel.connect(cls=Player(bot, channel, TempCtx(member, channel), settings))
|
||||
await player.send_ws({"op": "createPlayer", "members_id": [member.id for member in channel.members]})
|
||||
return player
|
||||
except:
|
||||
@@ -264,7 +265,7 @@ async def closeConnection(player: Player, member: Member, data: dict):
|
||||
player._ipc_connection = False
|
||||
|
||||
async def getPlaylists(member: Member, data: dict):
|
||||
playlists: dict = await func.get_playlist(member.id, "playlist")
|
||||
playlists: dict = await func.get_user(member.id, "playlist")
|
||||
if not playlists:
|
||||
return
|
||||
|
||||
@@ -276,10 +277,11 @@ async def getPlaylists(member: Member, data: dict):
|
||||
playlists[pId]["tracks"] = [ track.track_id for track in tracks.tracks ]
|
||||
|
||||
elif pList["type"] == "share":
|
||||
playlist = await func.get_playlist(pList["user"], "playlist", pList["referId"])
|
||||
playlist = await func.get_user(pList["user"], "playlist")
|
||||
playlist = playlist.get(pList["referId"])
|
||||
if playlist:
|
||||
if member.id not in playlist["perms"]["read"]:
|
||||
await func.update_playlist(member.id, {f"playlist.{pId}": 1}, mode="unset")
|
||||
await func.update_user(member.id, {"$unset": {f"playlist.{pId}": 1}})
|
||||
del playlists[pId]
|
||||
continue
|
||||
|
||||
@@ -304,9 +306,9 @@ async def removePlaylist(member: Member, data:dict):
|
||||
|
||||
if isShare:
|
||||
refer_user = data.get("refer_user")
|
||||
await func.update_playlist(refer_user, {f"playlist.{pId}.perms.read": member.id}, mode="pull")
|
||||
await func.update_user(refer_user, {"$pull": {f"playlist.{pId}.perms.read": member.id}})
|
||||
|
||||
await func.update_playlist(member.id, {f'playlist.{pId}': 1}, mode="unset")
|
||||
await func.update_user(member.id, {"$unset": {f'playlist.{pId}': 1}})
|
||||
|
||||
async def addPlaylistTrack(member: Member, data: dict):
|
||||
track_id = data.get("track_id")
|
||||
@@ -314,7 +316,8 @@ async def addPlaylistTrack(member: Member, data: dict):
|
||||
if not track_id or not pId:
|
||||
return
|
||||
|
||||
playlist: dict = await func.get_playlist(member.id, 'playlist', pId)
|
||||
playlist: dict = await func.get_user(member.id, 'playlist')
|
||||
playlist = playlist.get(pId)
|
||||
if not playlist:
|
||||
return
|
||||
|
||||
@@ -328,7 +331,7 @@ async def addPlaylistTrack(member: Member, data: dict):
|
||||
if track_id in playlist['tracks']:
|
||||
return error_msg(func.get_lang(member.guild.id, "playlistrepeated"), user_id=member.id)
|
||||
|
||||
await func.update_playlist(member.id, {f'playlist.{pId}.tracks': track_id}, mode="push")
|
||||
await func.update_user(member.id, {"$push": {f'playlist.{pId}.tracks': track_id}})
|
||||
|
||||
async def removePlaylistTrack(member: Member, data: dict):
|
||||
track_id = data.get("track_id")
|
||||
@@ -336,7 +339,7 @@ async def removePlaylistTrack(member: Member, data: dict):
|
||||
if not track_id or not pId:
|
||||
return
|
||||
|
||||
await func.update_playlist(member.id, {f'playlist.{pId}.tracks': track_id }, mode="pull")
|
||||
await func.update_user(member.id, {"$pull": {f'playlist.{pId}.tracks': track_id }})
|
||||
|
||||
methods = {
|
||||
"initPlayer": [initPlayer, False],
|
||||
|
||||
Reference in New Issue
Block a user