Renamed/normalized some music playlist command names.

.lopl will now load files from subdirectories too
This commit is contained in:
Toastie 2025-03-01 14:18:48 +13:00
parent 11b3705939
commit 0ee5c0dd94
Signed by: toastie_t0ast
GPG key ID: 0861BE54AD481DC7
6 changed files with 110 additions and 82 deletions

View file

@ -664,7 +664,7 @@ public sealed partial class Music : EllieModule<IMusicService>
[Cmd] [Cmd]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
public async Task PlaylistShuffle() public async Task QueueShuffle()
{ {
var valid = await ValidateAsync(); var valid = await ValidateAsync();
if (!valid) if (!valid)

View file

@ -1,5 +1,7 @@
#nullable disable #nullable disable
using CommandLine;
using LinqToDB; using LinqToDB;
using Microsoft.EntityFrameworkCore;
using EllieBot.Modules.Music.Services; using EllieBot.Modules.Music.Services;
using EllieBot.Db.Models; using EllieBot.Db.Models;
@ -50,17 +52,17 @@ public sealed partial class Music
} }
var embed = CreateEmbed() var embed = CreateEmbed()
.WithAuthor(GetText(strs.playlists_page(num)), MUSIC_ICON_URL) .WithAuthor(GetText(strs.playlists_page(num)), MUSIC_ICON_URL)
.WithDescription(string.Join("\n", .WithDescription(string.Join("\n",
playlists.Select(r => GetText(strs.playlists(r.Id, r.Name, r.Author, r.Songs.Count))))) playlists.Select(r => GetText(strs.playlists(r.Id, r.Name, r.Author, r.Songs.Count)))))
.WithOkColor(); .WithOkColor();
await Response().Embed(embed).SendAsync(); await Response().Embed(embed).SendAsync();
} }
[Cmd] [Cmd]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
public async Task DeletePlaylist([Leftover] int id) public async Task PlaylistDelete([Leftover] int id)
{ {
var success = false; var success = false;
try try
@ -103,26 +105,26 @@ public sealed partial class Music
} }
await Response() await Response()
.Paginated() .Paginated()
.Items(mpl.Songs) .Items(mpl.Songs)
.PageSize(20) .PageSize(20)
.CurrentPage(page) .CurrentPage(page)
.Page((items, _) => .Page((items, _) =>
{ {
var i = 0; var i = 0;
var str = string.Join("\n", var str = string.Join("\n",
items items
.Select(x => $"`{++i}.` [{x.Title.TrimTo(45)}]({x.Query}) `{x.Provider}`")); .Select(x => $"`{++i}.` [{x.Title.TrimTo(45)}]({x.Query}) `{x.Provider}`"));
return CreateEmbed().WithTitle($"\"{mpl.Name}\" by {mpl.Author}") return CreateEmbed().WithTitle($"\"{mpl.Name}\" by {mpl.Author}")
.WithOkColor() .WithOkColor()
.WithDescription(str); .WithDescription(str);
}) })
.SendAsync(); .SendAsync();
} }
[Cmd] [Cmd]
[RequireContext(ContextType.Guild)] [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)) if (!_service.TryGetMusicPlayer(ctx.Guild.Id, out var mp))
{ {
@ -131,14 +133,14 @@ public sealed partial class Music
} }
var songs = mp.GetQueuedTracks() var songs = mp.GetQueuedTracks()
.Select(s => new PlaylistSong .Select(s => new PlaylistSong
{ {
Provider = s.Platform.ToString(), Provider = s.Platform.ToString(),
ProviderType = (MusicType)s.Platform, ProviderType = (MusicType)s.Platform,
Title = s.Title, Title = s.Title,
Query = s.Url Query = s.Url
}) })
.ToList(); .ToList();
MusicPlaylist playlist; MusicPlaylist playlist;
await using (var uow = _db.GetDbContext()) await using (var uow = _db.GetDbContext())
@ -155,18 +157,30 @@ public sealed partial class Music
} }
await Response() await Response()
.Embed(CreateEmbed() .Embed(CreateEmbed()
.WithOkColor() .WithOkColor()
.WithTitle(GetText(strs.playlist_saved)) .WithTitle(GetText(strs.playlist_saved))
.AddField(GetText(strs.name), name) .AddField(GetText(strs.name), name)
.AddField(GetText(strs.id), playlist.Id.ToString())) .AddField(GetText(strs.id), playlist.Id.ToString()))
.SendAsync(); .SendAsync();
}
public class PlaylistLoadOptions : IEllieCommandOptions
{
[Option("shuffle")]
public bool Shuffled { get; set; } = false;
public void NormalizeOptions()
{
}
} }
[Cmd] [Cmd]
[RequireContext(ContextType.Guild)] [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 // expensive action, 1 at a time
await _playlistLock.WaitAsync(); await _playlistLock.WaitAsync();
try try
@ -201,7 +215,9 @@ public sealed partial class Music
MusicPlaylist mpl; MusicPlaylist mpl;
await using (var uow = _db.GetDbContext()) await using (var uow = _db.GetDbContext())
{ {
mpl = uow.Set<MusicPlaylist>().GetWithSongs(id); mpl = uow.Set<MusicPlaylist>()
.AsNoTracking()
.GetWithSongs(id);
} }
if (mpl is null) if (mpl is null)
@ -214,14 +230,19 @@ public sealed partial class Music
try try
{ {
msg = await Response() msg = await Response()
.Pending(strs.attempting_to_queue(Format.Bold(mpl.Songs.Count.ToString()))) .Pending(strs.attempting_to_queue(Format.Bold(mpl.Songs.Count.ToString())))
.SendAsync(); .SendAsync();
} }
catch (Exception) 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()); ctx.User.ToString());
if (msg is not null) if (msg is not null)

