Migrate scripts to voicelink, rewrite handlers and views

This commit is contained in:
Choco
2025-09-29 19:39:19 +08:00
parent 7a4f85a74d
commit ef54f96f51
52 changed files with 2048 additions and 1642 deletions

View File

@@ -21,23 +21,22 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"""
import discord, voicelink, time
import time
import discord
import voicelink
from io import StringIO
from discord import app_commands
from discord.ext import commands
from function import (
send,
time as ctime,
get_user,
update_user,
check_roles,
get_aliases,
cooldown_check,
logger
)
from views import PlaylistViewManager, InboxView, HelpView
from voicelink import MongoDBHandler, Config
from voicelink.views import PlaylistViewManager, InboxView, HelpView
from voicelink.utils import format_ms, dispatch_message, send_localized_message
def assign_playlist_id(existed: list) -> str:
for i in range(200, 210):
@@ -46,7 +45,7 @@ def assign_playlist_id(existed: list) -> str:
async def check_playlist_perms(user_id: int, author_id: int, playlist_id: str) -> dict:
"""Check if user has read permissions for a specific playlist."""
user_data = await get_user(author_id, 'playlist')
user_data = await MongoDBHandler.get_user(author_id, d_type='playlist')
playlist = user_data.get(playlist_id)
if not playlist or user_id not in playlist['perms']['read']:
@@ -56,7 +55,7 @@ async def check_playlist_perms(user_id: int, author_id: int, playlist_id: str) -
async def check_playlist(ctx: commands.Context, name: str = None, full: bool = False, share: bool = True) -> dict:
"""Get user's playlist data with various filtering options."""
user_playlists = await get_user(ctx.author.id, 'playlist')
user_playlists = await MongoDBHandler.get_user(ctx.author.id, d_type='playlist')
if not ctx.interaction.response.is_done():
await ctx.defer()
@@ -90,7 +89,7 @@ async def search_playlist(url: str, requester: discord.Member, time_needed: bool
result = {"name": tracks.name, "tracks": tracks.tracks}
if time_needed:
result["time"] = ctime(sum(track.length for track in tracks.tracks))
result["time"] = format_ms(sum(track.length for track in tracks.tracks))
return result
except Exception:
@@ -135,7 +134,7 @@ async def _process_playlist(ctx: commands.Context, playlist_data: dict, playlist
)
if not shared_playlist:
await update_user(ctx.author.id, {"$unset": {f"playlist.{playlist_id}": 1}})
await MongoDBHandler.update_user(ctx.author.id, {"$unset": {f"playlist.{playlist_id}": 1}})
return None
if shared_playlist['type'] == 'link':
@@ -157,14 +156,14 @@ async def _process_playlist(ctx: commands.Context, playlist_data: dict, playlist
decoded_tracks = []
total_time = 0
for track in shared_playlist['tracks']:
decoded_track = voicelink.decode(track)
decoded_track = voicelink.Track.decode(track)
total_time += decoded_track.get("length", 0)
decoded_tracks.append(decoded_track)
return {
'emoji': emoji,
'id': playlist_id,
'time': ctime(total_time),
'time': format_ms(total_time),
'name': playlist_data['name'],
'tracks': decoded_tracks,
'perms': shared_playlist['perms'],
@@ -175,14 +174,14 @@ async def _process_playlist(ctx: commands.Context, playlist_data: dict, playlist
decoded_tracks = []
total_time = 0
for track in playlist_data['tracks']:
decoded_track = voicelink.decode(track)
decoded_track = voicelink.Track.decode(track)
total_time += decoded_track.get("length", 0)
decoded_tracks.append(decoded_track)
return {
'emoji': emoji,
'id': playlist_id,
'time': ctime(total_time),
'time': format_ms(total_time),
'name': playlist_data['name'],
'tracks': decoded_tracks,
'perms': playlist_data['perms'],
@@ -196,7 +195,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_user(interaction.user.id, 'playlist')
playlists_raw: dict[str, dict] = await MongoDBHandler.get_user(interaction.user.id, d_type='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]
@@ -210,7 +209,7 @@ class Playlists(commands.Cog, name="playlist"):
async def playlist(self, ctx: commands.Context):
view = HelpView(self.bot, ctx.author)
embed = view.build_embed(self.qualified_name)
view.response = send(ctx, embed, view=view)
view.response = dispatch_message(ctx, embed, view=view)
@playlist.command(name="play", aliases=get_aliases("play"))
@app_commands.describe(
@@ -224,10 +223,10 @@ class Playlists(commands.Cog, name="playlist"):
result = await check_playlist(ctx, name.lower() if name else None)
if not result['playlist']:
return await send(ctx, 'playlistNotFound', name, ephemeral=True)
rank, max_p, max_t = check_roles()
return await send_localized_message(ctx, 'playlistNotFound', name, ephemeral=True)
max_p, max_t, _ = Config().get_playlist_config()
if result['position'] > max_p:
return await send(ctx, 'playlistNotAccess', ephemeral=True)
return await send_localized_message(ctx, 'playlistNotAccess', ephemeral=True)
player: voicelink.Player = ctx.guild.voice_client
if not player:
@@ -237,21 +236,21 @@ class Playlists(commands.Cog, name="playlist"):
tracks = await search_playlist(result['playlist']['uri'], ctx.author, time_needed=False)
else:
if not result['playlist']['tracks']:
return await send(ctx, 'playlistNoTrack', result['playlist']['name'], ephemeral=True)
return await send_localized_message(ctx, 'playlistNoTrack', result['playlist']['name'], ephemeral=True)
_tracks = []
for track in result['playlist']['tracks'][:max_t]:
_tracks.append(voicelink.Track(track_id=track, info=voicelink.decode(track), requester=ctx.author))
_tracks.append(voicelink.Track(track_id=track, info=voicelink.Track.decode(track), requester=ctx.author))
tracks = {"name": result['playlist']['name'], "tracks": _tracks}
if not tracks:
return await send(ctx, 'playlistNoTrack', result['playlist']['name'], ephemeral=True)
return await send_localized_message(ctx, 'playlistNoTrack', result['playlist']['name'], ephemeral=True)
if value and 0 < value <= (len(tracks['tracks'])):
tracks['tracks'] = [tracks['tracks'][value - 1]]
await player.add_track(tracks['tracks'])
await send(ctx, 'playlistPlay', result['playlist']['name'], len(tracks['tracks'][:max_t]))
await send_localized_message(ctx, 'playlistPlay', result['playlist']['name'], len(tracks['tracks'][:max_t]))
if not player.is_playing:
await player.do_next()
@@ -261,13 +260,13 @@ class Playlists(commands.Cog, name="playlist"):
async def view(self, ctx: commands.Context) -> None:
"""List all your playlists and all songs in your favourite playlist."""
user_playlists = await check_playlist(ctx, full=True)
_, max_playlists, _ = check_roles()
max_p, _, _ = Config().get_playlist_config()
playlist_results = []
for index, playlist_id in enumerate(user_playlists, start=1):
playlist_data = user_playlists[playlist_id]
is_locked = max_playlists < index
is_locked = max_p < index
try:
result = await _process_playlist(ctx, playlist_data, playlist_id, is_locked)
@@ -284,7 +283,7 @@ class Playlists(commands.Cog, name="playlist"):
})
view = PlaylistViewManager(ctx, playlist_results)
view.response = await send(ctx, content=await view.build_embed(), view=view, ephemeral=True)
view.response = await dispatch_message(ctx, content=await view.build_embed(), view=view, ephemeral=True)
@playlist.command(name="create", aliases=get_aliases("create"))
@app_commands.describe(
@@ -295,25 +294,25 @@ class Playlists(commands.Cog, name="playlist"):
async def create(self, ctx: commands.Context, name: str, link: str = None):
"Create your custom playlist."
if len(name) > 10:
return await send(ctx, 'playlistOverText', ephemeral=True)
return await send_localized_message(ctx, 'playlistOverText', ephemeral=True)
rank, max_p, max_t = check_roles()
max_p, _, _ = Config().get_playlist_config()
user = await check_playlist(ctx, full=True)
if len(user) >= max_p:
return await send(ctx, 'overPlaylistCreation', max_p, ephemeral=True)
return await send_localized_message(ctx, 'overPlaylistCreation', max_p, ephemeral=True)
for data in user:
if user[data]['name'].lower() == name.lower():
return await send(ctx, 'playlistExists', name, ephemeral=True)
return await send_localized_message(ctx, 'playlistExists', name, ephemeral=True)
if link:
tracks = await voicelink.NodePool.get_node().get_tracks(link, requester=ctx.author)
if not isinstance(tracks, voicelink.Playlist):
return await send(ctx, "playlistNotInvalidUrl", ephemeral=True)
return await send_localized_message(ctx, "playlistNotInvalidUrl", 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_user(ctx.author.id, {"$set": {f"playlist.{assign_playlist_id([data for data in user])}": data}})
await send(ctx, "playlistCreated", name)
await MongoDBHandler.update_user(ctx.author.id, {"$set": {f"playlist.{assign_playlist_id([data for data in user])}": data}})
await send_localized_message(ctx, "playlistCreated", name)
@playlist.command(name="delete", aliases=get_aliases("delete"))
@app_commands.describe(name="The name of the playlist.")
@@ -323,15 +322,15 @@ class Playlists(commands.Cog, name="playlist"):
"Delete your custom playlist."
result = await check_playlist(ctx, name.lower(), share=False)
if not result['playlist']:
return await ctx(ctx, "playlistNotFound", name, ephemeral=True)
return await send_localized_message(ctx, "playlistNotFound", name, ephemeral=True)
if result['id'] == "200":
return await send(ctx, "playlistDeleteError", ephemeral=True)
return await send_localized_message(ctx, "playlistDeleteError", ephemeral=True)
if result['playlist']['type'] == 'share':
await update_user(result['playlist']['user'], {"$pull": {f"playlist.{result['playlist']['referId']}.perms.read": ctx.author.id}})
await MongoDBHandler.update_user(result['playlist']['user'], {"$pull": {f"playlist.{result['playlist']['referId']}.perms.read": ctx.author.id}})
await update_user(ctx.author.id, {"$unset": {f"playlist.{result['id']}": 1}})
return await send(ctx, "playlistRemove", result["playlist"]["name"])
await MongoDBHandler.update_user(ctx.author.id, {"$unset": {f"playlist.{result['id']}": 1}})
return await send_localized_message(ctx, "playlistRemove", result["playlist"]["name"])
@playlist.command(name="share", aliases=get_aliases("share"))
@app_commands.describe(
@@ -343,28 +342,28 @@ class Playlists(commands.Cog, name="playlist"):
async def share(self, ctx: commands.Context, member: discord.Member, name: str):
"Share your custom playlist with your friends."
if member.id == ctx.author.id:
return await send(ctx, 'playlistSendErrorPlayer', ephemeral=True)
return await send_localized_message(ctx, 'playlistSendErrorPlayer', ephemeral=True)
if member.bot:
return await send(ctx, 'playlistSendErrorBot', ephemeral=True)
return await send_localized_message(ctx, 'playlistSendErrorBot', ephemeral=True)
result = await check_playlist(ctx, name.lower(), share=False)
if not result['playlist']:
return await send(ctx, 'playlistNotFound', name, ephemeral=True)
return await send_localized_message(ctx, 'playlistNotFound', name, ephemeral=True)
if result['playlist']['type'] == 'share':
return await send(ctx, 'playlistBelongs', result['playlist']['user'], ephemeral=True)
return await send_localized_message(ctx, 'playlistBelongs', result['playlist']['user'], ephemeral=True)
if member.id in result['playlist']['perms']['read']:
return await send(ctx, 'playlistShare', member, ephemeral=True)
return await send_localized_message(ctx, 'playlistShare', member, ephemeral=True)
receiver = await get_user(member.id)
receiver = await MongoDBHandler.get_user(member.id)
if not receiver:
return await send(ctx, 'noPlaylistAcc', member)
return await send_localized_message(ctx, 'noPlaylistAcc', member)
for mail in receiver['inbox']:
if mail['sender'] == ctx.author.id and mail['referId'] == result['id']:
return await send(ctx, 'playlistSent', ephemeral=True)
return await send_localized_message(ctx, 'playlistSent', ephemeral=True)
if len(receiver['inbox']) >= 10:
return await send(ctx.guild.id, 'inboxFull', member, ephemeral=True)
return await send_localized_message(ctx.guild.id, 'inboxFull', member, ephemeral=True)
await update_user(
await MongoDBHandler.update_user(
member.id,
{"$push": {"inbox": {
'sender': ctx.author.id,
@@ -375,7 +374,7 @@ class Playlists(commands.Cog, name="playlist"):
'type': 'invite'
}}}
)
return await send(ctx, "invitationSent", member)
return await send_localized_message(ctx, "invitationSent", member)
@playlist.command(name="rename", aliases=get_aliases("rename"))
@app_commands.describe(
@@ -387,36 +386,36 @@ class Playlists(commands.Cog, name="playlist"):
async def rename(self, ctx: commands.Context, name: str, newname: str) -> None:
"Rename your custom playlist."
if len(newname) > 10:
return await send(ctx, 'playlistOverText', ephemeral=True)
return await send_localized_message(ctx, 'playlistOverText', ephemeral=True)
if name.lower() == newname.lower():
return await send(ctx, 'playlistSameName', ephemeral=True)
return await send_localized_message(ctx, 'playlistSameName', ephemeral=True)
user = await check_playlist(ctx, full=True)
found, id = False, 0
for data in user:
if user[data]['name'].lower() == name.lower():
found, id = True, data
if user[data]['name'].lower() == newname.lower():
return await send(ctx, 'playlistExists', ephemeral=True)
return await send_localized_message(ctx, 'playlistExists', ephemeral=True)
if not found:
return await send(ctx.guild.id, 'playlistNotFound', name, ephemeral=True)
return await send_localized_message(ctx.guild.id, 'playlistNotFound', name, ephemeral=True)
await update_user(ctx.author.id, {"$set": {f'playlist.{id}.name': newname}})
await send(ctx, 'playlistRenamed', name, newname)
await MongoDBHandler.update_user(ctx.author.id, {"$set": {f'playlist.{id}.name': newname}})
await send_localized_message(ctx, 'playlistRenamed', 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_user(ctx.author.id)
rank, max_p, max_t = check_roles()
user = await MongoDBHandler.get_user(ctx.author.id)
max_p, _, _ = Config().get_playlist_config()
if not user['inbox']:
return await send(ctx, 'inboxNoMsg', ephemeral=True)
return await send_localized_message(ctx, "inboxNoMsg", ephemeral=True)
inbox = user['inbox'].copy()
view = InboxView(ctx.author, user['inbox'])
view.response = await send(ctx, view.build_embed(), view=view, ephemeral=True)
view.response = await dispatch_message(ctx, view.build_embed(), view=view, ephemeral=True)
await view.wait()
if inbox == user['inbox']:
@@ -425,7 +424,7 @@ class Playlists(commands.Cog, name="playlist"):
update_data, dId = {}, {dId for dId in user["playlist"]}
for data in view.new_playlist[:(max_p - len(user['playlist']))]:
addId = assign_playlist_id(dId)
await update_user(data['sender'], {"$push": {f"playlist.{data['referId']}.perms.read": ctx.author.id}})
await MongoDBHandler.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{time.strftime('%M%S', time.gmtime(int(data['time'])))}",
@@ -435,7 +434,7 @@ class Playlists(commands.Cog, name="playlist"):
dId.add(addId)
if update_data:
await update_user(ctx.author.id, {"$set": update_data})
await MongoDBHandler.update_user(ctx.author.id, {"$set": update_data})
@playlist.command(name="add", aliases=get_aliases("add"))
@commands.dynamic_cooldown(cooldown_check, commands.BucketType.guild)
@@ -448,26 +447,26 @@ class Playlists(commands.Cog, name="playlist"):
"Add tracks in to your custom playlist."
result = await check_playlist(ctx, name.lower(), share=False)
if not result['playlist']:
return await send(ctx, 'playlistNotFound', name, ephemeral=True)
return await send_localized_message(ctx, 'playlistNotFound', name, ephemeral=True)
if result['playlist']['type'] in ['share', 'link']:
return await send(ctx, 'playlistNotAllow', ephemeral=True)
return await send_localized_message(ctx, 'playlistNotAllow', ephemeral=True)
rank, max_p, max_t = check_roles()
_, max_t, _ = Config().get_playlist_config()
if len(result['playlist']['tracks']) >= max_t:
return await send(ctx, 'playlistLimitTrack', max_t, ephemeral=True)
return await send_localized_message(ctx, 'playlistLimitTrack', max_t, ephemeral=True)
results = await voicelink.NodePool.get_node().get_tracks(query, requester=ctx.author)
if not results:
return await send(ctx, 'noTrackFound')
return await send_localized_message(ctx, 'noTrackFound')
if isinstance(results, voicelink.Playlist):
return await send(ctx, 'playlistPlaylistLink', ephemeral=True)
return await send_localized_message(ctx, 'playlistPlaylistLink', ephemeral=True)
if results[0].is_stream:
return await send(ctx, 'playlistStream', ephemeral=True)
return await send_localized_message(ctx, 'playlistStream', ephemeral=True)
await update_user(ctx.author.id, {"$push": {f'playlist.{result["id"]}.tracks': results[0].track_id}})
await send(ctx, 'playlistAdded', results[0].title, ctx.author, result['playlist']['name'])
await MongoDBHandler.update_user(ctx.author.id, {"$push": {f'playlist.{result["id"]}.tracks': results[0].track_id}})
await send_localized_message(ctx, 'playlistAdded', results[0].title, ctx.author, result['playlist']['name'])
@playlist.command(name="remove", aliases=get_aliases("remove"))
@commands.dynamic_cooldown(cooldown_check, commands.BucketType.guild)
@@ -480,16 +479,16 @@ class Playlists(commands.Cog, name="playlist"):
"Remove song from your favorite playlist."
result = await check_playlist(ctx, name.lower(), share=False)
if not result['playlist']:
return await send(ctx, 'playlistNotFound', name, ephemeral=True)
return await send_localized_message(ctx, 'playlistNotFound', name, ephemeral=True)
if result['playlist']['type'] in ['link', 'share']:
return await send(ctx, 'playlistNotAllow', ephemeral=True)
return await send_localized_message(ctx, 'playlistNotAllow', ephemeral=True)
if not 0 < position <= len(result['playlist']['tracks']):
return await send(ctx, 'playlistPositionNotFound', position, name)
return await send_localized_message(ctx, 'playlistPositionNotFound', position, name)
await update_user(ctx.author.id, {"$pull": {f'playlist.{result["id"]}.tracks': result['playlist']['tracks'][position - 1]}})
await MongoDBHandler.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 send(ctx, 'playlistRemoved', track.get("title"), ctx.author, name)
track = voicelink.Track.decode(result['playlist']['tracks'][position - 1])
await send_localized_message(ctx, 'playlistRemoved', track.get("title"), ctx.author, name)
@playlist.command(name="clear", aliases=get_aliases("clear"))
@commands.dynamic_cooldown(cooldown_check, commands.BucketType.guild)
@@ -498,13 +497,13 @@ class Playlists(commands.Cog, name="playlist"):
"Remove all songs from your favorite playlist."
result = await check_playlist(ctx, name.lower(), share=False)
if not result['playlist']:
return await send(ctx, 'playlistNotFound', name, ephemeral=True)
return await send_localized_message(ctx, 'playlistNotFound', name, ephemeral=True)
if result['playlist']['type'] in ['link', 'share']:
return await send(ctx, 'playlistNotAllow', ephemeral=True)
return await send_localized_message(ctx, 'playlistNotAllow', ephemeral=True)
await update_user(ctx.author.id, {"$set": {f'playlist.{result["id"]}.tracks': []}})
await send(ctx, 'playlistClear', name)
await MongoDBHandler.update_user(ctx.author.id, {"$set": {f'playlist.{result["id"]}.tracks': []}})
await send_localized_message(ctx, 'playlistClear', name)
@playlist.command(name="export", aliases=get_aliases("export"))
@commands.dynamic_cooldown(cooldown_check, commands.BucketType.guild)
@@ -513,29 +512,29 @@ class Playlists(commands.Cog, name="playlist"):
"Exports the entire playlist to a text file"
result = await check_playlist(ctx, name.lower())
if not result['playlist']:
return await send(ctx, 'playlistNotFound', name, ephemeral=True)
return await send_localized_message(ctx, 'playlistNotFound', name, ephemeral=True)
if result['playlist']['type'] == 'link':
tracks = await search_playlist(result['playlist']['uri'], ctx.author, time_needed=False)
else:
if not result['playlist']['tracks']:
return await send(ctx, 'playlistNoTrack', result['playlist']['name'], ephemeral=True)
return await send_localized_message(ctx, 'playlistNoTrack', result['playlist']['name'], ephemeral=True)
_tracks = []
for track in result['playlist']['tracks']:
_tracks.append(voicelink.Track(track_id=track, info=voicelink.decode(track), requester=ctx.author))
_tracks.append(voicelink.Track(track_id=track, info=voicelink.Track.decode(track), requester=ctx.author))
tracks = {"name": result['playlist']['name'], "tracks": _tracks}
if not tracks:
return await send(ctx, 'playlistNoTrack', result['playlist']['name'], ephemeral=True)
return await send_localized_message(ctx, 'playlistNoTrack', result['playlist']['name'], ephemeral=True)
temp = ""
raw = "----------->Raw Info<-----------\n"
total_length = 0
for index, track in enumerate(tracks['tracks'], start=1):
temp += f"{index}. {track.title} [{ctime(track.length)}]\n"
temp += f"{index}. {track.title} [{format_ms(track.length)}]\n"
raw += track.track_id
if index != len(tracks['tracks']):
raw += ","
@@ -544,7 +543,7 @@ class Playlists(commands.Cog, name="playlist"):
temp = "!Remember do not change this file!\n------------->Info<-------------\nPlaylist: {} ({})\nRequester: {} ({})\nTracks: {} - {}\n------------>Tracks<------------\n".format(
tracks['name'], result['playlist']['type'],
ctx.author.display_name, ctx.author.id,
len(tracks['tracks']), ctime(total_length)
len(tracks['tracks']), format_ms(total_length)
) + temp
temp += raw
@@ -556,17 +555,17 @@ class Playlists(commands.Cog, name="playlist"):
async def _import(self, ctx: commands.Context, name: str, attachment: discord.Attachment):
"Create your custom playlist."
if len(name) > 10:
return await send(ctx, 'playlistOverText', ephemeral=True)
return await send_localized_message(ctx, 'playlistOverText', ephemeral=True)
rank, max_p, max_t = check_roles()
max_p, _, _ = Config().get_playlist_config()
user = await check_playlist(ctx, full=True)
if len(user) >= max_p:
return await send(ctx, 'overPlaylistCreation', max_p, ephemeral=True)
return await send_localized_message(ctx, 'overPlaylistCreation', max_p, ephemeral=True)
for data in user:
if user[data]['name'].lower() == name.lower():
return await send(ctx, 'playlistExists', name, ephemeral=True)
return await send_localized_message(ctx, 'playlistExists', name, ephemeral=True)
try:
bytes = await attachment.read()
@@ -574,8 +573,8 @@ 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_user(ctx.author.id, {"$set": {f"playlist.{assign_playlist_id([data for data in user])}": data}})
await send(ctx, 'playlistCreated', name)
await MongoDBHandler.update_user(ctx.author.id, {"$set": {f"playlist.{assign_playlist_id([data for data in user])}": data}})
await send_localized_message(ctx, 'playlistCreated', name)
except Exception as e:
logger.error("Decode Error", exc_info=e)