From c1a9d7603f412dd81e21a6b70f084c15fd2187cf Mon Sep 17 00:00:00 2001 From: cloudwithax Date: Sun, 5 Feb 2023 13:27:43 -0500 Subject: [PATCH] manually sync out of date changes into v2 --- examples/advanced.py | 29 +++++++++--------- pomice/objects.py | 13 ++++++-- pomice/player.py | 12 +++++--- pomice/pool.py | 62 +++++++++++++++++++++++++++++++++++++-- pomice/queue.py | 8 ++--- pomice/spotify/client.py | 30 ++++++++++++++++++- pomice/spotify/objects.py | 6 ++-- 7 files changed, 128 insertions(+), 32 deletions(-) diff --git a/examples/advanced.py b/examples/advanced.py index 85350fe..8945cfe 100644 --- a/examples/advanced.py +++ b/examples/advanced.py @@ -7,9 +7,7 @@ from a queue system, advanced queue control and more. import discord import pomice -import asyncio import math -import random from discord.ext import commands from contextlib import suppress @@ -21,7 +19,7 @@ class Player(pomice.Player): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.queue = asyncio.Queue() + self.queue = pomice.Queue() self.controller: discord.Message = None # Set context here so we can send a now playing embed self.context: commands.Context = None @@ -49,8 +47,8 @@ class Player(pomice.Player): # Queue up the next track, else teardown the player try: - track: pomice.Track = self.queue.get_nowait() - except asyncio.queues.QueueEmpty: + track: pomice.Track = self.queue.get() + except pomice.QueueEmpty: return await self.teardown() await self.play(track) @@ -143,7 +141,7 @@ class Music(commands.Cog): async def on_pomice_track_exception(self, player: Player, track, _): await player.do_next() - @commands.command(aliases=['join', 'joi', 'j', 'summon', 'su', 'con']) + @commands.command(aliases=['joi', 'j', 'summon', 'su', 'con', 'connect']) async def join(self, ctx: commands.Context, *, channel: discord.VoiceChannel = None) -> None: if not channel: channel = getattr(ctx.author.voice, "channel", None) @@ -157,7 +155,7 @@ class Music(commands.Cog): player: Player = ctx.voice_client # Set the player context so we can use it so send messages - player.set_context(ctx=ctx) + await player.set_context(ctx=ctx) await ctx.send(f"Joined the voice channel `{channel.name}`") @commands.command(aliases=['disconnect', 'dc', 'disc', 'lv', 'fuckoff']) @@ -172,7 +170,9 @@ class Music(commands.Cog): async def play(self, ctx: commands.Context, *, search: str) -> None: # Checks if the player is in the channel before we play anything if not (player := ctx.voice_client): - await ctx.invoke(self.join) + await ctx.author.voice.channel.connect(cls=Player) + player: Player = ctx.voice_client + await player.set_context(ctx=ctx) # If you search a keyword, Pomice will automagically search the result using YouTube # You can pass in "search_type=" as an argument to change the search type @@ -187,10 +187,10 @@ class Music(commands.Cog): if isinstance(results, pomice.Playlist): for track in results.tracks: - await player.queue.put(track) + player.queue.put(track) else: track = results[0] - await player.queue.put(track) + player.queue.put(track) if not player.is_playing: await player.do_next() @@ -315,7 +315,7 @@ class Music(commands.Cog): if self.is_privileged(ctx): await ctx.send('An admin or DJ has shuffled the queue.', delete_after=10) player.shuffle_votes.clear() - return random.shuffle(player.queue._queue) + return player.queue.shuffle() required = self.required(ctx) player.shuffle_votes.add(ctx.author) @@ -323,7 +323,7 @@ class Music(commands.Cog): if len(player.shuffle_votes) >= required: await ctx.send('Vote to shuffle passed. Shuffling the queue.', delete_after=10) player.shuffle_votes.clear() - random.shuffle(player.queue._queue) + player.queue.shuffle() else: await ctx.send(f'{ctx.author.mention} has voted to shuffle the queue. Votes: {len(player.shuffle_votes)}/{required}', delete_after=15) @@ -348,7 +348,6 @@ class Music(commands.Cog): -def setup(bot: commands.Bot): - bot.add_cog(Music(bot)) - +async def setup(bot: commands.Bot): + await bot.add_cog(Music(bot)) diff --git a/pomice/objects.py b/pomice/objects.py index d84478f..191a282 100644 --- a/pomice/objects.py +++ b/pomice/objects.py @@ -1,5 +1,6 @@ import re -from typing import List, Optional +from typing import List, Optional, Union +from discord import Member, User from discord.ext import commands @@ -25,12 +26,15 @@ class Track: spotify: bool = False, search_type: SearchType = SearchType.ytsearch, spotify_track = None, - filters: Optional[List[Filter]] = None + filters: Optional[List[Filter]] = None, + timestamp: Optional[float] = None, + requester: Optional[Union[Member, User]] = None ): self.track_id = track_id self.info = info self.spotify = spotify self.filters: List[Filter] = filters + self.timestamp: Optional[float] = timestamp self.original: Optional[Track] = None if spotify else self self._search_type = search_type @@ -54,7 +58,10 @@ class Track: self.length = info.get("length") self.ctx = ctx - self.requester = self.ctx.author if ctx else None + if requester: + self.requester = requester + else: + self.requester = self.ctx.author if ctx else None self.is_stream = info.get("isStream") self.is_seekable = info.get("isSeekable") self.position = info.get("position") diff --git a/pomice/player.py b/pomice/player.py index 0bdca30..c335c24 100644 --- a/pomice/player.py +++ b/pomice/player.py @@ -33,10 +33,6 @@ class Filters: """Property which checks if any applied filters were preloaded""" return any(f for f in self._filters if f.preload == True) - @property - def has_global(self): - """Property which checks if any applied filters are global""" - return any(f for f in self._filters if f.preload == False) @property def empty(self): @@ -284,6 +280,14 @@ class Player(VoiceProtocol): """ return await self._node.get_tracks(query, ctx=ctx, search_type=search_type, filters=filters) + async def get_recommendations(self, *, query: str, ctx: Optional[commands.Context] = None): + """ + Gets recommendations from Spotify. Query must be a valid Spotify Track URL. + You can pass in a discord.py Context object to get a + Context object on all tracks that get recommended. + """ + return await self._node.get_recommendations(query=query, ctx=ctx) + async def connect(self, *, timeout: float, reconnect: bool, self_deaf: bool = False, self_mute: bool = False): await self.guild.change_voice_state(channel=self.channel, self_deaf=self_deaf, self_mute=self_mute) self._node._players[self.guild.id] = self diff --git a/pomice/pool.py b/pomice/pool.py index 07bfe35..3ed5195 100644 --- a/pomice/pool.py +++ b/pomice/pool.py @@ -48,6 +48,14 @@ DISCORD_MP3_URL_REGEX = re.compile( r"(?P[0-9]+)/(?P[a-zA-Z0-9_.]+)+" ) +YOUTUBE_PLAYLIST_REGEX = re.compile( + r"(?P