View file

@ -39,7 +39,7 @@ public sealed class LocalTrackResolver : ILocalTrackResolver
yield break; yield break;
} }
var files = dir.EnumerateFiles() var files = dir.EnumerateFiles("*", SearchOption.AllDirectories)
.Where(x => .Where(x =>
{ {
if (!x.Attributes.HasFlag(FileAttributes.Hidden | FileAttributes.System) if (!x.Attributes.HasFlag(FileAttributes.Hidden | FileAttributes.System)

View file

@ -13,6 +13,6 @@ public static class MusicPlaylistExtensions
return playlists.AsQueryable().Skip((num - 1) * 20).Take(20).Include(pl => pl.Songs).ToList(); 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); => playlists.Include(mpl => mpl.Songs).FirstOrDefault(mpl => mpl.Id == id);
} }

View file

@ -423,11 +423,6 @@ draw:
- draw - draw
drawnew: drawnew:
- drawnew - drawnew
playlistshuffle:
- playlistshuffle
- shuffle
- sh
- plsh
flip: flip:
- flip - flip
betflip: betflip:
@ -528,6 +523,11 @@ queuesearch:
- queuesearch - queuesearch
- qs - qs
- yqs - yqs
queueshuffle:
- queueshuffle
- qsh
- qshuffle
- shuffle
listqueue: listqueue:
- listqueue - listqueue
- lq - lq
@ -538,9 +538,14 @@ volume:
- volume - volume
- vol - vol
- defvol - defvol
playlist: playlistload:
- playlist - playlistload
- pl - pload
- plload
- pll
playlists:
- playlists
- pls
localplaylist: localplaylist:
- localplaylist - localplaylist
- lopl - lopl
@ -550,6 +555,9 @@ radio:
local: local:
- local - local
- lo - lo
playlist:
- playlist
- pl
join: join:
- join - join
- j - j
@ -574,21 +582,20 @@ queueautoplay:
- qap - qap
queuefairplay: queuefairplay:
- qfp - qfp
save: playlistsave:
- save - playlistsave
- plsave
- psave
streamrole: streamrole:
- streamrole - streamrole
load:
- load
playlists:
- playlists
- pls
playlistshow: playlistshow:
- playlistshow - playlistshow
- plshow - plshow
deleteplaylist: playlistdelete:
- deleteplaylist - playlistdelete
- delpls - pldel
- plrm
- pldelete
streamadd: streamadd:
- streamadd - streamadd
- sta - sta
@ -877,7 +884,7 @@ betstats:
- bs - bs
gamblestats: gamblestats:
- gamblestats - gamblestats
- gs - gs
bettest: bettest:
- bettest - bettest
slot: slot:
@ -889,7 +896,7 @@ affinity:
waifuclaim: waifuclaim:
- waifuclaim - waifuclaim
- claim - claim
- wc - wc
waifuclaims: waifuclaims:
- waifuclaims - waifuclaims
- claims - claims
@ -1353,7 +1360,7 @@ marmaladeinfo:
- mainfo - mainfo
marmaladesearch: marmaladesearch:
- marmaladesearch - marmaladesearch
- masearchW - masearch
# Bank stuff # Bank stuff
bankdeposit: bankdeposit:
- deposit - deposit
@ -1512,7 +1519,7 @@ btnroleremove:
- r - r
- rm - rm
btnroleremoveall: btnroleremoveall:
- remall - removeall
- rma - rma
btnrolelist: btnrolelist:
- list - list
@ -1573,7 +1580,7 @@ fishlist:
- fil - fil
- fishlist - fishlist
fishspot: fishspot:
- fishspot - fishspot
- fisp - fisp
- fish? - fish?
xprate: xprate:

View file

@ -1383,12 +1383,6 @@ drawnew:
params: params:
- num: - num:
desc: "The number of cards to be drawn from the new deck." desc: "The number of cards to be drawn from the new deck."
playlistshuffle:
desc: Shuffles the current playlist.
ex:
- ''
params:
- { }
flip: flip:
desc: Flips coin(s) - heads or tails, and shows an image. desc: Flips coin(s) - heads or tails, and shows an image.
ex: ex:
@ -1701,6 +1695,12 @@ play:
desc: "The index of the desired song or search result to navigate to." desc: "The index of the desired song or search result to navigate to."
- query: - query:
desc: "The search query is used to find and play songs matching the specified criteria." desc: "The search query is used to find and play songs matching the specified criteria."
queueshuffle:
desc: Shuffles the current playlist.
ex:
- ''
params:
- { }
stop: stop:
desc: Stops the music and preserves the current song index. Stays in the channel. desc: Stops the music and preserves the current song index. Stays in the channel.
ex: ex:
@ -1832,13 +1832,6 @@ queuerepeat:
params: params:
- type: - type:
desc: "The type of repeat strategy to be set." 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: 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 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: ex:
@ -1849,13 +1842,20 @@ streamrole:
addRole: addRole:
desc: "The role to be added to users when they start streaming." 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. desc: Loads a saved playlist using its ID. Use `{0}pls` to list all saved playlists and `{0}save` to save new ones.
ex: ex:
- 5 - 5
params: params:
- id: - id:
desc: "The id of the playlist to be loaded." 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: playlists:
desc: Lists all playlists. Paginated, 20 per page. desc: Lists all playlists. Paginated, 20 per page.
ex: ex:
@ -1872,8 +1872,8 @@ playlistshow:
desc: "The id of the playlist to retrieve songs from." desc: "The id of the playlist to retrieve songs from."
page: page:
desc: "The current page number for the pagination." desc: "The current page number for the pagination."
deleteplaylist: playlistdelete:
desc: Deletes a saved playlist using its id. Works only if you made it or if you are the bot owner. desc: Deletes a saved playlist using its ID. Works only on playlists saved by you.
ex: ex:
- 5 - 5
params: params: