Transfer track info to track id

This commit is contained in:
Choco
2023-05-16 19:03:48 +08:00
parent cc64cc1ea6
commit a44b6c9384
15 changed files with 71 additions and 96 deletions

View File

@@ -3,7 +3,6 @@ import voicelink
from discord import app_commands
from discord.ext import commands
from tldextract import extract
from function import (
time as ctime,
get_playlist,
@@ -120,9 +119,8 @@ class Playlists(commands.Cog, name="playlist"):
playtrack = []
for track in result['playlist']['tracks'][:max_t]:
track['info']['length'] *= 1000
playtrack.append(voicelink.Track(track_id=track['id'], info=track['info'], requester=ctx.author, spotify=True if extract(
track['info']['uri']).domain == 'spotify' else False))
playtrack.append(voicelink.Track(track_id=track, info=voicelink.decode(track), requester=ctx.author))
tracks = {"name": result['playlist']['name'], "tracks": playtrack}
if not tracks:
@@ -152,8 +150,7 @@ class Playlists(commands.Cog, name="playlist"):
try:
if playlist['type'] == 'link':
tracks = await search_playlist(playlist['uri'], requester=ctx.author)
results.append({'emoji': ('🔒' if max_p < index else '🔗'), 'id': data, 'time': tracks['time'], 'name': playlist[
'name'], 'tracks': tracks['tracks'], 'perms': playlist['perms'], 'type': playlist['type']})
results.append({'emoji': ('🔒' if max_p < index else '🔗'), 'id': data, 'time': tracks['time'], 'name': playlist['name'], 'tracks': tracks['tracks'], 'perms': playlist['perms'], 'type': playlist['type']})
else:
if share := playlist['type'] == 'share':
playlist = await check_playlist_perms(ctx.author.id, playlist['user'], playlist['referId'])
@@ -162,25 +159,25 @@ class Playlists(commands.Cog, name="playlist"):
continue
if playlist['type'] == 'link':
tracks = await search_playlist(playlist['uri'], requester=ctx.author)
results.append({'emoji': ('🔒' if max_p < index else '🤝'), 'id': data, 'time': tracks['time'], 'name': user[data][
'name'], 'tracks': tracks['tracks'], 'perms': playlist['perms'], 'owner': user[data]['user'], 'type': 'share'})
results.append({'emoji': ('🔒' if max_p < index else '🤝'), 'id': data, 'time': tracks['time'], 'name': user[data]['name'], 'tracks': tracks['tracks'], 'perms': playlist['perms'], 'owner': user[data]['user'], 'type': 'share'})
continue
init = []
for track in playlist['tracks']:
time += track['info']['length'] * 1000
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'})
dt = voicelink.decode(track)
time += dt.get("length", 0)
init.append(dt)
playlist['tracks'] = init
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 Exception as e:
results.append({'emoji': '', 'id': data, 'time': '00:00', 'name': 'Error', 'tracks': [], 'type': 'error'})
embed = discord.Embed(title=get_lang(ctx.guild.id, 'playlistViewTitle').format(ctx.author.name),
description='```%0s %4s %10s %10s %10s\n' % tuple(get_lang(ctx.guild.id, 'playlistViewHeaders')) + '\n'.join(
'%0s %3s. %10s %10s %10s' % (info['emoji'], info['id'], f"[{info['time']}]", info['name'], len(info['tracks'])) for info in results) + '```',
description='```%0s %4s %10s %10s %10s\n' % tuple(get_lang(ctx.guild.id, 'playlistViewHeaders')) + '\n'.join('%0s %3s. %10s %10s %10s' % (info['emoji'], info['id'], f"[{info['time']}]", info['name'], len(info['tracks'])) for info in results) + '```',
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)
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)
embed.set_footer(text=get_lang(ctx.guild.id, 'playlistFooter'))
view = PlaylistView(embed, results, ctx.author)
@@ -197,27 +194,25 @@ class Playlists(commands.Cog, name="playlist"):
"Create your custom playlist."
if len(name) > 10:
return await ctx.send(get_lang(ctx.guild.id, 'playlistOverText'), ephemeral=True)
isLinkType = True if link else False
rank, max_p, max_t = await checkroles(ctx.author.id)
if isLinkType and rank != "Gold":
return await ctx.send(get_lang(ctx.guild.id, 'playlistCreateError'), ephemeral=True)
user = await check_playlist(ctx, full=True)
if not user:
return await create_account(ctx)
if len(user) >= max_p:
return await ctx.send(get_lang(ctx.guild.id, 'overPlaylistCreation').format(max_p), ephemeral=True)
for data in user:
if user[data]['name'].lower() == name.lower():
return await ctx.send(get_lang(ctx.guild.id, 'playlistExists'), ephemeral=True)
if isLinkType:
if link:
tracks = await voicelink.NodePool.get_node().get_tracks(link, requester=ctx.author)
if not isinstance(tracks, voicelink.Playlist):
return await ctx.send(get_lang(ctx.guild.id, 'playlistNotInvaildUrl'), ephemeral=True)
playlist_name.pop(str(ctx.author.id), None)
data = {'uri': link, 'perms': {'read': []}, 'name': name, 'type': 'link'} if isLinkType else {
'tracks': [], 'perms': {'read': [], 'write': [], 'remove': []}, 'name': name, 'type': 'playlist'}
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, {f"playlist.{assign_playlistId([data for data in user])}": data})
await ctx.send(get_lang(ctx.guild.id, 'playlistCreated').format(name))
@@ -353,24 +348,22 @@ class Playlists(commands.Cog, name="playlist"):
return await ctx.send(get_lang(ctx.guild.id, 'playlistNotFound').format(name), ephemeral=True)
if result['playlist']['type'] in ['share', 'link']:
return await ctx.send(get_lang(ctx.guild.id, 'playlistNotAllow'), ephemeral=True)
rank, max_p, max_t = await checkroles(ctx.author.id)
if len(result['playlist']['tracks']) >= max_t:
return await ctx.send(get_lang(ctx.guild.id, 'playlistLimitTrack').format(max_t), ephemeral=True)
results = await voicelink.NodePool.get_node().get_tracks(query, requester=ctx.author)
if not results:
return await ctx.send(get_lang(ctx.guild.id, 'noTrackFound'))
if isinstance(results, voicelink.Playlist):
return await ctx.send(get_lang(ctx.guild.id, 'playlistPlaylistLink'), ephemeral=True)
if results[0].is_stream:
return await ctx.send(get_lang(ctx.guild.id, 'playlistStream'), ephemeral=True)
await update_playlist(ctx.author.id, {f'playlist.{result["id"]}.tracks': {'id': results[0].track_id, 'info': {'identifier': results[0].identifier,
'author': results[0].author,
'length': results[0].length / 1000,
'title': results[0].title,
'uri': results[0].uri}}}, push=True)
await update_playlist(ctx.author.id, {f'playlist.{result["id"]}.tracks': results[0].track_id}, push=True)
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"))

View File

@@ -63,7 +63,6 @@
"playlistShare": "抱歉!此播放清單已與 {0} 共享。",
"playlistSent": "抱歉!你已發送過邀請。",
"noPlaylistAcc": "{0} 沒有建立播放清單帳戶。",
"playlistCreateError": "抱歉!你無法建立此類型的播放清單!",
"overPlaylistCreation": "你不能建立超過 `{0}` 個播放清單!",
"playlistExists": "播放清單 [`{0}`] 已存在。",
"playlistNotInvaildUrl": "請輸入有效的連結或公開的 Spotify 或 YouTube 播放清單連結。",

View File

@@ -63,7 +63,6 @@
"playlistShare": "Es tut uns leid! Diese Playlist wurde mit {0} geteilt.",
"playlistSent": "Es tut uns leid! Sie haben bereits eine Einladung gesendet.",
"noPlaylistAcc": "{0} hat kein Playlist-Konto erstellt.",
"playlistCreateError": "Es tut uns leid! Sie können diese Art von Wiedergabeliste nicht erstellen!",
"overPlaylistCreation": "Sie können nicht mehr als `{0}` Wiedergabelisten erstellen!",
"playlistExists": "Playlist [`{0}`] existiert bereits.",
"playlistNotInvaildUrl": "Bitte geben Sie einen gültigen Link oder öffentlichen Spotify- oder YouTube-Playlist-Link ein.",

View File

@@ -63,7 +63,6 @@
"playlistShare": "Sorry! This playlist has been shared with {0}.",
"playlistSent": "Sorry! You have sent an invitation before.",
"noPlaylistAcc": "{0} didn't create a playlist account.",
"playlistCreateError": "Sorry! You are not able to create this type of playlist!",
"overPlaylistCreation": "You cannot create more than `{0}` playlists!",
"playlistExists": "Playlist [`{0}`] already exists.",
"playlistNotInvaildUrl": "Please enter a valid link or public spotify or youtube playlist link.",

View File

@@ -63,7 +63,6 @@
"playlistShare": "Lo siento! Esta lista de reproducción se ha compartido con `{0}`.",
"playlistSent": "Lo siento! Ya ha enviado una invitación antes.",
"noPlaylistAcc": "`{0}` no ha creado una cuenta de lista de reproducción.",
"playlistCreateError": "Lo siento! No puede crear este tipo de lista de reproducción.",
"overPlaylistCreation": "¡No puede crear más de `{0}` listas de reproducción!",
"playlistExists": "La lista de reproducción [`{0}`] ya existe.",
"playlistNotInvaildUrl": "Ingrese un enlace válido o un enlace público de lista de reproducción de Spotify o YouTube.",

View File

@@ -63,7 +63,6 @@
"playlistShare": "申し訳ありません!このプレイリストは{0}さんと共有されています。",
"playlistSent": "申し訳ありません!以前に招待状を送信しました。",
"noPlaylistAcc": "{0}さんはプレイリストアカウントを作成していません。",
"playlistCreateError": "申し訳ありません!この種類のプレイリストを作成することはできません!",
"overPlaylistCreation": " {0}個以上のプレイリストを作成することはできません!",
"playlistExists": "プレイリスト[{0}]はすでに存在します。",
"playlistNotInvaildUrl": "有効なリンクまたは公開SpotifyまたはYouTubeプレイリストリンクを入力してください。",

View File

@@ -63,7 +63,6 @@
"playlistShare": "죄송합니다! 이 재생 목록은 {0}과(와) 공유되었습니다.",
"playlistSent": "죄송합니다! 이미 초대장을 보냈습니다.",
"noPlaylistAcc": "{0}님은 재생 목록 계정을 만들지 않았습니다.",
"playlistCreateError": "죄송합니다! 이 유형의 재생 목록을 만들 수 없습니다!",
"overPlaylistCreation": "더 이상 {0}개 이상의 재생 목록을 만들 수 없습니다!",
"playlistExists": "재생 목록 [{0}]이(가) 이미 있습니다.",
"playlistNotInvaildUrl": "유효한 링크 또는 공개 Spotify 또는 YouTube 재생 목록 링크를 입력하세요.",

View File

@@ -30,9 +30,9 @@ from function import (
get_playlist,
update_playlist,
create_account,
checkroles,
formatTime
checkroles
)
from typing import Dict
def key(interaction: discord.Interaction):
@@ -166,15 +166,10 @@ class Add(discord.ui.Button):
rank, max_p, max_t = await checkroles(interaction.user.id)
if len(user['200']['tracks']) >= max_t:
return await interaction.response.send_message(self.player.get_msg("playlistlimited").format(max_t), ephemeral=True)
addtrack = {'id': track.track_id,
'info':{'identifier': track.identifier,
'author': track.author,
'length': track.length / 1000,
'title': track.title,
'uri': track.uri}}
if addtrack in user['200']['tracks']:
if track.track_id in user['200']['tracks']:
return await interaction.response.send_message(self.player.get_msg("playlistrepeated"), ephemeral=True)
respond = await update_playlist(interaction.user.id, {'playlist.200.tracks': addtrack}, push=True)
respond = await update_playlist(interaction.user.id, {'playlist.200.tracks': track.track_id}, push=True)
if respond:
await interaction.response.send_message(self.player.get_msg("playlistAdded").format(track.title, interaction.user.mention, user['200']['name']), ephemeral=True)
else:

View File

@@ -90,7 +90,7 @@ class PlaylistView(discord.ui.View):
embed = discord.Embed(title=func.get_lang(self.guildID, 'playlistView'), color=func.settings.embed_color)
embed.description= func.get_lang(self.guildID, 'playlistViewDesc').format(self.current['name'], self.current['id'], len(self.current['tracks']), self.current.get('owner', "None"), self.current['type'])
embed.description= func.get_lang(self.guildID, 'playlistViewDesc').format(self.current['name'], self.current['id'], len(self.current['tracks']), owner if (owner := self.current.get('owner')) else f"{self.author.id} (You)", self.current['type'])
perms = self.current['perms']
permsStr = func.get_lang(self.guildID, 'settingsPermTitle')
@@ -101,9 +101,9 @@ class PlaylistView(discord.ui.View):
trackStr = func.get_lang(self.guildID, 'playlistViewTrack')
if tracks:
try:
embed.add_field(name=trackStr, value='\n'.join(f"{func.emoji_source(extract(track['info']['uri']).domain)} `{index}.` `[{func.time(track['info']['length'] * 1000)}]` **{track['info']['title'][:30]}** " for index, track in enumerate(tracks, start=offset - 6)), inline=False)
except:
if self.current.get("type") == "playlist":
embed.add_field(name=trackStr, value="\n".join(f"{func.emoji_source(track['sourceName'])} `{index}.` `[{func.time(track['length'])}]` **{track['title'][:30]}**" for index, track in enumerate(tracks, start=offset - 6)), inline=False)
else:
embed.add_field(name=trackStr, value='\n'.join(f"{func.emoji_source(extract(track.info['uri']).domain)} `{index}.` `[{func.time(track.length)}]` **{track.title[:30]}** " for index, track in enumerate(tracks, start=offset - 6)), inline=False)
else:
embed.add_field(name=trackStr, value=func.get_lang(self.guildID, 'playlistNoTrack').format(self.current['name']), inline=False)

