Associate user provided images with playlists (using EXTIMG or same named file), fixes #833
This commit is contained in:
@@ -35,7 +35,7 @@ namespace lms::db
|
||||
{
|
||||
namespace
|
||||
{
|
||||
static constexpr Version LMS_DATABASE_VERSION{ 104 };
|
||||
static constexpr Version LMS_DATABASE_VERSION{ 105 };
|
||||
}
|
||||
|
||||
VersionInfo::VersionInfo()
|
||||
@@ -1723,6 +1723,12 @@ FROM track)");
|
||||
utils::executeCommand(*session.getDboSession(), "ALTER TABLE scan_settings ADD COLUMN musicnn_model_identifier TEXT NOT NULL DEFAULT ''");
|
||||
}
|
||||
|
||||
void migrateFromV104(Session& session)
|
||||
{
|
||||
utils::executeCommand(*session.getDboSession(), R"(ALTER TABLE "playlist_file" ADD COLUMN "preferred_artwork_id" bigint)");
|
||||
utils::executeCommand(*session.getDboSession(), R"(ALTER TABLE "playlist_file" ADD COLUMN "cover_image_file" text NOT NULL DEFAULT '')");
|
||||
}
|
||||
|
||||
bool doDbMigration(Session& session)
|
||||
{
|
||||
constexpr std::string_view outdatedMsg{ "Outdated database, please rebuild it (delete the .db file and restart)" };
|
||||
@@ -1803,6 +1809,7 @@ FROM track)");
|
||||
{ 101, migrateFromV101 },
|
||||
{ 102, migrateFromV102 },
|
||||
{ 103, migrateFromV103 },
|
||||
{ 104, migrateFromV104 },
|
||||
};
|
||||
|
||||
bool migrationPerformed{};
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include "core/ILogger.hpp"
|
||||
#include "database/Session.hpp"
|
||||
#include "database/objects/Artwork.hpp"
|
||||
#include "database/objects/Directory.hpp"
|
||||
#include "database/objects/MediaLibrary.hpp"
|
||||
#include "database/objects/Track.hpp"
|
||||
@@ -181,4 +182,19 @@ namespace lms::db
|
||||
root["files"] = std::move(fileArray);
|
||||
_entries = Wt::Json::serialize(root);
|
||||
}
|
||||
|
||||
void PlayListFile::setCoverImageFile(const std::filesystem::path& file)
|
||||
{
|
||||
_coverImageFile = file;
|
||||
}
|
||||
|
||||
void PlayListFile::updatePreferredArtwork(Session& session, PlayListFileId id, ArtworkId artworkId)
|
||||
{
|
||||
session.checkWriteTransaction();
|
||||
|
||||
if (artworkId.isValid())
|
||||
utils::executeCommand(*session.getDboSession(), "UPDATE playlist_file SET preferred_artwork_id = ? WHERE id = ?", artworkId, id);
|
||||
else
|
||||
utils::executeCommand(*session.getDboSession(), "UPDATE playlist_file SET preferred_artwork_id = NULL WHERE id = ?", id);
|
||||
}
|
||||
} // namespace lms::db
|
||||
|
||||
@@ -31,12 +31,14 @@
|
||||
|
||||
#include "database/IdRange.hpp"
|
||||
#include "database/Object.hpp"
|
||||
#include "database/objects/ArtworkId.hpp"
|
||||
#include "database/objects/DirectoryId.hpp"
|
||||
|
||||
LMS_DECLARE_IDTYPE(PlayListFileId)
|
||||
|
||||
namespace lms::db
|
||||
{
|
||||
class Artwork;
|
||||
class Session;
|
||||
class Directory;
|
||||
class MediaLibrary;
|
||||
@@ -61,6 +63,8 @@ namespace lms::db
|
||||
const Wt::WDateTime& getLastWriteTime() const { return _fileLastWrite; }
|
||||
std::size_t getFileSize() const { return _fileSize; }
|
||||
std::string_view getName() const { return _name; }
|
||||
const std::filesystem::path& getCoverImageFile() const { return _coverImageFile; }
|
||||
ArtworkId getPreferredArtworkId() const { return _preferredArtwork.id(); }
|
||||
std::vector<std::filesystem::path> getFiles() const;
|
||||
ObjectPtr<TrackList> getTrackList() const;
|
||||
ObjectPtr<Directory> getDirectory() const;
|
||||
@@ -70,12 +74,15 @@ namespace lms::db
|
||||
void setAbsoluteFilePath(const std::filesystem::path& filePath);
|
||||
void setLastWriteTime(Wt::WDateTime time) { _fileLastWrite = time; }
|
||||
void setFileSize(std::size_t fileSize) { _fileSize = fileSize; }
|
||||
void setCoverImageFile(const std::filesystem::path& file);
|
||||
void setMediaLibrary(ObjectPtr<MediaLibrary> mediaLibrary) { _mediaLibrary = getDboPtr(mediaLibrary); }
|
||||
void setDirectory(ObjectPtr<Directory> directory);
|
||||
void setTrackList(ObjectPtr<TrackList> trackList);
|
||||
void setName(std::string_view name);
|
||||
void setFiles(std::span<const std::filesystem::path> files);
|
||||
|
||||
static void updatePreferredArtwork(Session& session, PlayListFileId id, ArtworkId artworkId);
|
||||
|
||||
template<class Action>
|
||||
void persist(Action& a)
|
||||
{
|
||||
@@ -85,9 +92,11 @@ namespace lms::db
|
||||
Wt::Dbo::field(a, _fileLastWrite, "file_last_write");
|
||||
Wt::Dbo::field(a, _name, "name");
|
||||
Wt::Dbo::field(a, _entries, "entries");
|
||||
Wt::Dbo::field(a, _coverImageFile, "cover_image_file");
|
||||
|
||||
Wt::Dbo::belongsTo(a, _mediaLibrary, "media_library", Wt::Dbo::OnDeleteSetNull); // don't delete playlist on media library removal, we want to wait for the next scan to have a chance to migrate files
|
||||
Wt::Dbo::belongsTo(a, _directory, "directory", Wt::Dbo::OnDeleteCascade);
|
||||
Wt::Dbo::belongsTo(a, _preferredArtwork, "preferred_artwork", Wt::Dbo::OnDeleteSetNull);
|
||||
Wt::Dbo::hasOne(a, _trackList, "playlist_file");
|
||||
}
|
||||
|
||||
@@ -106,9 +115,11 @@ namespace lms::db
|
||||
|
||||
std::string _name;
|
||||
std::string _entries; // A json encoded list of files
|
||||
std::filesystem::path _coverImageFile;
|
||||
|
||||
Wt::Dbo::ptr<MediaLibrary> _mediaLibrary;
|
||||
Wt::Dbo::ptr<Directory> _directory;
|
||||
Wt::Dbo::ptr<Artwork> _preferredArtwork;
|
||||
Wt::Dbo::weak_ptr<TrackList> _trackList;
|
||||
};
|
||||
} // namespace lms::db
|
||||
|
||||
@@ -125,6 +125,7 @@ namespace lms::db
|
||||
TrackListType getType() const { return _type; }
|
||||
ObjectPtr<User> getUser() const { return _user; }
|
||||
UserId getUserId() const { return _user.id(); }
|
||||
ObjectPtr<PlayListFile> getPlayListFile() const { return _playListFile; }
|
||||
Wt::WDateTime getLastModifiedDateTime() const { return _lastModifiedDateTime; }
|
||||
Wt::WDateTime getCreationDateTime() const { return _creationDateTime; }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user