From ad53028ac7dc0616a49d487a2071712ebce0e1ca Mon Sep 17 00:00:00 2001 From: cloudwithax Date: Sun, 3 Oct 2021 12:05:20 -0400 Subject: [PATCH] Fixed bugs related to Spotify track queueing and searching --- pomice/node.py | 17 ++++++++++------- pomice/objects.py | 11 ++++++++--- pomice/player.py | 8 +++++--- pomice/pool.py | 2 +- pomice/spotify/models/base.py | 4 ---- 5 files changed, 24 insertions(+), 18 deletions(-) diff --git a/pomice/node.py b/pomice/node.py index cf9df77..d1a4186 100644 --- a/pomice/node.py +++ b/pomice/node.py @@ -221,15 +221,16 @@ class Node: search_tracks = await results.get_all_tracks() tracks = [ objects.Track( - track_id='spotify', + track_id=track.id, ctx=ctx, + spotify=True, info={'title': track.name or 'Unknown', 'author': ', '.join(artist.name for artist in track.artists) or 'Unknown', 'length': track.duration or 0, 'identifier': track.id or 'Unknown', 'uri': track.url or 'spotify', 'isStream': False, 'isSeekable': False, 'position': 0, 'thumbnail': track.images[0].url if track.images else None}, ) for track in search_tracks ] - return objects.Playlist(playlist_info={"name": results.name, "selectedTrack": search_tracks[0]}, tracks=tracks, ctx=ctx) + return objects.Playlist(playlist_info={"name": results.name, "selectedTrack": tracks[0]}, tracks=tracks, ctx=ctx, spotify=True) except: raise exceptions.SpotifyPlaylistLoadFailed(f"Unable to find results for {query}") elif search_type == "album": @@ -238,8 +239,9 @@ class Node: search_tracks = await results.get_all_tracks() tracks = [ objects.Track( - track_id='spotify', + track_id=track.id, ctx=ctx, + spotify=True, info={'title': track.name or 'Unknown', 'author': ', '.join(artist.name for artist in track.artists) or 'Unknown', 'length': track.duration or 0, 'identifier': track.id or 'Unknown', 'uri': track.url or 'spotify', 'isStream': False, 'isSeekable': False, 'position': 0, 'thumbnail': track.images[0].url if track.images else None}, @@ -247,18 +249,19 @@ class Node: ) for track in search_tracks ] - return objects.Playlist(playlist_info={"name": results.name, "selectedTrack": search_tracks[0]}, tracks=tracks, ctx=ctx) + return objects.Playlist(playlist_info={"name": results.name, "selectedTrack": tracks[0]}, tracks=tracks, ctx=ctx, spotify=True) except: raise exceptions.SpotifyAlbumLoadFailed(f"Unable to find results for {query}") elif search_type == 'track': try: results: spotify.Track = await self._spotify_client.get_track(spotify_id=spotify_id) - return objects.Track( - track_id='spotify', + return [objects.Track( + track_id=results.id, ctx=ctx, + spotify=True, info={'title': results.name or 'Unknown', 'author': ', '.join(artist.name for artist in results.artists) or 'Unknown', 'length': results.duration or 0, 'identifier': results.id or 'Unknown', 'uri': results.url or 'spotify', - 'isStream': False, 'isSeekable': False, 'position': 0, 'thumbnail': results.images[0].url if results.images else None},) + 'isStream': False, 'isSeekable': False, 'position': 0, 'thumbnail': results.images[0].url if results.images else None},)] except: raise exceptions.SpotifyTrackLoadFailed(f"Unable to find results for {query}") diff --git a/pomice/objects.py b/pomice/objects.py index 96e5856..f42b63c 100644 --- a/pomice/objects.py +++ b/pomice/objects.py @@ -6,10 +6,11 @@ class Track: You can also pass in commands.Context to get a discord.py Context object by passing in a valid Context object when you search for a track. """ - def __init__(self, track_id: str, info: dict, ctx: commands.Context = None): + def __init__(self, track_id: str, info: dict, ctx: commands.Context = None, spotify: bool = False): self.track_id = track_id self.info = info + self.spotify = spotify self.title = info.get("title") self.author = info.get("author") @@ -36,15 +37,19 @@ class Playlist: You can also pass in commands.Context to get a discord.py Context object by passing in a valid Context object when you search for a track. """ - def __init__(self, playlist_info: dict, tracks: list, ctx: commands.Context = None): + def __init__(self, playlist_info: dict, tracks: list, ctx: commands.Context = None, spotify: bool = False): self.playlist_info = playlist_info self.tracks_raw = tracks + self.spotify = spotify self.name = playlist_info.get("name") self.selected_track = playlist_info.get("selectedTrack") - self.tracks = [Track(track_id=track["track"], info=track["info"], ctx=ctx) for track in self.tracks_raw] + if self.spotify == True: + self.tracks = tracks + else: + self.tracks = [Track(track_id=track["track"], info=track["info"], ctx=ctx) for track in self.tracks_raw] def __str__(self): diff --git a/pomice/player.py b/pomice/player.py index 233a08c..6b2c660 100644 --- a/pomice/player.py +++ b/pomice/player.py @@ -168,9 +168,11 @@ class Player(VoiceProtocol): async def play(self, track: objects.Track, start_position: int = 0): """Plays a track. If a Spotify track is passed in, it will be handled accordingly.""" - if track.track_id == "spotify": - track: objects.Track = await self._node.get_tracks(f"{track.title} {track.author}") - await self._node.send(op='play', guildId=str(self._guild.id), track=track.track_id, startTime=start_position, endTime=track.length, noReplace=False) + if track.spotify == True: + spotify_track: objects.Track = await self._node.get_tracks(f"ytmsearch:{track.title} {track.author} audio") + await self._node.send(op='play', guildId=str(self._guild.id), track=spotify_track[0].track_id, startTime=start_position, endTime=spotify_track[0].length, noReplace=False) + else: + await self._node.send(op='play', guildId=str(self._guild.id), track=track.track_id, startTime=start_position, endTime=track.length, noReplace=False) self._current = track return self._current diff --git a/pomice/pool.py b/pomice/pool.py index 0796307..9dc650c 100644 --- a/pomice/pool.py +++ b/pomice/pool.py @@ -36,7 +36,7 @@ class NodePool: return available_nodes.get(identifier, None) @classmethod - async def create_node(self, bot: typing.Union[commands.Bot, discord.Client, commands.AutoShardedBot, discord.AutoShardedClient], host: str, port: str, password: str, identifier: str, spotify_client_id: Optional[str], spotify_client_secret: Optional[str]) -> Node: + async def create_node(self, bot: typing.Union[commands.Bot, discord.Client, commands.AutoShardedBot, discord.AutoShardedClient], host: str, port: str, password: str, identifier: str, spotify_client_id: Optional[str] = None, spotify_client_secret: Optional[str] = None) -> Node: """Creates a Node object to be then added into the node pool. If you like to have Spotify searching capabilites, pass in valid Spotify API credentials.""" if identifier in self._nodes.keys(): raise exceptions.NodeCreationError(f"A node with identifier '{identifier}' already exists.") diff --git a/pomice/spotify/models/base.py b/pomice/spotify/models/base.py index 5347b9e..4068d5c 100644 --- a/pomice/spotify/models/base.py +++ b/pomice/spotify/models/base.py @@ -17,10 +17,6 @@ class SpotifyBase: __slots__ = () def __new__(cls, client, *_, **__): - if not isinstance(client, spotify.Client): - raise TypeError( - f"{cls!r}: expected client argument to be an instance of `spotify.Client`. Instead got {type(client)}" - ) if hasattr(client, "__client_thread__"): cls = getattr( # pylint: disable=self-cls-assignment