From 0ee5c0dd94aa876a23b17515f6231dd6b4efc57c Mon Sep 17 00:00:00 2001 From: Toastie <toastie@toastiet0ast.com> Date: Sat, 1 Mar 2025 14:18:48 +1300 Subject: [PATCH] Renamed/normalized some music playlist command names. .lopl will now load files from subdirectories too --- src/EllieBot/Modules/Music/Music.cs | 2 +- .../Modules/Music/PlaylistCommands.cs | 101 +++++++++++------- .../_common/Resolvers/LocalTrackResolver.cs | 2 +- .../_common/db/MusicPlaylistExtensions.cs | 2 +- src/EllieBot/strings/aliases.yml | 53 +++++---- .../strings/commands/commands.en-US.yml | 32 +++--- 6 files changed, 110 insertions(+), 82 deletions(-) diff --git a/src/EllieBot/Modules/Music/Music.cs b/src/EllieBot/Modules/Music/Music.cs index 1061ad1..cba818b 100644 --- a/src/EllieBot/Modules/Music/Music.cs +++ b/src/EllieBot/Modules/Music/Music.cs @@ -664,7 +664,7 @@ public sealed partial class Music : EllieModule<IMusicService> [Cmd] [RequireContext(ContextType.Guild)] - public async Task PlaylistShuffle() + public async Task QueueShuffle() { var valid = await ValidateAsync(); if (!valid) diff --git a/src/EllieBot/Modules/Music/PlaylistCommands.cs b/src/EllieBot/Modules/Music/PlaylistCommands.cs index 2eb1d57..72edf86 100644 --- a/src/EllieBot/Modules/Music/PlaylistCommands.cs +++ b/src/EllieBot/Modules/Music/PlaylistCommands.cs @@ -1,5 +1,7 @@ #nullable disable +using CommandLine; using LinqToDB; +using Microsoft.EntityFrameworkCore; using EllieBot.Modules.Music.Services; using EllieBot.Db.Models; @@ -50,17 +52,17 @@ public sealed partial class Music } var embed = CreateEmbed() - .WithAuthor(GetText(strs.playlists_page(num)), MUSIC_ICON_URL) - .WithDescription(string.Join("\n", - playlists.Select(r => GetText(strs.playlists(r.Id, r.Name, r.Author, r.Songs.Count))))) - .WithOkColor(); + .WithAuthor(GetText(strs.playlists_page(num)), MUSIC_ICON_URL) + .WithDescription(string.Join("\n", + playlists.Select(r => GetText(strs.playlists(r.Id, r.Name, r.Author, r.Songs.Count))))) + .WithOkColor(); await Response().Embed(embed).SendAsync(); } [Cmd] [RequireContext(ContextType.Guild)] - public async Task DeletePlaylist([Leftover] int id) + public async Task PlaylistDelete([Leftover] int id) { var success = false; try @@ -103,26 +105,26 @@ public sealed partial class Music } await Response() - .Paginated() - .Items(mpl.Songs) - .PageSize(20) - .CurrentPage(page) - .Page((items, _) => - { - var i = 0; - var str = string.Join("\n", - items - .Select(x => $"`{++i}.` [{x.Title.TrimTo(45)}]({x.Query}) `{x.Provider}`")); - return CreateEmbed().WithTitle($"\"{mpl.Name}\" by {mpl.Author}") - .WithOkColor() - .WithDescription(str); - }) - .SendAsync(); + .Paginated() + .Items(mpl.Songs) + .PageSize(20) + .CurrentPage(page) + .Page((items, _) => + { + var i = 0; + var str = string.Join("\n", + items + .Select(x => $"`{++i}.` [{x.Title.TrimTo(45)}]({x.Query}) `{x.Provider}`")); + return CreateEmbed().WithTitle($"\"{mpl.Name}\" by {mpl.Author}") + .WithOkColor() + .WithDescription(str); + }) + .SendAsync(); } [Cmd] [RequireContext(ContextType.Guild)] - public async Task Save([Leftover] string name) + public async Task PlaylistSave([Leftover] string name) { if (!_service.TryGetMusicPlayer(ctx.Guild.Id, out var mp)) { @@ -131,14 +133,14 @@ public sealed partial class Music } var songs = mp.GetQueuedTracks() - .Select(s => new PlaylistSong - { - Provider = s.Platform.ToString(), - ProviderType = (MusicType)s.Platform, - Title = s.Title, - Query = s.Url - }) - .ToList(); + .Select(s => new PlaylistSong + { + Provider = s.Platform.ToString(), + ProviderType = (MusicType)s.Platform, + Title = s.Title, + Query = s.Url + }) + .ToList(); MusicPlaylist playlist; await using (var uow = _db.GetDbContext()) @@ -155,18 +157,30 @@ public sealed partial class Music } await Response() - .Embed(CreateEmbed() - .WithOkColor() - .WithTitle(GetText(strs.playlist_saved)) - .AddField(GetText(strs.name), name) - .AddField(GetText(strs.id), playlist.Id.ToString())) - .SendAsync(); + .Embed(CreateEmbed() + .WithOkColor() + .WithTitle(GetText(strs.playlist_saved)) + .AddField(GetText(strs.name), name) + .AddField(GetText(strs.id), playlist.Id.ToString())) + .SendAsync(); + } + + public class PlaylistLoadOptions : IEllieCommandOptions + { + [Option("shuffle")] + public bool Shuffled { get; set; } = false; + + public void NormalizeOptions() + { + } } [Cmd] [RequireContext(ContextType.Guild)] - public async Task Load([Leftover] int id) + [EllieOptions<PlaylistLoadOptions>] + public async Task PlaylistLoad(int id, params string[] args) { + var opts = OptionsParser.ParseFrom(new PlaylistLoadOptions(), args).Item1; // expensive action, 1 at a time await _playlistLock.WaitAsync(); try @@ -201,7 +215,9 @@ public sealed partial class Music MusicPlaylist mpl; await using (var uow = _db.GetDbContext()) { - mpl = uow.Set<MusicPlaylist>().GetWithSongs(id); + mpl = uow.Set<MusicPlaylist>() + .AsNoTracking() + .GetWithSongs(id); } if (mpl is null) @@ -214,14 +230,19 @@ public sealed partial class Music try { msg = await Response() - .Pending(strs.attempting_to_queue(Format.Bold(mpl.Songs.Count.ToString()))) - .SendAsync(); + .Pending(strs.attempting_to_queue(Format.Bold(mpl.Songs.Count.ToString()))) + .SendAsync(); } catch (Exception) { } - await mp.EnqueueManyAsync(mpl.Songs.Select(x => (x.Query, (MusicPlatform)x.ProviderType)), + var songs = opts.Shuffled + ? mpl.Songs.Shuffle() + : mpl.Songs; + + await mp.EnqueueManyAsync( + songs.Select(x => (x.Query, (MusicPlatform)x.ProviderType)), ctx.User.ToString()); if (msg is not null) diff --git a/src/EllieBot/Modules/Music/_common/Resolvers/LocalTrackResolver.cs b/src/EllieBot/Modules/Music/_common/Resolvers/LocalTrackResolver.cs index d728ce7..a47ff46 100644 --- a/src/EllieBot/Modules/Music/_common/Resolvers/LocalTrackResolver.cs +++ b/src/EllieBot/Modules/Music/_common/Resolvers/LocalTrackResolver.cs @@ -39,7 +39,7 @@ public sealed class LocalTrackResolver : ILocalTrackResolver yield break; } - var files = dir.EnumerateFiles() + var files = dir.EnumerateFiles("*", SearchOption.AllDirectories) .Where(x => { if (!x.Attributes.HasFlag(FileAttributes.Hidden | FileAttributes.System) diff --git a/src/EllieBot/Modules/Music/_common/db/MusicPlaylistExtensions.cs b/src/EllieBot/Modules/Music/_common/db/MusicPlaylistExtensions.cs index 0e3e603..e272342 100644 --- a/src/EllieBot/Modules/Music/_common/db/MusicPlaylistExtensions.cs +++ b/src/EllieBot/Modules/Music/_common/db/MusicPlaylistExtensions.cs @@ -13,6 +13,6 @@ public static class MusicPlaylistExtensions return playlists.AsQueryable().Skip((num - 1) * 20).Take(20).Include(pl => pl.Songs).ToList(); } - public static MusicPlaylist GetWithSongs(this DbSet<MusicPlaylist> playlists, int id) + public static MusicPlaylist GetWithSongs(this IQueryable<MusicPlaylist> playlists, int id) => playlists.Include(mpl => mpl.Songs).FirstOrDefault(mpl => mpl.Id == id); } \ No newline at end of file diff --git a/src/EllieBot/strings/aliases.yml b/src/EllieBot/strings/aliases.yml index 3e76803..38df275 100644 --- a/src/EllieBot/strings/aliases.yml +++ b/src/EllieBot/strings/aliases.yml @@ -423,11 +423,6 @@ draw: - draw drawnew: - drawnew -playlistshuffle: - - playlistshuffle - - shuffle - - sh - - plsh flip: - flip betflip: @@ -528,6 +523,11 @@ queuesearch: - queuesearch - qs - yqs +queueshuffle: + - queueshuffle + - qsh + - qshuffle + - shuffle listqueue: - listqueue - lq @@ -538,9 +538,14 @@ volume: - volume - vol - defvol -playlist: - - playlist - - pl +playlistload: + - playlistload + - pload + - plload + - pll +playlists: + - playlists + - pls localplaylist: - localplaylist - lopl @@ -550,6 +555,9 @@ radio: local: - local - lo +playlist: + - playlist + - pl join: - join - j @@ -574,21 +582,20 @@ queueautoplay: - qap queuefairplay: - qfp -save: - - save +playlistsave: + - playlistsave + - plsave + - psave streamrole: - streamrole -load: - - load -playlists: - - playlists - - pls playlistshow: - playlistshow - plshow -deleteplaylist: - - deleteplaylist - - delpls +playlistdelete: + - playlistdelete + - pldel + - plrm + - pldelete streamadd: - streamadd - sta @@ -877,7 +884,7 @@ betstats: - bs gamblestats: - gamblestats - - gs + - gs bettest: - bettest slot: @@ -889,7 +896,7 @@ affinity: waifuclaim: - waifuclaim - claim - - wc + - wc waifuclaims: - waifuclaims - claims @@ -1353,7 +1360,7 @@ marmaladeinfo: - mainfo marmaladesearch: - marmaladesearch - - masearchW + - masearch # Bank stuff bankdeposit: - deposit @@ -1512,7 +1519,7 @@ btnroleremove: - r - rm btnroleremoveall: - - remall + - removeall - rma btnrolelist: - list @@ -1573,7 +1580,7 @@ fishlist: - fil - fishlist fishspot: - - fishspot + - fishspot - fisp - fish? xprate: diff --git a/src/EllieBot/strings/commands/commands.en-US.yml b/src/EllieBot/strings/commands/commands.en-US.yml index e366798..527679c 100644 --- a/src/EllieBot/strings/commands/commands.en-US.yml +++ b/src/EllieBot/strings/commands/commands.en-US.yml @@ -1383,12 +1383,6 @@ drawnew: params: - num: desc: "The number of cards to be drawn from the new deck." -playlistshuffle: - desc: Shuffles the current playlist. - ex: - - '' - params: - - { } flip: desc: Flips coin(s) - heads or tails, and shows an image. ex: @@ -1701,6 +1695,12 @@ play: desc: "The index of the desired song or search result to navigate to." - query: desc: "The search query is used to find and play songs matching the specified criteria." +queueshuffle: + desc: Shuffles the current playlist. + ex: + - '' + params: + - { } stop: desc: Stops the music and preserves the current song index. Stays in the channel. ex: @@ -1832,13 +1832,6 @@ queuerepeat: params: - type: desc: "The type of repeat strategy to be set." -save: - desc: Saves a playlist under a certain name. Playlist name must be no longer than 20 characters and must not contain dashes. - ex: - - classical1 - params: - - name: - desc: "The name provided is used to uniquely identify the saved playlist." streamrole: desc: Sets a role which is monitored for streamers (FromRole), and a role to add if a user from 'FromRole' is streaming (AddRole). When a user from 'FromRole' starts streaming, they will receive an 'AddRole'. You can only have 1 Stream Role per server. Provide no parameters to disable ex: @@ -1849,13 +1842,20 @@ streamrole: addRole: desc: "The role to be added to users when they start streaming." - { } -load: +playlistload: desc: Loads a saved playlist using its ID. Use `{0}pls` to list all saved playlists and `{0}save` to save new ones. ex: - 5 params: - id: desc: "The id of the playlist to be loaded." +playlistsave: + desc: Saves a playlist under a certain name. Playlist name must be no longer than 20 characters and must not contain dashes. + ex: + - classical1 + params: + - name: + desc: "The name provided is used to uniquely identify the saved playlist." playlists: desc: Lists all playlists. Paginated, 20 per page. ex: @@ -1872,8 +1872,8 @@ playlistshow: desc: "The id of the playlist to retrieve songs from." page: desc: "The current page number for the pagination." -deleteplaylist: - desc: Deletes a saved playlist using its id. Works only if you made it or if you are the bot owner. +playlistdelete: + desc: Deletes a saved playlist using its ID. Works only on playlists saved by you. ex: - 5 params: