remove all discord deps, there goes some of the code lol
This commit is contained in:
parent
c6c52649c2
commit
079070b362
|
|
@ -6,10 +6,6 @@ from typing import Optional
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from discord import Client
|
|
||||||
from discord import Guild
|
|
||||||
from discord.ext import commands
|
|
||||||
|
|
||||||
from .objects import Track
|
from .objects import Track
|
||||||
from .pool import NodePool
|
from .pool import NodePool
|
||||||
|
|
||||||
|
|
@ -41,9 +37,6 @@ class PomiceEvent(ABC):
|
||||||
name = "event"
|
name = "event"
|
||||||
handler_args: Tuple
|
handler_args: Tuple
|
||||||
|
|
||||||
def dispatch(self, bot: Client) -> None:
|
|
||||||
bot.dispatch(f"pomice_{self.name}", *self.handler_args)
|
|
||||||
|
|
||||||
|
|
||||||
class TrackStartEvent(PomiceEvent):
|
class TrackStartEvent(PomiceEvent):
|
||||||
"""Fired when a track has successfully started.
|
"""Fired when a track has successfully started.
|
||||||
|
|
@ -147,7 +140,7 @@ class WebSocketClosedPayload:
|
||||||
__slots__ = ("guild", "code", "reason", "by_remote")
|
__slots__ = ("guild", "code", "reason", "by_remote")
|
||||||
|
|
||||||
def __init__(self, data: dict):
|
def __init__(self, data: dict):
|
||||||
self.guild: Optional[Guild] = NodePool.get_node().bot.get_guild(int(data["guildId"]))
|
self.guild: int = data["guildId"]
|
||||||
self.code: int = data["code"]
|
self.code: int = data["code"]
|
||||||
self.reason: str = data["code"]
|
self.reason: str = data["code"]
|
||||||
self.by_remote: bool = data["byRemote"]
|
self.by_remote: bool = data["byRemote"]
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
from typing import List
|
from typing import List
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from typing import Union
|
|
||||||
|
|
||||||
from discord import ClientUser
|
|
||||||
from discord import Member
|
|
||||||
from discord import User
|
|
||||||
from discord.ext import commands
|
|
||||||
|
|
||||||
from .enums import PlaylistType
|
from .enums import PlaylistType
|
||||||
from .enums import SearchType
|
from .enums import SearchType
|
||||||
|
|
@ -53,12 +47,10 @@ class Track:
|
||||||
*,
|
*,
|
||||||
track_id: str,
|
track_id: str,
|
||||||
info: dict,
|
info: dict,
|
||||||
ctx: Optional[commands.Context] = None,
|
|
||||||
track_type: TrackType,
|
track_type: TrackType,
|
||||||
search_type: SearchType = SearchType.ytsearch,
|
search_type: SearchType = SearchType.ytsearch,
|
||||||
filters: Optional[List[Filter]] = None,
|
filters: Optional[List[Filter]] = None,
|
||||||
timestamp: Optional[float] = None,
|
timestamp: Optional[float] = None,
|
||||||
requester: Optional[Union[Member, User, ClientUser]] = None,
|
|
||||||
):
|
):
|
||||||
self.track_id: str = track_id
|
self.track_id: str = track_id
|
||||||
self.info: dict = info
|
self.info: dict = info
|
||||||
|
|
@ -89,11 +81,6 @@ class Track:
|
||||||
self.is_seekable: bool = info.get("isSeekable", False)
|
self.is_seekable: bool = info.get("isSeekable", False)
|
||||||
self.position: int = info.get("position", 0)
|
self.position: int = info.get("position", 0)
|
||||||
|
|
||||||
self.ctx: Optional[commands.Context] = ctx
|
|
||||||
self.requester: Optional[Union[Member, User, ClientUser]] = requester
|
|
||||||
if not self.requester and self.ctx:
|
|
||||||
self.requester = self.ctx.author
|
|
||||||
|
|
||||||
def __eq__(self, other: object) -> bool:
|
def __eq__(self, other: object) -> bool:
|
||||||
if not isinstance(other, Track):
|
if not isinstance(other, Track):
|
||||||
return False
|
return False
|
||||||
|
|
|
||||||
113
pomice/player.py
113
pomice/player.py
|
|
@ -5,15 +5,8 @@ from typing import Any
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
from typing import List
|
from typing import List
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
from discord import Client
|
|
||||||
from discord import Guild
|
|
||||||
from discord import VoiceChannel
|
|
||||||
from discord import VoiceProtocol
|
|
||||||
from discord.ext import commands
|
|
||||||
|
|
||||||
from . import events
|
from . import events
|
||||||
from .enums import SearchType
|
from .enums import SearchType
|
||||||
from .events import PomiceEvent
|
from .events import PomiceEvent
|
||||||
|
|
@ -32,9 +25,6 @@ from .pool import Node
|
||||||
from .pool import NodePool
|
from .pool import NodePool
|
||||||
from pomice.utils import LavalinkVersion
|
from pomice.utils import LavalinkVersion
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from discord.types.voice import VoiceServerUpdate
|
|
||||||
from discord.types.voice import GuildVoiceState
|
|
||||||
|
|
||||||
__all__ = ("Filters", "Player")
|
__all__ = ("Filters", "Player")
|
||||||
|
|
||||||
|
|
@ -129,7 +119,7 @@ class Filters:
|
||||||
return self._filters
|
return self._filters
|
||||||
|
|
||||||
|
|
||||||
class Player(VoiceProtocol):
|
class Player:
|
||||||
"""The base player class for Pomice.
|
"""The base player class for Pomice.
|
||||||
In order to initiate a player, you must pass it in as a cls when you connect to a channel.
|
In order to initiate a player, you must pass it in as a cls when you connect to a channel.
|
||||||
i.e: ```py
|
i.e: ```py
|
||||||
|
|
@ -156,25 +146,11 @@ class Player(VoiceProtocol):
|
||||||
"_player_endpoint_uri",
|
"_player_endpoint_uri",
|
||||||
)
|
)
|
||||||
|
|
||||||
def __call__(self, client: Client, channel: VoiceChannel) -> Player:
|
|
||||||
self.client = client
|
|
||||||
self.channel = channel
|
|
||||||
self._guild = channel.guild
|
|
||||||
|
|
||||||
return self
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
client: Client,
|
|
||||||
channel: VoiceChannel,
|
|
||||||
*,
|
*,
|
||||||
node: Optional[Node] = None,
|
node: Optional[Node] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
self.client: Client = client
|
|
||||||
self.channel: VoiceChannel = channel
|
|
||||||
self._guild = channel.guild
|
|
||||||
|
|
||||||
self._bot: Client = client
|
|
||||||
self._node: Node = node if node else NodePool.get_node()
|
self._node: Node = node if node else NodePool.get_node()
|
||||||
self._current: Optional[Track] = None
|
self._current: Optional[Track] = None
|
||||||
self._filters: Filters = Filters()
|
self._filters: Filters = Filters()
|
||||||
|
|
@ -260,11 +236,6 @@ class Player(VoiceProtocol):
|
||||||
"""Property which returns the node the player is connected to"""
|
"""Property which returns the node the player is connected to"""
|
||||||
return self._node
|
return self._node
|
||||||
|
|
||||||
@property
|
|
||||||
def guild(self) -> Guild:
|
|
||||||
"""Property which returns the guild associated with the player"""
|
|
||||||
return self._guild
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def volume(self) -> int:
|
def volume(self) -> int:
|
||||||
"""Property which returns the players current volume"""
|
"""Property which returns the players current volume"""
|
||||||
|
|
@ -276,16 +247,16 @@ class Player(VoiceProtocol):
|
||||||
return self._filters
|
return self._filters
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def bot(self) -> Client:
|
def bot_id(self) -> int:
|
||||||
"""Property which returns the bot associated with this player instance"""
|
"""Property which returns the bot id associated with this player instance"""
|
||||||
return self._bot
|
return self._node._bot_id
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_dead(self) -> bool:
|
def is_dead(self) -> bool:
|
||||||
"""Returns a bool representing whether the player is dead or not.
|
"""Returns a bool representing whether the player is dead or not.
|
||||||
A player is considered dead if it has been destroyed and removed from stored players.
|
A player is considered dead if it has been destroyed and removed from stored players.
|
||||||
"""
|
"""
|
||||||
return self.guild.id not in self._node._players
|
return self not in self._node._players
|
||||||
|
|
||||||
def _adjust_end_time(self) -> Optional[str]:
|
def _adjust_end_time(self) -> Optional[str]:
|
||||||
if self._node._version >= LavalinkVersion(3, 7, 5):
|
if self._node._version >= LavalinkVersion(3, 7, 5):
|
||||||
|
|
@ -321,30 +292,6 @@ class Player(VoiceProtocol):
|
||||||
|
|
||||||
self._log.debug(f"Dispatched voice update to {state['event']['endpoint']} with data {data}")
|
self._log.debug(f"Dispatched voice update to {state['event']['endpoint']} with data {data}")
|
||||||
|
|
||||||
async def on_voice_server_update(self, data: VoiceServerUpdate) -> None:
|
|
||||||
self._voice_state.update({"event": data})
|
|
||||||
await self._dispatch_voice_update(self._voice_state)
|
|
||||||
|
|
||||||
async def on_voice_state_update(self, data: GuildVoiceState) -> None:
|
|
||||||
self._voice_state.update({"sessionId": data.get("session_id")})
|
|
||||||
|
|
||||||
channel_id = data.get("channel_id")
|
|
||||||
if not channel_id:
|
|
||||||
await self.disconnect()
|
|
||||||
self._voice_state.clear()
|
|
||||||
return
|
|
||||||
|
|
||||||
channel = self.guild.get_channel(int(channel_id))
|
|
||||||
if not channel:
|
|
||||||
await self.disconnect()
|
|
||||||
self._voice_state.clear()
|
|
||||||
return
|
|
||||||
|
|
||||||
if not data.get("token"):
|
|
||||||
return
|
|
||||||
|
|
||||||
await self._dispatch_voice_update({**self._voice_state, "event": data})
|
|
||||||
|
|
||||||
async def _dispatch_event(self, data: dict) -> None:
|
async def _dispatch_event(self, data: dict) -> None:
|
||||||
event_type: str = data["type"]
|
event_type: str = data["type"]
|
||||||
event: PomiceEvent = getattr(events, event_type)(data, self)
|
event: PomiceEvent = getattr(events, event_type)(data, self)
|
||||||
|
|
@ -385,7 +332,6 @@ class Player(VoiceProtocol):
|
||||||
self,
|
self,
|
||||||
query: str,
|
query: str,
|
||||||
*,
|
*,
|
||||||
ctx: Optional[commands.Context] = None,
|
|
||||||
search_type: SearchType = SearchType.ytsearch,
|
search_type: SearchType = SearchType.ytsearch,
|
||||||
filters: Optional[List[Filter]] = None,
|
filters: Optional[List[Filter]] = None,
|
||||||
) -> Optional[Union[List[Track], Playlist]]:
|
) -> Optional[Union[List[Track], Playlist]]:
|
||||||
|
|
@ -401,38 +347,22 @@ class Player(VoiceProtocol):
|
||||||
You may also pass in a List of filters
|
You may also pass in a List of filters
|
||||||
to be applied to your track once it plays.
|
to be applied to your track once it plays.
|
||||||
"""
|
"""
|
||||||
return await self._node.get_tracks(query, ctx=ctx, search_type=search_type, filters=filters)
|
return await self._node.get_tracks(query, search_type=search_type, filters=filters)
|
||||||
|
|
||||||
async def build_track(self, identifier: str, ctx: Optional[commands.Context] = None) -> Track:
|
async def build_track(self, identifier: str) -> Track:
|
||||||
"""
|
"""
|
||||||
Builds a track using a valid track identifier
|
Builds a track using a valid track identifier
|
||||||
|
|
||||||
You can also pass in a discord.py Context object to get a
|
|
||||||
Context object on the track it builds.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return await self._node.build_track(identifier, ctx=ctx)
|
return await self._node.build_track(identifier)
|
||||||
|
|
||||||
async def get_recommendations(
|
async def get_recommendations(self, *, track: Track) -> Optional[Union[List[Track], Playlist]]:
|
||||||
self, *, track: Track, ctx: Optional[commands.Context] = None
|
|
||||||
) -> Optional[Union[List[Track], Playlist]]:
|
|
||||||
"""
|
"""
|
||||||
Gets recommendations from either YouTube or Spotify.
|
Gets recommendations from either YouTube or Spotify.
|
||||||
You can pass in a discord.py Context object to get a
|
You can pass in a discord.py Context object to get a
|
||||||
Context object on all tracks that get recommended.
|
Context object on all tracks that get recommended.
|
||||||
"""
|
"""
|
||||||
return await self._node.get_recommendations(track=track, ctx=ctx)
|
return await self._node.get_recommendations(track=track)
|
||||||
|
|
||||||
async def connect(
|
|
||||||
self, *, timeout: float, reconnect: bool, self_deaf: bool = False, self_mute: bool = False
|
|
||||||
) -> None:
|
|
||||||
await self.guild.change_voice_state(
|
|
||||||
channel=self.channel,
|
|
||||||
self_deaf=self_deaf,
|
|
||||||
self_mute=self_mute,
|
|
||||||
)
|
|
||||||
self._node._players[self.guild.id] = self
|
|
||||||
self._is_connected = True
|
|
||||||
|
|
||||||
async def stop(self) -> None:
|
async def stop(self) -> None:
|
||||||
"""Stops the currently playing track."""
|
"""Stops the currently playing track."""
|
||||||
|
|
@ -446,15 +376,6 @@ class Player(VoiceProtocol):
|
||||||
|
|
||||||
self._log.debug(f"Player has been stopped.")
|
self._log.debug(f"Player has been stopped.")
|
||||||
|
|
||||||
async def disconnect(self, *, force: bool = False) -> None:
|
|
||||||
"""Disconnects the player from voice."""
|
|
||||||
try:
|
|
||||||
await self.guild.change_voice_state(channel=None)
|
|
||||||
finally:
|
|
||||||
self.cleanup()
|
|
||||||
self._is_connected = False
|
|
||||||
self.channel = None # type: ignore
|
|
||||||
|
|
||||||
async def destroy(self) -> None:
|
async def destroy(self) -> None:
|
||||||
"""Disconnects and destroys the player, and runs internal cleanup."""
|
"""Disconnects and destroys the player, and runs internal cleanup."""
|
||||||
try:
|
try:
|
||||||
|
|
@ -486,9 +407,7 @@ class Player(VoiceProtocol):
|
||||||
if not track.isrc:
|
if not track.isrc:
|
||||||
# We have to bare raise here because theres no other way to skip this block feasibly
|
# We have to bare raise here because theres no other way to skip this block feasibly
|
||||||
raise
|
raise
|
||||||
search = (
|
search = (await self._node.get_tracks(f"{track._search_type}:{track.isrc}"))[
|
||||||
await self._node.get_tracks(f"{track._search_type}:{track.isrc}", ctx=track.ctx)
|
|
||||||
)[
|
|
||||||
0
|
0
|
||||||
] # type: ignore
|
] # type: ignore
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|
@ -497,7 +416,6 @@ class Player(VoiceProtocol):
|
||||||
search = (
|
search = (
|
||||||
await self._node.get_tracks(
|
await self._node.get_tracks(
|
||||||
f"{track._search_type}:{track.title} - {track.author}",
|
f"{track._search_type}:{track.title} - {track.author}",
|
||||||
ctx=track.ctx,
|
|
||||||
)
|
)
|
||||||
)[
|
)[
|
||||||
0
|
0
|
||||||
|
|
@ -612,15 +530,6 @@ class Player(VoiceProtocol):
|
||||||
self._log.debug(f"Player volume has been adjusted to {volume}")
|
self._log.debug(f"Player volume has been adjusted to {volume}")
|
||||||
return self._volume
|
return self._volume
|
||||||
|
|
||||||
async def move_to(self, channel: VoiceChannel) -> None:
|
|
||||||
"""Moves the player to a new voice channel."""
|
|
||||||
|
|
||||||
await self.guild.change_voice_state(channel=channel)
|
|
||||||
|
|
||||||
self.channel = channel
|
|
||||||
|
|
||||||
await self._dispatch_voice_update()
|
|
||||||
|
|
||||||
async def add_filter(self, _filter: Filter, fast_apply: bool = False) -> Filters:
|
async def add_filter(self, _filter: Filter, fast_apply: bool = False) -> Filters:
|
||||||
"""Adds a filter to the player. Takes a pomice.Filter object.
|
"""Adds a filter to the player. Takes a pomice.Filter object.
|
||||||
This will only work if you are using a version of Lavalink that supports filters.
|
This will only work if you are using a version of Lavalink that supports filters.
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,6 @@ from urllib.parse import quote
|
||||||
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
import orjson as json
|
import orjson as json
|
||||||
from discord import Client
|
|
||||||
from discord.ext import commands
|
|
||||||
from discord.utils import MISSING
|
|
||||||
from websockets import client
|
from websockets import client
|
||||||
from websockets import exceptions
|
from websockets import exceptions
|
||||||
from websockets import typing as wstype
|
from websockets import typing as wstype
|
||||||
|
|
@ -106,7 +103,7 @@ class Node:
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
pool: Type[NodePool],
|
pool: Type[NodePool],
|
||||||
bot: commands.Bot,
|
bot_id: int,
|
||||||
host: str,
|
host: str,
|
||||||
port: int,
|
port: int,
|
||||||
password: str,
|
password: str,
|
||||||
|
|
@ -127,7 +124,7 @@ class Node:
|
||||||
if not isinstance(port, int):
|
if not isinstance(port, int):
|
||||||
raise TypeError("Port must be an integer")
|
raise TypeError("Port must be an integer")
|
||||||
|
|
||||||
self._bot: commands.Bot = bot
|
self._bot_id: int = bot_id
|
||||||
self._host: str = host
|
self._host: str = host
|
||||||
self._port: int = port
|
self._port: int = port
|
||||||
self._pool: Type[NodePool] = pool
|
self._pool: Type[NodePool] = pool
|
||||||
|
|
@ -208,9 +205,9 @@ class Node:
|
||||||
return self._players
|
return self._players
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def bot(self) -> Client:
|
def bot_id(self) -> int:
|
||||||
"""Property which returns the discord.py client linked to this node"""
|
"""Property which returns the bot id linked to this node"""
|
||||||
return self._bot
|
return self._bot_id
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def player_count(self) -> int:
|
def player_count(self) -> int:
|
||||||
|
|
@ -535,7 +532,7 @@ class Node:
|
||||||
f"Successfully disconnected from node {self._identifier} and closed all sessions. Took {end - start:.3f}s",
|
f"Successfully disconnected from node {self._identifier} and closed all sessions. Took {end - start:.3f}s",
|
||||||
)
|
)
|
||||||
|
|
||||||
async def build_track(self, identifier: str, ctx: Optional[commands.Context] = None) -> Track:
|
async def build_track(self, identifier: str = None) -> Track:
|
||||||
"""
|
"""
|
||||||
Builds a track using a valid track identifier
|
Builds a track using a valid track identifier
|
||||||
|
|
||||||
|
|
@ -550,7 +547,6 @@ class Node:
|
||||||
)
|
)
|
||||||
return Track(
|
return Track(
|
||||||
track_id=identifier,
|
track_id=identifier,
|
||||||
ctx=ctx,
|
|
||||||
info=data,
|
info=data,
|
||||||
track_type=TrackType(data["sourceName"]),
|
track_type=TrackType(data["sourceName"]),
|
||||||
)
|
)
|
||||||
|
|
@ -559,7 +555,6 @@ class Node:
|
||||||
self,
|
self,
|
||||||
query: str,
|
query: str,
|
||||||
*,
|
*,
|
||||||
ctx: Optional[commands.Context] = None,
|
|
||||||
search_type: SearchType = SearchType.ytsearch,
|
search_type: SearchType = SearchType.ytsearch,
|
||||||
filters: Optional[List[Filter]] = None,
|
filters: Optional[List[Filter]] = None,
|
||||||
) -> Optional[Union[Playlist, List[Track]]]:
|
) -> Optional[Union[Playlist, List[Track]]]:
|
||||||
|
|
@ -593,7 +588,6 @@ class Node:
|
||||||
return [
|
return [
|
||||||
Track(
|
Track(
|
||||||
track_id=apple_music_results.id,
|
track_id=apple_music_results.id,
|
||||||
ctx=ctx,
|
|
||||||
track_type=TrackType.APPLE_MUSIC,
|
track_type=TrackType.APPLE_MUSIC,
|
||||||
search_type=search_type,
|
search_type=search_type,
|
||||||
filters=filters,
|
filters=filters,
|
||||||
|
|
@ -615,7 +609,6 @@ class Node:
|
||||||
tracks = [
|
tracks = [
|
||||||
Track(
|
Track(
|
||||||
track_id=track.id,
|
track_id=track.id,
|
||||||
ctx=ctx,
|
|
||||||
track_type=TrackType.APPLE_MUSIC,
|
track_type=TrackType.APPLE_MUSIC,
|
||||||
search_type=search_type,
|
search_type=search_type,
|
||||||
filters=filters,
|
filters=filters,
|
||||||
|
|
@ -660,7 +653,6 @@ class Node:
|
||||||
return [
|
return [
|
||||||
Track(
|
Track(
|
||||||
track_id=spotify_results.id,
|
track_id=spotify_results.id,
|
||||||
ctx=ctx,
|
|
||||||
track_type=TrackType.SPOTIFY,
|
track_type=TrackType.SPOTIFY,
|
||||||
search_type=search_type,
|
search_type=search_type,
|
||||||
filters=filters,
|
filters=filters,
|
||||||
|
|
@ -682,7 +674,6 @@ class Node:
|
||||||
tracks = [
|
tracks = [
|
||||||
Track(
|
Track(
|
||||||
track_id=track.id,
|
track_id=track.id,
|
||||||
ctx=ctx,
|
|
||||||
track_type=TrackType.SPOTIFY,
|
track_type=TrackType.SPOTIFY,
|
||||||
search_type=search_type,
|
search_type=search_type,
|
||||||
filters=filters,
|
filters=filters,
|
||||||
|
|
@ -734,7 +725,6 @@ class Node:
|
||||||
"position": info["position"],
|
"position": info["position"],
|
||||||
"identifier": info["identifier"],
|
"identifier": info["identifier"],
|
||||||
},
|
},
|
||||||
ctx=ctx,
|
|
||||||
track_type=TrackType.HTTP,
|
track_type=TrackType.HTTP,
|
||||||
filters=filters,
|
filters=filters,
|
||||||
),
|
),
|
||||||
|
|
@ -762,7 +752,6 @@ class Node:
|
||||||
"position": info["position"],
|
"position": info["position"],
|
||||||
"identifier": info["identifier"],
|
"identifier": info["identifier"],
|
||||||
},
|
},
|
||||||
ctx=ctx,
|
|
||||||
track_type=TrackType.LOCAL,
|
track_type=TrackType.LOCAL,
|
||||||
filters=filters,
|
filters=filters,
|
||||||
),
|
),
|
||||||
|
|
@ -804,7 +793,6 @@ class Node:
|
||||||
Track(
|
Track(
|
||||||
track_id=track["encoded"],
|
track_id=track["encoded"],
|
||||||
info=track["info"],
|
info=track["info"],
|
||||||
ctx=ctx,
|
|
||||||
track_type=TrackType(track["info"]["sourceName"]),
|
track_type=TrackType(track["info"]["sourceName"]),
|
||||||
)
|
)
|
||||||
for track in data["tracks"]
|
for track in data["tracks"]
|
||||||
|
|
@ -822,7 +810,6 @@ class Node:
|
||||||
Track(
|
Track(
|
||||||
track_id=track["encoded"],
|
track_id=track["encoded"],
|
||||||
info=track["info"],
|
info=track["info"],
|
||||||
ctx=ctx,
|
|
||||||
track_type=TrackType(track["info"]["sourceName"]),
|
track_type=TrackType(track["info"]["sourceName"]),
|
||||||
filters=filters,
|
filters=filters,
|
||||||
timestamp=timestamp,
|
timestamp=timestamp,
|
||||||
|
|
@ -835,9 +822,7 @@ class Node:
|
||||||
"There was an error while trying to load this track.",
|
"There was an error while trying to load this track.",
|
||||||
)
|
)
|
||||||
|
|
||||||
async def get_recommendations(
|
async def get_recommendations(self, *, track: Track) -> Optional[Union[List[Track], Playlist]]:
|
||||||
self, *, track: Track, ctx: Optional[commands.Context] = None
|
|
||||||
) -> Optional[Union[List[Track], Playlist]]:
|
|
||||||
"""
|
"""
|
||||||
Gets recommendations from either YouTube or Spotify.
|
Gets recommendations from either YouTube or Spotify.
|
||||||
The track that is passed in must be either from
|
The track that is passed in must be either from
|
||||||
|
|
@ -850,7 +835,6 @@ class Node:
|
||||||
tracks = [
|
tracks = [
|
||||||
Track(
|
Track(
|
||||||
track_id=track.id,
|
track_id=track.id,
|
||||||
ctx=ctx,
|
|
||||||
track_type=TrackType.SPOTIFY,
|
track_type=TrackType.SPOTIFY,
|
||||||
info={
|
info={
|
||||||
"title": track.name,
|
"title": track.name,
|
||||||
|
|
@ -873,7 +857,6 @@ class Node:
|
||||||
elif track.track_type == TrackType.YOUTUBE:
|
elif track.track_type == TrackType.YOUTUBE:
|
||||||
return await self.get_tracks(
|
return await self.get_tracks(
|
||||||
query=f"ytsearch:https://www.youtube.com/watch?v={track.identifier}&list=RD{track.identifier}",
|
query=f"ytsearch:https://www.youtube.com/watch?v={track.identifier}&list=RD{track.identifier}",
|
||||||
ctx=ctx,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
@ -956,7 +939,7 @@ class NodePool:
|
||||||
async def create_node(
|
async def create_node(
|
||||||
cls,
|
cls,
|
||||||
*,
|
*,
|
||||||
bot: commands.Bot,
|
bot_id: int,
|
||||||
host: str,
|
host: str,
|
||||||
port: int,
|
port: int,
|
||||||
password: str,
|
password: str,
|
||||||
|
|
@ -984,7 +967,7 @@ class NodePool:
|
||||||
|
|
||||||
node = Node(
|
node = Node(
|
||||||
pool=cls,
|
pool=cls,
|
||||||
bot=bot,
|
bot_id=bot_id,
|
||||||
host=host,
|
host=host,
|
||||||
port=port,
|
port=port,
|
||||||
password=password,
|
password=password,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue