Allow range in listplaylist and listplaylistinfo

This commit is contained in:
jcorporation 2024-02-08 21:26:28 +01:00
parent c71e586c53
commit a3794f8c3b
6 changed files with 37 additions and 13 deletions

1
NEWS
View File

@ -12,6 +12,7 @@ ver 0.24 (not yet released)
- stickers on playlists and some tag types - stickers on playlists and some tag types
- new command "stickernames" - new command "stickernames"
- new "search"/"find" filter "added-since" - new "search"/"find" filter "added-since"
- allow range in listplaylist and listplaylistinfo
* database * database
- attribute "added" shows when each song was added to the database - attribute "added" shows when each song was added to the database
- proxy: require MPD 0.21 or later - proxy: require MPD 0.21 or later

View File

@ -944,15 +944,17 @@ remote playlists (absolute URI with a supported scheme).
.. _command_listplaylist: .. _command_listplaylist:
:command:`listplaylist {NAME}` :command:`listplaylist {NAME} [{START:END}]`
Lists the songs in the playlist. Playlist plugins are Lists the songs in the playlist. Playlist plugins are
supported. supported. A range may be specified to list
only a part of the playlist. [#since_0_24]_
.. _command_listplaylistinfo: .. _command_listplaylistinfo:
:command:`listplaylistinfo {NAME}` :command:`listplaylistinfo {NAME} [{START:END}]`
Lists the songs with metadata in the playlist. Playlist Lists the songs with metadata in the playlist. Playlist
plugins are supported. plugins are supported. A range may be specified to list
only a part of the playlist. [#since_0_24]_
.. _command_listplaylists: .. _command_listplaylists:

View File

@ -117,8 +117,8 @@ static constexpr struct command commands[] = {
{ "listneighbors", PERMISSION_READ, 0, 0, handle_listneighbors }, { "listneighbors", PERMISSION_READ, 0, 0, handle_listneighbors },
#endif #endif
{ "listpartitions", PERMISSION_READ, 0, 0, handle_listpartitions }, { "listpartitions", PERMISSION_READ, 0, 0, handle_listpartitions },
{ "listplaylist", PERMISSION_READ, 1, 1, handle_listplaylist }, { "listplaylist", PERMISSION_READ, 1, 2, handle_listplaylist },
{ "listplaylistinfo", PERMISSION_READ, 1, 1, handle_listplaylistinfo }, { "listplaylistinfo", PERMISSION_READ, 1, 2, handle_listplaylistinfo },
{ "listplaylists", PERMISSION_READ, 0, 0, handle_listplaylists }, { "listplaylists", PERMISSION_READ, 0, 0, handle_listplaylists },
{ "load", PERMISSION_ADD, 1, 3, handle_load }, { "load", PERMISSION_ADD, 1, 3, handle_load },
{ "lsinfo", PERMISSION_READ, 0, 1, handle_lsinfo }, { "lsinfo", PERMISSION_READ, 0, 1, handle_lsinfo },

View File

@ -125,8 +125,10 @@ handle_listplaylist(Client &client, Request args, Response &r)
#endif #endif
); );
RangeArg range = args.ParseOptional(1, RangeArg::All());
if (playlist_file_print(r, client.GetPartition(), SongLoader(client), if (playlist_file_print(r, client.GetPartition(), SongLoader(client),
name, false)) name, range.start, range.end, false))
return CommandResult::OK; return CommandResult::OK;
throw PlaylistError::NoSuchList(); throw PlaylistError::NoSuchList();
@ -142,8 +144,10 @@ handle_listplaylistinfo(Client &client, Request args, Response &r)
#endif #endif
); );
RangeArg range = args.ParseOptional(1, RangeArg::All());
if (playlist_file_print(r, client.GetPartition(), SongLoader(client), if (playlist_file_print(r, client.GetPartition(), SongLoader(client),
name, true)) name, range.start, range.end, true))
return CommandResult::OK; return CommandResult::OK;
throw PlaylistError::NoSuchList(); throw PlaylistError::NoSuchList();

View File

@ -18,14 +18,25 @@ static void
playlist_provider_print(Response &r, playlist_provider_print(Response &r,
const SongLoader &loader, const SongLoader &loader,
const char *uri, const char *uri,
SongEnumerator &e, bool detail) noexcept SongEnumerator &e,
unsigned start_index,
unsigned end_index,
bool detail) noexcept
{ {
const auto base_uri = uri != nullptr const auto base_uri = uri != nullptr
? PathTraitsUTF8::GetParent(uri) ? PathTraitsUTF8::GetParent(uri)
: "."; : ".";
std::unique_ptr<DetachedSong> song; std::unique_ptr<DetachedSong> song;
while ((song = e.NextSong()) != nullptr) {
for (unsigned i = 0;
i < end_index && (song = e.NextSong()) != nullptr;
++i) {
if (i < start_index) {
/* skip songs before the start index */
continue;
}
if (playlist_check_translate_song(*song, base_uri, if (playlist_check_translate_song(*song, base_uri,
loader) && loader) &&
detail) detail)
@ -40,7 +51,10 @@ playlist_provider_print(Response &r,
bool bool
playlist_file_print(Response &r, Partition &partition, playlist_file_print(Response &r, Partition &partition,
const SongLoader &loader, const SongLoader &loader,
const LocatedUri &uri, bool detail) const LocatedUri &uri,
unsigned start_index,
unsigned end_index,
bool detail)
{ {
Mutex mutex; Mutex mutex;
@ -56,6 +70,7 @@ playlist_file_print(Response &r, Partition &partition,
if (playlist == nullptr) if (playlist == nullptr)
return false; return false;
playlist_provider_print(r, loader, uri.canonical_uri, *playlist, detail); playlist_provider_print(r, loader, uri.canonical_uri, *playlist,
start_index, end_index, detail);
return true; return true;
} }

View File

@ -18,6 +18,8 @@ struct Partition;
bool bool
playlist_file_print(Response &r, Partition &partition, playlist_file_print(Response &r, Partition &partition,
const SongLoader &loader, const SongLoader &loader,
const LocatedUri &uri, bool detail); const LocatedUri &uri,
unsigned start_index, unsigned end_index,
bool detail);
#endif #endif