View File

@@ -21,7 +21,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"""
__version__ = "1.0"
__version__ = "1.3"
__author__ = 'Vocard Development, Choco'
__license__ = "MIT"
__copyright__ = "Copyright 2023 (c) Vocard Development, Choco"
@@ -35,3 +35,4 @@ from .player import Player, connect_channel
from .pool import *
from .queue import *
from .placeholders import Placeholders, build_embed
from .formatter import encode, decode

View File

@@ -33,6 +33,8 @@ from function import (
time as ctime
)
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.
@@ -42,29 +44,30 @@ class Track:
def __init__(
self,
*,
track_id: str,
track_id: str = None,
info: dict,
requester: Member,
spotify: bool = False,
search_type: SearchType = SearchType.ytsearch,
spotify_track = None,
):
self.track_id = track_id
self.info = info
self.spotify = spotify
if self.spotify:
self.artistId: Optional[list] = info.get("artistId")
self.original: Optional[Track] = None if spotify else self
self._search_type = SearchType.ytmsearch if spotify else search_type
self.spotify_track = spotify_track
self.identifier = info.get("identifier")
self.title = info.get("title", "Unknown")
self.author = info.get("author", "Unknown")
self.uri = info.get("uri", "https://discord.com/application-directory/605618911471468554")
self.identifier = info.get("identifier")
self.source = info.get("sourceName", extract(self.uri).domain)
self.spotify = True if self.source == "spotify" else False
if self.spotify:
self.artistId: Optional[list] = info.get("artistId")
self.original: Optional[Track] = None if self.spotify else self
self._search_type = SearchType.ytmsearch if self.spotify else search_type
self.spotify_track = spotify_track
self.thumbnail = None
self.source = extract(self.uri).domain
self.emoji = emoji_source(self.source)
if info.get("thumbnail"):
@@ -83,6 +86,9 @@ class Track:
self.is_seekable = info.get("isSeekable", True)
self.position = info.get("position", 0)
if not track_id:
self.track_id = encode(self)
def toDict(self):
return {
"track_id": self.track_id,
@@ -90,6 +96,9 @@ class Track:
"thumbnail": self.thumbnail
}
def encode(self):
return encode(self)
def __eq__(self, other):
if not isinstance(other, Track):
return False
@@ -102,7 +111,6 @@ class Track:
def __repr__(self):
return f"<Voicelink.track title={self.title!r} uri=<{self.uri!r}> length={self.length}>"
class Playlist:
"""The base playlist object.
Returns critical playlist information needed for parsing by Lavalink.

View File

