From 2be0284e1a2308cbd37ae9cb564641ee6f40b868 Mon Sep 17 00:00:00 2001 From: 1Example <68064118+1Example@users.noreply.github.com> Date: Wed, 4 Mar 2026 16:22:06 +0200 Subject: [PATCH 01/12] Update PyLav version specification to use GitHub URL Signed-off-by: 1Example <68064118+1Example@users.noreply.github.com> --- tools/dependency_updater.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/dependency_updater.py b/tools/dependency_updater.py index b03efb8c0..b28fcafcb 100644 --- a/tools/dependency_updater.py +++ b/tools/dependency_updater.py @@ -17,7 +17,7 @@ print(f"PyLav max version: {pylav_threshold_version}") -new_pylav_version = f"Py-Lav[all]>={__PYLAV_VERSION__},<{pylav_threshold_version}" +new_pylav_version = "Py-Lav[all] @ git+https://github.com/1Example/PyLav@main" print(f"New PyLav version range: {new_pylav_version}") From 841f6c508fcb2ff314ac43ac1b5f54b226add1cb Mon Sep 17 00:00:00 2001 From: 1Example <68064118+1Example@users.noreply.github.com> Date: Wed, 4 Mar 2026 16:24:23 +0200 Subject: [PATCH 02/12] Point PyLav dependency to patched fork --- audio/info.json | 2 +- plconfig/info.json | 2 +- plcontroller/info.json | 2 +- pleffects/info.json | 2 +- pllocal/info.json | 2 +- pllyrics/info.json | 2 +- plmanagednode/info.json | 2 +- plmigrator/info.json | 2 +- plnodes/info.json | 2 +- plnotifier/info.json | 2 +- plplaylists/info.json | 2 +- plradio/info.json | 2 +- plutils/info.json | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/audio/info.json b/audio/info.json index 75b376994..b2711b100 100644 --- a/audio/info.json +++ b/audio/info.json @@ -20,7 +20,7 @@ ], "required_cogs": {}, "requirements": [ - "Py-Lav[all]>=1.15.14,<1.16" + "Py-Lav[all] @ git+https://github.com/1Example/PyLav@main" ], "short": "A media player cog", "tags": [ diff --git a/plconfig/info.json b/plconfig/info.json index 6207f1bb3..c3eef74bf 100644 --- a/plconfig/info.json +++ b/plconfig/info.json @@ -20,7 +20,7 @@ ], "required_cogs": {}, "requirements": [ - "Py-Lav[all]>=1.15.14,<1.16" + "Py-Lav[all] @ git+https://github.com/1Example/PyLav@main" ], "short": "Configure PyLav's global settings.", "tags": [ diff --git a/plcontroller/info.json b/plcontroller/info.json index f4b3859b6..40632e284 100644 --- a/plcontroller/info.json +++ b/plcontroller/info.json @@ -20,7 +20,7 @@ ], "required_cogs": {}, "requirements": [ - "Py-Lav[all]>=1.15.14,<1.16" + "Py-Lav[all] @ git+https://github.com/1Example/PyLav@main" ], "short": "A media player cog", "tags": [ diff --git a/pleffects/info.json b/pleffects/info.json index 0c869a3e2..559d95727 100644 --- a/pleffects/info.json +++ b/pleffects/info.json @@ -20,7 +20,7 @@ ], "required_cogs": {}, "requirements": [ - "Py-Lav[all]>=1.15.14,<1.16" + "Py-Lav[all] @ git+https://github.com/1Example/PyLav@main" ], "short": "Commands to manage and apply effects to the players.", "tags": [ diff --git a/pllocal/info.json b/pllocal/info.json index 6f535d3a3..5b0b586d3 100644 --- a/pllocal/info.json +++ b/pllocal/info.json @@ -20,7 +20,7 @@ ], "required_cogs": {}, "requirements": [ - "Py-Lav[all]>=1.15.14,<1.16" + "Py-Lav[all] @ git+https://github.com/1Example/PyLav@main" ], "short": "Commands to interact with local media files.", "tags": [ diff --git a/pllyrics/info.json b/pllyrics/info.json index 32d756b0a..76bdc4502 100644 --- a/pllyrics/info.json +++ b/pllyrics/info.json @@ -20,7 +20,7 @@ ], "required_cogs": {}, "requirements": [ - "Py-Lav[all]>=1.15.14,<1.16" + "Py-Lav[all] @ git+https://github.com/1Example/PyLav@main" ], "short": "Get lyric for songs.", "tags": [ diff --git a/plmanagednode/info.json b/plmanagednode/info.json index f92f9d2ee..5183a6332 100644 --- a/plmanagednode/info.json +++ b/plmanagednode/info.json @@ -20,7 +20,7 @@ ], "required_cogs": {}, "requirements": [ - "Py-Lav[all]>=1.15.14,<1.16" + "Py-Lav[all] @ git+https://github.com/1Example/PyLav@main" ], "short": "Commands to configure Pylav's managed node.", "tags": [ diff --git a/plmigrator/info.json b/plmigrator/info.json index 218124161..8d54bdcd1 100644 --- a/plmigrator/info.json +++ b/plmigrator/info.json @@ -18,7 +18,7 @@ "permissions": [], "required_cogs": {}, "requirements": [ - "Py-Lav[all]>=1.15.14,<1.16" + "Py-Lav[all] @ git+https://github.com/1Example/PyLav@main" ], "short": "Convert your Audio settings to PyLav.", "tags": [ diff --git a/plnodes/info.json b/plnodes/info.json index bc7921457..a9d818d33 100644 --- a/plnodes/info.json +++ b/plnodes/info.json @@ -20,7 +20,7 @@ ], "required_cogs": {}, "requirements": [ - "Py-Lav[all]>=1.15.14,<1.16" + "Py-Lav[all] @ git+https://github.com/1Example/PyLav@main" ], "short": "A collection of node controller commands for PyLav.", "tags": [ diff --git a/plnotifier/info.json b/plnotifier/info.json index f8aa1c39b..3ab06f76d 100644 --- a/plnotifier/info.json +++ b/plnotifier/info.json @@ -20,7 +20,7 @@ ], "required_cogs": {}, "requirements": [ - "Py-Lav[all]>=1.15.14,<1.16" + "Py-Lav[all] @ git+https://github.com/1Example/PyLav@main" ], "short": "Configure PyLav's notifications.", "tags": [ diff --git a/plplaylists/info.json b/plplaylists/info.json index 9c29e9a1a..cf88b0419 100644 --- a/plplaylists/info.json +++ b/plplaylists/info.json @@ -20,7 +20,7 @@ ], "required_cogs": {}, "requirements": [ - "Py-Lav[all]>=1.15.14,<1.16" + "Py-Lav[all] @ git+https://github.com/1Example/PyLav@main" ], "short": "Control Playlists from PyLav", "tags": [ diff --git a/plradio/info.json b/plradio/info.json index 33d19e14e..fda901fca 100644 --- a/plradio/info.json +++ b/plradio/info.json @@ -20,7 +20,7 @@ ], "required_cogs": {}, "requirements": [ - "Py-Lav[all]>=1.15.14,<1.16" + "Py-Lav[all] @ git+https://github.com/1Example/PyLav@main" ], "short": "Apply some equalizer presets to the PyLav player.", "tags": [ diff --git a/plutils/info.json b/plutils/info.json index 5962a91d1..df5338097 100644 --- a/plutils/info.json +++ b/plutils/info.json @@ -20,7 +20,7 @@ ], "required_cogs": {}, "requirements": [ - "Py-Lav[all]>=1.15.14,<1.16" + "Py-Lav[all] @ git+https://github.com/1Example/PyLav@main" ], "short": "A bunch of utility commands for PyLav cogs.", "tags": [ From 9c1c431bf585b5372f6d18d3e36a02cc82d83939 Mon Sep 17 00:00:00 2001 From: 1Example <68064118+1Example@users.noreply.github.com> Date: Wed, 4 Mar 2026 16:39:41 +0200 Subject: [PATCH 03/12] Update PyLav version source from main to develop Signed-off-by: 1Example <68064118+1Example@users.noreply.github.com> --- tools/dependency_updater.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/dependency_updater.py b/tools/dependency_updater.py index b28fcafcb..25d110a10 100644 --- a/tools/dependency_updater.py +++ b/tools/dependency_updater.py @@ -17,7 +17,7 @@ print(f"PyLav max version: {pylav_threshold_version}") -new_pylav_version = "Py-Lav[all] @ git+https://github.com/1Example/PyLav@main" +new_pylav_version = "Py-Lav[all] @ git+https://github.com/1Example/PyLav@develop" print(f"New PyLav version range: {new_pylav_version}") From 2b88abf85b460f23e3a0addfc01d2d76e2a5185b Mon Sep 17 00:00:00 2001 From: 1Example <68064118+1Example@users.noreply.github.com> Date: Wed, 4 Mar 2026 16:42:37 +0200 Subject: [PATCH 04/12] Point PyLav dependency to patched fork --- audio/info.json | 2 +- plconfig/info.json | 2 +- plcontroller/info.json | 2 +- pleffects/info.json | 2 +- pllocal/info.json | 2 +- pllyrics/info.json | 2 +- plmanagednode/info.json | 2 +- plmigrator/info.json | 2 +- plnodes/info.json | 2 +- plnotifier/info.json | 2 +- plplaylists/info.json | 2 +- plradio/info.json | 2 +- plutils/info.json | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/audio/info.json b/audio/info.json index b2711b100..474181161 100644 --- a/audio/info.json +++ b/audio/info.json @@ -20,7 +20,7 @@ ], "required_cogs": {}, "requirements": [ - "Py-Lav[all] @ git+https://github.com/1Example/PyLav@main" + "Py-Lav[all] @ git+https://github.com/1Example/PyLav@develop" ], "short": "A media player cog", "tags": [ diff --git a/plconfig/info.json b/plconfig/info.json index c3eef74bf..afcbb5727 100644 --- a/plconfig/info.json +++ b/plconfig/info.json @@ -20,7 +20,7 @@ ], "required_cogs": {}, "requirements": [ - "Py-Lav[all] @ git+https://github.com/1Example/PyLav@main" + "Py-Lav[all] @ git+https://github.com/1Example/PyLav@develop" ], "short": "Configure PyLav's global settings.", "tags": [ diff --git a/plcontroller/info.json b/plcontroller/info.json index 40632e284..e73dc2ee2 100644 --- a/plcontroller/info.json +++ b/plcontroller/info.json @@ -20,7 +20,7 @@ ], "required_cogs": {}, "requirements": [ - "Py-Lav[all] @ git+https://github.com/1Example/PyLav@main" + "Py-Lav[all] @ git+https://github.com/1Example/PyLav@develop" ], "short": "A media player cog", "tags": [ diff --git a/pleffects/info.json b/pleffects/info.json index 559d95727..c4dd9233d 100644 --- a/pleffects/info.json +++ b/pleffects/info.json @@ -20,7 +20,7 @@ ], "required_cogs": {}, "requirements": [ - "Py-Lav[all] @ git+https://github.com/1Example/PyLav@main" + "Py-Lav[all] @ git+https://github.com/1Example/PyLav@develop" ], "short": "Commands to manage and apply effects to the players.", "tags": [ diff --git a/pllocal/info.json b/pllocal/info.json index 5b0b586d3..3410ee919 100644 --- a/pllocal/info.json +++ b/pllocal/info.json @@ -20,7 +20,7 @@ ], "required_cogs": {}, "requirements": [ - "Py-Lav[all] @ git+https://github.com/1Example/PyLav@main" + "Py-Lav[all] @ git+https://github.com/1Example/PyLav@develop" ], "short": "Commands to interact with local media files.", "tags": [ diff --git a/pllyrics/info.json b/pllyrics/info.json index 76bdc4502..bac1f83ec 100644 --- a/pllyrics/info.json +++ b/pllyrics/info.json @@ -20,7 +20,7 @@ ], "required_cogs": {}, "requirements": [ - "Py-Lav[all] @ git+https://github.com/1Example/PyLav@main" + "Py-Lav[all] @ git+https://github.com/1Example/PyLav@develop" ], "short": "Get lyric for songs.", "tags": [ diff --git a/plmanagednode/info.json b/plmanagednode/info.json index 5183a6332..fcf171f0d 100644 --- a/plmanagednode/info.json +++ b/plmanagednode/info.json @@ -20,7 +20,7 @@ ], "required_cogs": {}, "requirements": [ - "Py-Lav[all] @ git+https://github.com/1Example/PyLav@main" + "Py-Lav[all] @ git+https://github.com/1Example/PyLav@develop" ], "short": "Commands to configure Pylav's managed node.", "tags": [ diff --git a/plmigrator/info.json b/plmigrator/info.json index 8d54bdcd1..f14683a21 100644 --- a/plmigrator/info.json +++ b/plmigrator/info.json @@ -18,7 +18,7 @@ "permissions": [], "required_cogs": {}, "requirements": [ - "Py-Lav[all] @ git+https://github.com/1Example/PyLav@main" + "Py-Lav[all] @ git+https://github.com/1Example/PyLav@develop" ], "short": "Convert your Audio settings to PyLav.", "tags": [ diff --git a/plnodes/info.json b/plnodes/info.json index a9d818d33..3c2ef08d6 100644 --- a/plnodes/info.json +++ b/plnodes/info.json @@ -20,7 +20,7 @@ ], "required_cogs": {}, "requirements": [ - "Py-Lav[all] @ git+https://github.com/1Example/PyLav@main" + "Py-Lav[all] @ git+https://github.com/1Example/PyLav@develop" ], "short": "A collection of node controller commands for PyLav.", "tags": [ diff --git a/plnotifier/info.json b/plnotifier/info.json index 3ab06f76d..dbd419a1b 100644 --- a/plnotifier/info.json +++ b/plnotifier/info.json @@ -20,7 +20,7 @@ ], "required_cogs": {}, "requirements": [ - "Py-Lav[all] @ git+https://github.com/1Example/PyLav@main" + "Py-Lav[all] @ git+https://github.com/1Example/PyLav@develop" ], "short": "Configure PyLav's notifications.", "tags": [ diff --git a/plplaylists/info.json b/plplaylists/info.json index cf88b0419..5234be155 100644 --- a/plplaylists/info.json +++ b/plplaylists/info.json @@ -20,7 +20,7 @@ ], "required_cogs": {}, "requirements": [ - "Py-Lav[all] @ git+https://github.com/1Example/PyLav@main" + "Py-Lav[all] @ git+https://github.com/1Example/PyLav@develop" ], "short": "Control Playlists from PyLav", "tags": [ diff --git a/plradio/info.json b/plradio/info.json index fda901fca..2824cd846 100644 --- a/plradio/info.json +++ b/plradio/info.json @@ -20,7 +20,7 @@ ], "required_cogs": {}, "requirements": [ - "Py-Lav[all] @ git+https://github.com/1Example/PyLav@main" + "Py-Lav[all] @ git+https://github.com/1Example/PyLav@develop" ], "short": "Apply some equalizer presets to the PyLav player.", "tags": [ diff --git a/plutils/info.json b/plutils/info.json index df5338097..63dbc8ae8 100644 --- a/plutils/info.json +++ b/plutils/info.json @@ -20,7 +20,7 @@ ], "required_cogs": {}, "requirements": [ - "Py-Lav[all] @ git+https://github.com/1Example/PyLav@main" + "Py-Lav[all] @ git+https://github.com/1Example/PyLav@develop" ], "short": "A bunch of utility commands for PyLav cogs.", "tags": [ From e932d9846f1e652e8be72917f946e9e2b77bff75 Mon Sep 17 00:00:00 2001 From: 1Example <68064118+1Example@users.noreply.github.com> Date: Wed, 4 Mar 2026 21:26:48 +0200 Subject: [PATCH 05/12] Add command to append URL or song to a playlist Signed-off-by: 1Example <68064118+1Example@users.noreply.github.com> --- plplaylists/cog.py | 108 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/plplaylists/cog.py b/plplaylists/cog.py index eacf53771..c3c9180a1 100644 --- a/plplaylists/cog.py +++ b/plplaylists/cog.py @@ -844,6 +844,114 @@ async def slash_playlist_upload(self, interaction: DISCORD_INTERACTION_TYPE, url ephemeral=True, ) + @slash_playlist.command(name="append", description=shorten_string(max_length=100, string=_("Append a URL or song to a playlist"))) + @app_commands.describe( + playlist=shorten_string(max_length=100, string=_("The playlist to append to")), + url=shorten_string( + max_length=100, + string=_( + "URL to append - any direct link including radio streams e.g. https://radio.example.com/stream" + ), + ), + ) + @app_commands.guild_only() + async def slash_playlist_append( + self, interaction: DISCORD_INTERACTION_TYPE, playlist: PlaylistConverter, url: str + ): + if not interaction.response.is_done(): + await interaction.response.defer(ephemeral=True) + context = await self.bot.get_context(interaction) + + playlists: list[Playlist] = playlist + playlist = await maybe_prompt_for_playlist(cog=self, playlists=playlists, context=context) + if not playlist: + return + + if playlist.id not in BUNDLED_PLAYLIST_IDS: + manageable = await playlist.can_manage(bot=self.bot, requester=context.author) + else: + manageable = False + + if not manageable: + await context.send( + embed=await context.pylav.construct_embed( + messageable=context, + description=_( + "{user_variable_do_not_translate}, playlist {playlist_name_variable_do_not_translate} cannot be managed by yourself." + ).format( + user_variable_do_not_translate=context.author.mention, + playlist_name_variable_do_not_translate=await playlist.get_name_formatted(with_url=True), + ), + ), + ephemeral=True, + ) + return + + url = url.strip("<>").strip() + query = await Query.from_string(url) + response = await context.pylav.get_tracks(query, player=context.player) + + if response is None: + await context.send( + embed=await context.pylav.construct_embed( + messageable=context, + description=_( + "Could not resolve `{url_variable_do_not_translate}` - no capable node is available. " + "Make sure your Lavalink node supports this source." + ).format(url_variable_do_not_translate=url), + ), + ephemeral=True, + ) + return + + match response.loadType: + case "track": + tracks = [response.data] + case "search": + tracks = list(response.data) + case "playlist": + tracks = list(response.data.tracks) + case _: + tracks = [] + + if not tracks: + await context.send( + embed=await context.pylav.construct_embed( + messageable=context, + description=_( + "No tracks were found for `{url_variable_do_not_translate}`. " + "The URL may be invalid or unsupported." + ).format(url_variable_do_not_translate=url), + ), + ephemeral=True, + ) + return + + await playlist.add_track(list(tracks)) + count = len(tracks) + match count: + case 1: + added_msg = _("1 track was added to the playlist.") + case __: + added_msg = _( + "{track_count_variable_do_not_translate} tracks were added to the playlist." + ).format(track_count_variable_do_not_translate=count) + + await context.send( + embed=await context.pylav.construct_embed( + messageable=context, + title=_("Playlist updated"), + description=_( + "{user_variable_do_not_translate}, playlist {playlist_name_variable_do_not_translate} has been updated.\n{added_variable_do_not_translate}" + ).format( + user_variable_do_not_translate=context.author.mention, + playlist_name_variable_do_not_translate=await playlist.get_name_formatted(with_url=True), + added_variable_do_not_translate=added_msg, + ), + ), + ephemeral=True, + ) + @slash_playlist.command(name="mix", description=_("Play a YouTube mix playlist from a input")) @app_commands.describe( video=_("The YouTube video ID to play a mix from"), From 9dccffe218249c7916e127a95b2a1d92019dd44d Mon Sep 17 00:00:00 2001 From: 1Example <68064118+1Example@users.noreply.github.com> Date: Wed, 4 Mar 2026 21:38:02 +0200 Subject: [PATCH 06/12] Add documentation for playlist append command Signed-off-by: 1Example <68064118+1Example@users.noreply.github.com> --- plplaylists/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plplaylists/README.md b/plplaylists/README.md index d1dbf9169..2f0ff36c7 100644 --- a/plplaylists/README.md +++ b/plplaylists/README.md @@ -42,3 +42,6 @@ - Create playlist from files. - If no URL is provided, it will upload the playlist file from the current attached filed. - If a URL is provided, it will upload the playlist file from the URL. +- `/playlist append [url]` + - Append a URL or song to a playlist. + - URL to append - any direct link including radio streams e.g. https://radio.example.com/stream From ff9ea8a29886f216474ae0969897e80a8977d01e Mon Sep 17 00:00:00 2001 From: 1Example <68064118+1Example@users.noreply.github.com> Date: Fri, 6 Mar 2026 22:58:28 +0200 Subject: [PATCH 07/12] Add query handling and autocomplete for slash commands Signed-off-by: 1Example <68064118+1Example@users.noreply.github.com> --- audio/slash_commands.py | 94 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/audio/slash_commands.py b/audio/slash_commands.py index f9662d426..bc4dcc37e 100644 --- a/audio/slash_commands.py +++ b/audio/slash_commands.py @@ -247,11 +247,23 @@ async def slash_play( context = await self.bot.get_context(interaction) if context.interaction and not context.interaction.response.is_done(): await context.defer(ephemeral=True) + if query == "FqgqQW21tQ@#1g2fasf2": + return await context.send( + embed=await self.pylav.construct_embed( + description=_("You have not selected something to play."), + messageable=context, + ), + ephemeral=True, + ) if query is None: if attachments := context.message.attachments: query = "\n".join( attachment.url for attachment in attachments if valid_query_attachment(attachment.filename) ) + if query is not None: + _track = self._track_cache.get(query) + if _track is not None: + query = _track if not query: await context.send( embed=await self.pylav.construct_embed( @@ -313,3 +325,85 @@ async def slash_play( await player.next(requester=context.author) await self._process_play_message(context, single_track, total_tracks_enqueue, queries) + + @slash_play.autocomplete("query") + async def slash_play_autocomplete_query( + self, interaction: DISCORD_INTERACTION_TYPE, current: str + ): + if not interaction.response.is_done(): + await interaction.response.defer(ephemeral=True) + # If it looks like a URL, don't show autocomplete + if current and (current.startswith("http://") or current.startswith("https://")): + return [ + Choice( + name=shorten_string(max_length=100, string=current), + value=current, + ) + ] + if not current: + return [ + Choice( + name=shorten_string(max_length=100, string=_("Type to search YouTube...")), + value="FqgqQW21tQ@#1g2fasf2", + ) + ] + search_query = f"ytsearch:{current}" + original_query = await Query.from_string(search_query) + try: + response = await interaction.client.pylav.search_query( + original_query, + fullsearch=True, + player=interaction.client.pylav.get_player(interaction.guild.id), + ) + except Exception as e: + LOGGER.debug(f"Error searching for {original_query}", exc_info=e) + return [ + Choice( + name=shorten_string(max_length=100, string=_("Error searching YouTube")), + value="FqgqQW21tQ@#1g2fasf2", + ) + ] + if not response: + return [ + Choice( + name=shorten_string(max_length=100, string=_("No results found on YouTube")), + value="FqgqQW21tQ@#1g2fasf2", + ) + ] + match response.loadType: + case "track": + tracks = [response.data] + case "search": + tracks = response.data + case "playlist": + tracks = response.data.tracks + case __: + tracks = [] + tracks = tracks[:25] + if not tracks: + return [ + Choice( + name=shorten_string(max_length=100, string=_("No results found on YouTube")), + value="FqgqQW21tQ@#1g2fasf2", + ) + ] + choices = [] + node = interaction.client.pylav.get_my_node() + if node is None: + node = await interaction.client.pylav.node_manager.find_best_node(feature="youtube") + player = interaction.client.pylav.get_player(interaction.guild.id) + for track in tracks: + track = await Track.build_track( + node=node, data=track, query=original_query, requester=interaction.user.id, player_instance=player + ) + if track is None: + continue + track_id = hashlib.md5(track.encoded.encode()).hexdigest() + self._track_cache[track_id] = track + choices.append( + Choice( + name=await track.get_track_display_name(max_length=95, unformatted=True, with_url=False), + value=track_id, + ) + ) + return choices From fde3b92b121da54de2539985722a47d0dcb459a8 Mon Sep 17 00:00:00 2001 From: 1Example <68064118+1Example@users.noreply.github.com> Date: Fri, 6 Mar 2026 23:05:42 +0200 Subject: [PATCH 08/12] Handle cached queries for audio commands Signed-off-by: 1Example <68064118+1Example@users.noreply.github.com> --- audio/slash_commands.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/audio/slash_commands.py b/audio/slash_commands.py index bc4dcc37e..36e4a2cd0 100644 --- a/audio/slash_commands.py +++ b/audio/slash_commands.py @@ -260,11 +260,13 @@ async def slash_play( query = "\n".join( attachment.url for attachment in attachments if valid_query_attachment(attachment.filename) ) + cached_queries = None if query is not None: _track = self._track_cache.get(query) if _track is not None: - query = _track - if not query: + cached_queries = [_track] + query = None + if not query and cached_queries is None: await context.send( embed=await self.pylav.construct_embed( description=_("You need to give me a query to enqueue."), @@ -301,7 +303,10 @@ async def slash_play( ) return player = await self.pylav.connect_player(channel=channel, requester=context.author) - queries = [await Query.from_string(qf) for q in query.split("\n") if (qf := q.strip("<>").strip())] + if cached_queries is not None: + queries = cached_queries + else: + queries = [await Query.from_string(qf) for q in query.split("\n") if (qf := q.strip("<>").strip())] total_tracks_enqueue = 0 single_track = None if isinstance(enqueue_type, app_commands.Choice): From 822a2a6122fd9d6bcfbdbe81a2cb665177857496 Mon Sep 17 00:00:00 2001 From: 1Example <68064118+1Example@users.noreply.github.com> Date: Fri, 6 Mar 2026 23:15:54 +0200 Subject: [PATCH 09/12] Refactor track query handling in slash_commands.py Refactor track handling to improve query processing and caching. Signed-off-by: 1Example <68064118+1Example@users.noreply.github.com> --- audio/slash_commands.py | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/audio/slash_commands.py b/audio/slash_commands.py index 36e4a2cd0..a2cbf9a1b 100644 --- a/audio/slash_commands.py +++ b/audio/slash_commands.py @@ -17,6 +17,7 @@ from pylav.extension.red.utils.validators import valid_query_attachment from pylav.helpers.format.strings import shorten_string from pylav.logging import getLogger +from pylav.nodes.api.responses.track import Track as Track_namespace_conflict from pylav.players.query.obj import Query from pylav.players.tracks.obj import Track from pylav.type_hints.bot import DISCORD_COG_TYPE_MIXIN, DISCORD_INTERACTION_TYPE @@ -260,13 +261,11 @@ async def slash_play( query = "\n".join( attachment.url for attachment in attachments if valid_query_attachment(attachment.filename) ) - cached_queries = None if query is not None: _track = self._track_cache.get(query) if _track is not None: - cached_queries = [_track] - query = None - if not query and cached_queries is None: + query = _track + if not query: await context.send( embed=await self.pylav.construct_embed( description=_("You need to give me a query to enqueue."), @@ -303,10 +302,27 @@ async def slash_play( ) return player = await self.pylav.connect_player(channel=channel, requester=context.author) - if cached_queries is not None: - queries = cached_queries - else: + if isinstance(query, (Track, Track_namespace_conflict)): + track = await Track.build_track( + node=player.node, + data=query, + requester=context.author.id, + query=None, + player_instance=player, + ) + if track is None: + return + await player.add(track=track, requester=context.author.id) + if not (player.is_active or player.queue.empty()): + await player.next(requester=context.author) + _query = await track.query() + queries = [] if _query is None else [_query] + await self._process_play_message(context, track, 1, queries) + return + if isinstance(query, str): queries = [await Query.from_string(qf) for q in query.split("\n") if (qf := q.strip("<>").strip())] + else: + queries = [] total_tracks_enqueue = 0 single_track = None if isinstance(enqueue_type, app_commands.Choice): From 57de757592f01265246b5faa777a1b231b24c595 Mon Sep 17 00:00:00 2001 From: 1Example <68064118+1Example@users.noreply.github.com> Date: Fri, 6 Mar 2026 23:24:05 +0200 Subject: [PATCH 10/12] Refactor track enqueue logic in slash_commands.py Refactor enqueue type handling to set priority and index based on user choice. Update track addition to player with specified index. Signed-off-by: 1Example <68064118+1Example@users.noreply.github.com> --- audio/slash_commands.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/audio/slash_commands.py b/audio/slash_commands.py index a2cbf9a1b..1dae68f72 100644 --- a/audio/slash_commands.py +++ b/audio/slash_commands.py @@ -302,6 +302,18 @@ async def slash_play( ) return player = await self.pylav.connect_player(channel=channel, requester=context.author) + if isinstance(enqueue_type, app_commands.Choice): + enqueue_type = enqueue_type.value + match enqueue_type: + case "play_now": + priority = -1 + index = 0 + case "play_next": + priority = 1 + index = 0 + case __: + priority = 100 + index = None if isinstance(query, (Track, Track_namespace_conflict)): track = await Track.build_track( node=player.node, @@ -312,8 +324,8 @@ async def slash_play( ) if track is None: return - await player.add(track=track, requester=context.author.id) - if not (player.is_active or player.queue.empty()): + await player.add(track=track, requester=context.author.id, index=index) + if enqueue_type == "play_now" or not (player.is_active or player.queue.empty()): await player.next(requester=context.author) _query = await track.query() queries = [] if _query is None else [_query] @@ -325,18 +337,6 @@ async def slash_play( queries = [] total_tracks_enqueue = 0 single_track = None - if isinstance(enqueue_type, app_commands.Choice): - enqueue_type = enqueue_type.value - match enqueue_type: - case "play_now": - priority = -1 - index = 0 - case "play_next": - priority = 1 - index = 0 - case __: - priority = 100 - index = None LOGGER.info(f"Priority: {priority}, Index: {index}") if queries: single_track, total_tracks_enqueue = await self._process_play_queries( From 0f47c1c929280d5b7b50665a56cea8a1174c4f8b Mon Sep 17 00:00:00 2001 From: 1Example <68064118+1Example@users.noreply.github.com> Date: Fri, 6 Mar 2026 23:34:35 +0200 Subject: [PATCH 11/12] Modify track enqueue logic for player Signed-off-by: 1Example <68064118+1Example@users.noreply.github.com> --- audio/slash_commands.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/audio/slash_commands.py b/audio/slash_commands.py index 1dae68f72..639a89b44 100644 --- a/audio/slash_commands.py +++ b/audio/slash_commands.py @@ -325,7 +325,7 @@ async def slash_play( if track is None: return await player.add(track=track, requester=context.author.id, index=index) - if enqueue_type == "play_now" or not (player.is_active or player.queue.empty()): + if (not (player.is_active or player.queue.empty())) or priority == -1: await player.next(requester=context.author) _query = await track.query() queries = [] if _query is None else [_query] From 967ccaf9437f62e0e88fcfcdae2367ca61f77c90 Mon Sep 17 00:00:00 2001 From: 1Example <68064118+1Example@users.noreply.github.com> Date: Sat, 7 Mar 2026 00:30:46 +0200 Subject: [PATCH 12/12] Update README links to new repository Signed-off-by: 1Example <68064118+1Example@users.noreply.github.com> --- README.md | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index ac2707f4b..f913a9519 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ -# Official [PyLav](https://github.com/PyLav/PyLav) Cogs for [Red-DiscordBot](https://github.com/Cog-Creators/Red-DiscordBot) +# Official [PyLav]([https://github.com/PyLav/PyLav](https://github.com/1Example/PyLav)) Cogs for [Red-DiscordBot](https://github.com/Cog-Creators/Red-DiscordBot) [![Crowdin](https://badges.crowdin.net/pylav/localized.svg)](https://crowdin.com/project/pylav)[![GitHub license](https://img.shields.io/github/license/PyLav/PyLav.svg)](https://github.com/PyLav/Py-Lav/blob/develop/LICENSE) -[![Support Server](https://img.shields.io/discord/970987707834720266)](https://discord.com/invite/vnmcXqtgeY) About Cogs --------------------------- @@ -30,22 +29,13 @@ Documentation Getting Started ------------------------------------- > **Warning** -> Make sure to follow [PyLav Setup](https://github.com/PyLav/PyLav/blob/develop/SETUP.md) +> Make sure to follow [PyLav Setup](https://github.com/1Example/PyLav/blob/develop/SETUP.md) If you already have a Red instance with PyLav setup then you can do the following ``` [p]load downloader -[p]repo add PyLav https://github.com/PyLav/Red-Cogs +[p]repo add PyLav https://github.com/1Example/PyLav-Cogs [p]cog install PyLav audio [p]load audio ``` - -Translations ------------------------------------- -You can help translating the project into your language here: -[![Crowdin](https://badges.crowdin.net/pylav/localized.svg)](https://crowdin.com/project/pylav) - ------------------------------- - -## Join our support server [![Support Server](https://img.shields.io/discord/970987707834720266?style=social)](https://discord.com/invite/vnmcXqtgeY)