Merge tag 'v0.22.2' into master

release v0.22.2
This commit is contained in:
Max Kellermann
2020-10-28 17:33:10 +01:00
22 changed files with 275 additions and 74 deletions

View File

@@ -0,0 +1,74 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "db/plugins/simple/Directory.hxx"
#include "archive/ArchiveList.hxx"
#include "decoder/DecoderList.hxx"
#include "playlist/PlaylistRegistry.hxx"
#include "fs/Traits.hxx"
gcc_pure
static bool
HaveArchivePluginForFilename(const char *filename) noexcept
{
#ifdef ENABLE_ARCHIVE
const char *suffix = PathTraitsUTF8::GetFilenameSuffix(filename);
return suffix != nullptr &&
archive_plugin_from_suffix(suffix) != nullptr;
#else
(void)filename;
return false;
#endif
}
gcc_pure
static bool
HaveContainerPluginForFilename(const char *filename) noexcept
{
const char *suffix = PathTraitsUTF8::GetFilenameSuffix(filename);
return suffix != nullptr &&
// TODO: check if this plugin really supports containers
decoder_plugins_supports_suffix(suffix);
}
gcc_pure
static bool
HavePlaylistPluginForFilename(const char *filename) noexcept
{
const char *suffix = PathTraitsUTF8::GetFilenameSuffix(filename);
return suffix != nullptr && playlist_suffix_supported(suffix);
}
bool
Directory::IsPluginAvailable() const noexcept
{
switch (device) {
case DEVICE_INARCHIVE:
return HaveArchivePluginForFilename(GetName());
case DEVICE_CONTAINER:
return HaveContainerPluginForFilename(GetName());
case DEVICE_PLAYLIST:
return HavePlaylistPluginForFilename(GetName());
default:
return true;
}
}

View File

@@ -69,46 +69,58 @@ UpdateWalk::RemoveExcludedFromDirectory(Directory &directory,
const ScopeDatabaseLock protect;
directory.ForEachChildSafe([&](Directory &child){
const auto name_fs =
AllocatedPath::FromUTF8(child.GetName());
const auto name_fs =
AllocatedPath::FromUTF8(child.GetName());
if (name_fs.IsNull() || exclude_list.Check(name_fs)) {
editor.DeleteDirectory(&child);
modified = true;
}
});
if (name_fs.IsNull() || exclude_list.Check(name_fs)) {
editor.DeleteDirectory(&child);
modified = true;
}
});
directory.ForEachSongSafe([&](Song &song){
assert(&song.parent == &directory);
assert(&song.parent == &directory);
const auto name_fs = AllocatedPath::FromUTF8(song.filename);
if (name_fs.IsNull() || exclude_list.Check(name_fs)) {
editor.DeleteSong(directory, &song);
modified = true;
}
});
const auto name_fs = AllocatedPath::FromUTF8(song.filename);
if (name_fs.IsNull() || exclude_list.Check(name_fs)) {
editor.DeleteSong(directory, &song);
modified = true;
}
});
}
inline void
UpdateWalk::PurgeDeletedFromDirectory(Directory &directory) noexcept
{
directory.ForEachChildSafe([&](Directory &child){
if (child.IsMount() || DirectoryExists(storage, child))
return;
if (child.IsMount())
/* mount points are always preserved */
return;
editor.LockDeleteDirectory(&child);
if (DirectoryExists(storage, child) &&
child.IsPluginAvailable())
return;
modified = true;
});
/* the directory was deleted (or the plugin which
handles this "virtual" directory is unavailable) */
editor.LockDeleteDirectory(&child);
modified = true;
});
directory.ForEachSongSafe([&](Song &song){
if (!directory_child_is_regular(storage, directory,
song.filename)) {
editor.LockDeleteSong(directory, &song);
if (!directory_child_is_regular(storage, directory,
song.filename) ||
!song.IsPluginAvailable()) {
/* the song file was deleted (or the decoder
plugin is unavailable) */
modified = true;
}
});
editor.LockDeleteSong(directory, &song);
modified = true;
}
});
for (auto i = directory.playlists.begin(),
end = directory.playlists.end();