@@ -446,7 +446,6 @@ class Player(VoiceProtocol):
track_id=track.id,
requester=requester,
search_type=SearchType.ytsearch,
spotify=True,
spotify_track=track,
info={
"title": track.name,
@@ -470,7 +469,6 @@ class Player(VoiceProtocol):
return [ Track(
track_id=track.id,
search_type=SearchType.ytsearch,
spotify=True,
spotify_track=track,
info={
"title": track.name,
@@ -578,7 +576,7 @@ class Player(VoiceProtocol):
finally:
if tracks:
if self.is_ipc_connected:
await self.send_ws({"op": "addTrack", "tracks": [track.toDict() for track in tracks]}, tracks[0].requester)
await self.send_ws({"op": "addTrack", "tracks": [track.track_id for track in tracks]}, tracks[0].requester)
return len(tracks) if isList else position
async def seek(self, position: float, requester: Member = None) -> float:
@@ -618,7 +616,7 @@ class Player(VoiceProtocol):
if self.is_ipc_connected:
await self.send_ws({
"op": "shuffleTrack",
"tracks": [track.toDict() for track in self.queue._queue],
"tracks": [track.track_id for track in self.queue._queue],
"verified": {
"index": self.queue._position if queue_type == "queue" else 0,
"track_id": replacement[0].track_id,

View File

@@ -402,10 +402,9 @@ class Node:
if isinstance(spotify_results, spotify.Track):
return [
Track(
track_id=spotify_results.id,
track_id=None,
requester=requester,
search_type=search_type,
spotify=True,
spotify_track=spotify_results,
info={
"title": spotify_results.name,
@@ -424,10 +423,9 @@ class Node:
tracks = [
Track(
track_id=track.id,
track_id=None,
requester=requester,
search_type=search_type,
spotify=True,
spotify_track=track,
info={
"title": track.name,
@@ -467,7 +465,7 @@ class Node:
return [
Track(
track_id=track["track"],
track_id=None,
info={
"title": discord_url.group("file"),
"author": "Unknown",

View File

@@ -2,7 +2,7 @@ import json
from discord import Member, VoiceChannel
from discord.ext import commands
from voicelink import Player, Track, Playlist, connect_channel
from voicelink import Player, Track, Playlist, connect_channel, decode
class TempCtx():
def __init__(self, author: Member, channel: VoiceChannel) -> None:
@@ -47,7 +47,7 @@ async def initPlayer(player: Player, member: Member, data: dict):
"avatar_url": member.display_avatar.url,
"name": member.name
} for member in player.channel.members ],
"tracks": [ track.toDict() for track in player.queue._queue ],
"tracks": [ track.track_id for track in player.queue._queue ],
"repeat_mode": player.queue.repeat.lower(),
"channel_name": player.channel.name,
"current_queue_position": player.queue._position if player.is_playing else player.queue._position + 1,
@@ -139,10 +139,10 @@ async def moveTrack(player: Player, member: Member, data: dict):
async def addTracks(player: Player, member: Member, data: dict):
raw_tracks = data.get("tracks", [])
tracks = [Track(
track_id=track["track_id"],
info=track["info"],
track_id=track_id,
info=decode(track_id),
requester=member
) for track in raw_tracks]
) for track_id in raw_tracks]
await player.add_track(tracks)
@@ -159,9 +159,9 @@ async def getTracks(player: Player, member: Member, data: dict):
return payload
if isinstance(tracks, Playlist):
tracks = [ track for track in tracks.tracks[:20] ]
tracks = [ track for track in tracks.tracks[:50] ]
payload["tracks"] = [ track.toDict() for track in tracks ]
payload["tracks"] = [ track.track_id for track in tracks ]
return payload
async def shuffleTrack(player: Player, member: Member, data: dict):

View File

@@ -176,7 +176,7 @@ const actions = {
player.addTrack(data["tracks"]);
var tracks = data["tracks"];
if (tracks.length == 1) {
var msg = `Added ${tracks[0]['info']['title']} songs into the queue.`
var msg = `Added ${decode(tracks[0]).title} songs into the queue.`
} else {
var msg = `Added ${tracks.length} into the queue.`
}
@@ -190,7 +190,7 @@ const actions = {
resultList.empty();
player.searchList = tracks;
for (var i in tracks) {
var track = new Track(tracks[i]);
var track = decode(tracks[i])
resultList.append(`<li class="search-result"><div class="search-result-left"><img src=${track.imageUrl} /><div class="search-result-info"><p class="info">${track.title}</p><p class="desc">${track.author}</p></div></div><p>${player.msToReadableTime(track.length)}</p></li>`)
}
}
@@ -331,18 +331,6 @@ const actions = {
}
class Track {
constructor(object) {
this.title = object["info"]["title"];
this.author = object["info"]["author"];
this.imageUrl = object["thumbnail"];
this.length = object["info"]["length"];
this.track_id = object["track_id"];
this.uri = object["info"]["uri"];
this.source = object["info"]["sourceName"];
}
}
class Player {
constructor(userId) {
this.socket = new Socket(`${window.location.protocol}//${window.location.hostname}:${window.location.port}`);
@@ -427,7 +415,7 @@ class Player {
}
addTrack(tracks) {
for (var i in tracks) {
var track = new Track(tracks[i]);
var track = decode(tracks[i])
this.queue.push(track);
$("#sortable").append(`<li><div class="track"><div class="left">${(this.isDJ) ? '<i class="fa-solid fa-bars handle"></i>' : ''}<img src=${track.imageUrl} /><div class="info"><p>${track.title}</p><p class="desc">${track.author}</p></div></div><p class="time">${this.msToReadableTime(track.length)}</p><i class="fa-solid fa-ellipsis-vertical action"></i></div></li>`)
}