From d4f3dd49b4aff022eb90f9718819038c878a373d Mon Sep 17 00:00:00 2001 From: datasone Date: Wed, 12 Apr 2023 00:04:37 +0800 Subject: [PATCH] db/SimpleDatabasePlugin: store `in_playlist` value of songs into database Fixes hide_playlist_targets not working after server restart Currently, `hide_playlists_targets` works by skipping songs with `in_playlist` value set to true in [`Directory::Walk`](https://github.com/MusicPlayerDaemon/MPD/blob/a57bcd02382947abbd961594cdf00302c0c7866a/src/db/plugins/simple/Directory.cxx#L237). But `in_playlist` is not stored and only updated in [`UpdateWalk::PurgeDanglingFromPlaylists`](https://github.com/MusicPlayerDaemon/MPD/blob/a57bcd02382947abbd961594cdf00302c0c7866a/src/db/update/Playlist.cxx#L139), which will only be executed while updating DB. This causes the problem that playlist target songs are correctly hidden after database update, but will remain visible after mpd server restarted. This pr solves the problem by storing `in_playlist` value of songs into the `SimpleDatabase` file. --- src/SongSave.cxx | 8 +++++++- src/SongSave.hxx | 2 +- src/db/plugins/simple/DirectorySave.cxx | 4 +++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/SongSave.cxx b/src/SongSave.cxx index 842c633b3..11e498904 100644 --- a/src/SongSave.cxx +++ b/src/SongSave.cxx @@ -63,6 +63,9 @@ song_save(BufferedOutputStream &os, const Song &song) if (song.audio_format.IsDefined()) os.Format("Format: %s\n", ToString(song.audio_format).c_str()); + if (song.in_playlist) + os.Write("InPlaylist: yes\n"); + if (!IsNegative(song.mtime)) os.Format(SONG_MTIME ": %li\n", (long)std::chrono::system_clock::to_time_t(song.mtime)); @@ -86,7 +89,7 @@ song_save(BufferedOutputStream &os, const DetachedSong &song) DetachedSong song_load(LineReader &file, const char *uri, - std::string *target_r) + std::string *target_r, bool *in_playlist_r) { DetachedSong song(uri); @@ -132,6 +135,9 @@ song_load(LineReader &file, const char *uri, song.SetStartTime(SongTime::FromMS(start_ms)); song.SetEndTime(SongTime::FromMS(end_ms)); + } else if (StringIsEqual(line, "InPlaylist")) { + if (in_playlist_r != nullptr) + *in_playlist_r = StringIsEqual(value, "yes"); } else { throw FormatRuntimeError("unknown line in db: %s", line); } diff --git a/src/SongSave.hxx b/src/SongSave.hxx index 8ee6ce76b..7b276bd7e 100644 --- a/src/SongSave.hxx +++ b/src/SongSave.hxx @@ -44,6 +44,6 @@ song_save(BufferedOutputStream &os, const DetachedSong &song); */ DetachedSong song_load(LineReader &file, const char *uri, - std::string *target_r=nullptr); + std::string *target_r=nullptr, bool *in_playlist_r=nullptr); #endif diff --git a/src/db/plugins/simple/DirectorySave.cxx b/src/db/plugins/simple/DirectorySave.cxx index e7648ac11..8dacae763 100644 --- a/src/db/plugins/simple/DirectorySave.cxx +++ b/src/db/plugins/simple/DirectorySave.cxx @@ -168,12 +168,14 @@ directory_load(LineReader &file, Directory &directory) throw FormatRuntimeError("Duplicate song '%s'", name); std::string target; + bool in_playlist = false; auto detached_song = song_load(file, name, - &target); + &target, &in_playlist); auto song = std::make_unique(std::move(detached_song), directory); song->target = std::move(target); + song->in_playlist = in_playlist; directory.AddSong(std::move(song)); } else if ((p = StringAfterPrefix(line, PLAYLIST_META_BEGIN))) {