Optimized artwork association with tracks
This commit is contained in:
@@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include "Utils.hpp"
|
#include "Utils.hpp"
|
||||||
#include "traits/IdTypeTraits.hpp"
|
#include "traits/IdTypeTraits.hpp"
|
||||||
|
#include "traits/PathTraits.hpp"
|
||||||
|
|
||||||
namespace lms::db
|
namespace lms::db
|
||||||
{
|
{
|
||||||
@@ -87,4 +88,17 @@ namespace lms::db
|
|||||||
|
|
||||||
return utils::fetchQuerySingleResult(query);
|
return utils::fetchQuerySingleResult(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::filesystem::path Artwork::getAbsoluteFilePath() const
|
||||||
|
{
|
||||||
|
auto query{ session()->query<std::filesystem::path>("SELECT COALESCE(image.absolute_file_path, track.absolute_file_path) AS absolute_file_path FROM artwork") };
|
||||||
|
query.leftJoin("image ON artwork.image_id = image.id");
|
||||||
|
query.leftJoin("track_embedded_image ON artwork.track_embedded_image_id = track_embedded_image.id");
|
||||||
|
query.leftJoin("track_embedded_image_link ON track_embedded_image.id = track_embedded_image_link.track_embedded_image_id");
|
||||||
|
query.leftJoin("track ON track.id = track_embedded_image_link.track_id");
|
||||||
|
query.limit(1); // there may be several tracks matching this artwork...
|
||||||
|
query.where("artwork.id = ?").bind(getId());
|
||||||
|
|
||||||
|
return utils::fetchQuerySingleResult(query);
|
||||||
|
}
|
||||||
} // namespace lms::db
|
} // namespace lms::db
|
||||||
|
|||||||
@@ -234,6 +234,7 @@ namespace lms::db
|
|||||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_embedded_image_link_id_idx ON track_embedded_image_link(id)");
|
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_embedded_image_link_id_idx ON track_embedded_image_link(id)");
|
||||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_embedded_image_link_track_id_idx ON track_embedded_image_link(track_id)");
|
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_embedded_image_link_track_id_idx ON track_embedded_image_link(track_id)");
|
||||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_embedded_image_link_track_embedded_image_id_track_id_idx ON track_embedded_image_link(track_embedded_image_id, track_id)");
|
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_embedded_image_link_track_embedded_image_id_track_id_idx ON track_embedded_image_link(track_embedded_image_id, track_id)");
|
||||||
|
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_embedded_image_link_track_type_track_embedded_image_id_idx ON track_embedded_image_link(track_id, type, track_embedded_image_id)");
|
||||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_embedded_image_link_type_track_embedded_image_id_track_id_idx ON track_embedded_image_link(type,track_embedded_image_id,track_id)");
|
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_embedded_image_link_type_track_embedded_image_id_track_id_idx ON track_embedded_image_link(type,track_embedded_image_id,track_id)");
|
||||||
|
|
||||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS image_directory_stem_idx ON image(directory_id, stem COLLATE NOCASE)");
|
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS image_directory_stem_idx ON image(directory_id, stem COLLATE NOCASE)");
|
||||||
|
|||||||
@@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
#include <Wt/Dbo/Dbo.h>
|
#include <Wt/Dbo/Dbo.h>
|
||||||
#include <Wt/WDateTime.h>
|
#include <Wt/WDateTime.h>
|
||||||
|
|
||||||
@@ -48,6 +50,7 @@ namespace lms::db
|
|||||||
TrackEmbeddedImageId getTrackEmbeddedImageId() const { return _trackEmbeddedImage.id(); }
|
TrackEmbeddedImageId getTrackEmbeddedImageId() const { return _trackEmbeddedImage.id(); }
|
||||||
ImageId getImageId() const { return _image.id(); }
|
ImageId getImageId() const { return _image.id(); }
|
||||||
Wt::WDateTime getLastWrittenTime() const;
|
Wt::WDateTime getLastWrittenTime() const;
|
||||||
|
std::filesystem::path getAbsoluteFilePath() const;
|
||||||
|
|
||||||
template<class Action>
|
template<class Action>
|
||||||
void persist(Action& a)
|
void persist(Action& a)
|
||||||
|
|||||||
@@ -40,8 +40,6 @@ namespace lms::db
|
|||||||
public:
|
public:
|
||||||
TrackEmbeddedImageLink() = default;
|
TrackEmbeddedImageLink() = default;
|
||||||
|
|
||||||
using HashType = std::uint64_t;
|
|
||||||
|
|
||||||
// find
|
// find
|
||||||
static std::size_t getCount(Session& session);
|
static std::size_t getCount(Session& session);
|
||||||
static pointer find(Session& session, TrackEmbeddedImageLinkId id);
|
static pointer find(Session& session, TrackEmbeddedImageLinkId id);
|
||||||
|
|||||||
@@ -48,11 +48,13 @@ namespace lms::db::tests
|
|||||||
{
|
{
|
||||||
auto transaction{ session.createWriteTransaction() };
|
auto transaction{ session.createWriteTransaction() };
|
||||||
image.get().modify()->setLastWriteTime(dateTime);
|
image.get().modify()->setLastWriteTime(dateTime);
|
||||||
|
image.get().modify()->setAbsoluteFilePath("/tmp/foo");
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto transaction{ session.createReadTransaction() };
|
auto transaction{ session.createReadTransaction() };
|
||||||
EXPECT_EQ(artwork.get()->getLastWrittenTime(), dateTime);
|
EXPECT_EQ(artwork.get()->getLastWrittenTime(), dateTime);
|
||||||
|
EXPECT_EQ(artwork.get()->getAbsoluteFilePath(), "/tmp/foo");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,11 +75,13 @@ namespace lms::db::tests
|
|||||||
auto transaction{ session.createWriteTransaction() };
|
auto transaction{ session.createWriteTransaction() };
|
||||||
session.create<db::TrackEmbeddedImageLink>(track.get(), image.get());
|
session.create<db::TrackEmbeddedImageLink>(track.get(), image.get());
|
||||||
track.get().modify()->setLastWriteTime(dateTime);
|
track.get().modify()->setLastWriteTime(dateTime);
|
||||||
|
track.get().modify()->setAbsoluteFilePath("/tmp/foo");
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto transaction{ session.createReadTransaction() };
|
auto transaction{ session.createReadTransaction() };
|
||||||
EXPECT_EQ(artwork.get()->getLastWrittenTime(), dateTime);
|
EXPECT_EQ(artwork.get()->getLastWrittenTime(), dateTime);
|
||||||
|
EXPECT_EQ(artwork.get()->getAbsoluteFilePath(), "/tmp/foo");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // namespace lms::db::tests
|
} // namespace lms::db::tests
|
||||||
@@ -27,34 +27,6 @@
|
|||||||
|
|
||||||
namespace lms::scanner::utils
|
namespace lms::scanner::utils
|
||||||
{
|
{
|
||||||
namespace
|
|
||||||
{
|
|
||||||
std::filesystem::path toPath(db::Session& session, const db::TrackEmbeddedImageId trackEmbeddedImageId)
|
|
||||||
{
|
|
||||||
session.checkReadTransaction();
|
|
||||||
|
|
||||||
std::filesystem::path res;
|
|
||||||
|
|
||||||
db::Track::FindParameters params;
|
|
||||||
params.setEmbeddedImage(trackEmbeddedImageId);
|
|
||||||
params.setRange(db::Range{ .offset = 0, .size = 1 });
|
|
||||||
db::Track::find(session, params, [&](const db::Track::pointer& track) {
|
|
||||||
res = track->getAbsoluteFilePath();
|
|
||||||
});
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::filesystem::path toPath(db::Session& session, db::ImageId imageId)
|
|
||||||
{
|
|
||||||
session.checkReadTransaction();
|
|
||||||
|
|
||||||
db::Image::pointer image{ db::Image::find(session, imageId) };
|
|
||||||
return image ? image->getAbsoluteFilePath() : std::filesystem::path{};
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
db::ObjectPtr<db::Artwork> getOrCreateArtworkFromTrackEmbeddedImage(db::Session& session, db::TrackEmbeddedImageId trackEmbeddedImageId)
|
db::ObjectPtr<db::Artwork> getOrCreateArtworkFromTrackEmbeddedImage(db::Session& session, db::TrackEmbeddedImageId trackEmbeddedImageId)
|
||||||
{
|
{
|
||||||
assert(trackEmbeddedImageId.isValid());
|
assert(trackEmbeddedImageId.isValid());
|
||||||
@@ -84,21 +56,4 @@ namespace lms::scanner::utils
|
|||||||
}
|
}
|
||||||
return artwork;
|
return artwork;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::filesystem::path toPath(db::Session& session, db::ArtworkId artworkId)
|
|
||||||
{
|
|
||||||
session.checkReadTransaction();
|
|
||||||
|
|
||||||
db::Artwork::pointer artwork{ db::Artwork::find(session, artworkId) };
|
|
||||||
if (!artwork)
|
|
||||||
return std::filesystem::path{};
|
|
||||||
|
|
||||||
if (artwork->getTrackEmbeddedImageId().isValid())
|
|
||||||
return toPath(session, artwork->getTrackEmbeddedImageId());
|
|
||||||
if (artwork->getImageId().isValid())
|
|
||||||
return toPath(session, artwork->getImageId());
|
|
||||||
|
|
||||||
return std::filesystem::path{};
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace lms::scanner::utils
|
} // namespace lms::scanner::utils
|
||||||
@@ -36,6 +36,4 @@ namespace lms::scanner::utils
|
|||||||
{
|
{
|
||||||
db::ObjectPtr<db::Artwork> getOrCreateArtworkFromTrackEmbeddedImage(db::Session& session, db::TrackEmbeddedImageId trackEmbeddedImageId);
|
db::ObjectPtr<db::Artwork> getOrCreateArtworkFromTrackEmbeddedImage(db::Session& session, db::TrackEmbeddedImageId trackEmbeddedImageId);
|
||||||
db::ObjectPtr<db::Artwork> getOrCreateArtworkFromImage(db::Session& session, db::ImageId imageId);
|
db::ObjectPtr<db::Artwork> getOrCreateArtworkFromImage(db::Session& session, db::ImageId imageId);
|
||||||
|
|
||||||
std::filesystem::path toPath(db::Session& session, db::ArtworkId artworkId);
|
|
||||||
} // namespace lms::scanner::utils
|
} // namespace lms::scanner::utils
|
||||||
@@ -271,7 +271,7 @@ namespace lms::scanner
|
|||||||
|
|
||||||
artist.modify()->setPreferredArtwork(artwork);
|
artist.modify()->setPreferredArtwork(artwork);
|
||||||
if (artwork)
|
if (artwork)
|
||||||
LMS_LOG(DBUPDATER, DEBUG, "Updated preferred artwork for artist '" << artist->getName() << "' with image in " << utils::toPath(session, artwork->getId()));
|
LMS_LOG(DBUPDATER, DEBUG, "Updated preferred artwork for artist '" << artist->getName() << "' with image in " << artwork->getAbsoluteFilePath());
|
||||||
else
|
else
|
||||||
LMS_LOG(DBUPDATER, DEBUG, "Removed preferred artwork from artist '" << artist->getName() << "'");
|
LMS_LOG(DBUPDATER, DEBUG, "Removed preferred artwork from artist '" << artist->getName() << "'");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -222,7 +222,7 @@ namespace lms::scanner
|
|||||||
release.modify()->setPreferredArtwork(artwork);
|
release.modify()->setPreferredArtwork(artwork);
|
||||||
|
|
||||||
if (artwork)
|
if (artwork)
|
||||||
LMS_LOG(DBUPDATER, DEBUG, "Updated preferred artwork in release '" << release->getName() << "' with image in " << utils::toPath(session, artwork->getId()));
|
LMS_LOG(DBUPDATER, DEBUG, "Updated preferred artwork in release '" << release->getName() << "' with image in " << artwork->getAbsoluteFilePath());
|
||||||
else
|
else
|
||||||
LMS_LOG(DBUPDATER, DEBUG, "Removed preferred artwork from release '" << release->getName() << "'");
|
LMS_LOG(DBUPDATER, DEBUG, "Removed preferred artwork from release '" << release->getName() << "'");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,10 +49,16 @@ namespace lms::scanner
|
|||||||
return !artwork;
|
return !artwork;
|
||||||
|
|
||||||
if (const db::TrackEmbeddedImageId* trackEmbeddedImageId = std::get_if<db::TrackEmbeddedImageId>(&preferredArtwork))
|
if (const db::TrackEmbeddedImageId* trackEmbeddedImageId = std::get_if<db::TrackEmbeddedImageId>(&preferredArtwork))
|
||||||
|
{
|
||||||
|
assert(trackEmbeddedImageId->isValid());
|
||||||
return artwork && *trackEmbeddedImageId == artwork->getTrackEmbeddedImageId();
|
return artwork && *trackEmbeddedImageId == artwork->getTrackEmbeddedImageId();
|
||||||
|
}
|
||||||
|
|
||||||
if (const db::ArtworkId* artworkId = std::get_if<db::ArtworkId>(&preferredArtwork))
|
if (const db::ArtworkId* artworkId = std::get_if<db::ArtworkId>(&preferredArtwork))
|
||||||
|
{
|
||||||
|
assert(artworkId->isValid());
|
||||||
return artwork && *artworkId == artwork->getId();
|
return artwork && *artworkId == artwork->getId();
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -77,36 +83,9 @@ namespace lms::scanner
|
|||||||
std::size_t processedTrackCount{};
|
std::size_t processedTrackCount{};
|
||||||
};
|
};
|
||||||
|
|
||||||
TrackArtwork computePreferredTrackArtwork(SearchTrackArtworkContext& searchContext, const db::Track::pointer& track)
|
TrackArtwork computePreferredTrackArtwork(SearchTrackArtworkContext& searchContext, const db::Track::pointer& track, TrackArtwork preferredMediaArtwork)
|
||||||
{
|
{
|
||||||
// Try to get a media image
|
TrackArtwork res{ preferredMediaArtwork };
|
||||||
TrackArtwork res;
|
|
||||||
{
|
|
||||||
db::TrackEmbeddedImage::FindParameters params;
|
|
||||||
params.setTrack(track->getId());
|
|
||||||
params.setImageTypes({ db::ImageType::Media });
|
|
||||||
params.setSortMethod(db::TrackEmbeddedImageSortMethod::SizeDesc);
|
|
||||||
params.setRange(db::Range{ .offset = 0, .size = 1 });
|
|
||||||
db::TrackEmbeddedImage::find(searchContext.session, params, [&](const db::TrackEmbeddedImage::pointer& image) { res = image->getId(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isValid(res))
|
|
||||||
return res;
|
|
||||||
|
|
||||||
// Fallback on another track of the same disc
|
|
||||||
const db::ReleaseId releaseId{ track->getReleaseId() };
|
|
||||||
if (!releaseId.isValid())
|
|
||||||
return res;
|
|
||||||
|
|
||||||
{
|
|
||||||
db::TrackEmbeddedImage::FindParameters params;
|
|
||||||
params.setRelease(releaseId);
|
|
||||||
params.setDiscNumber(track->getDiscNumber());
|
|
||||||
params.setImageTypes({ db::ImageType::Media });
|
|
||||||
params.setSortMethod(db::TrackEmbeddedImageSortMethod::TrackNumberThenSizeDesc);
|
|
||||||
params.setRange(db::Range{ .offset = 0, .size = 1 });
|
|
||||||
db::TrackEmbeddedImage::find(searchContext.session, params, [&](const db::TrackEmbeddedImage::pointer& image) { res = image->getId(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isValid(res))
|
if (isValid(res))
|
||||||
return res;
|
return res;
|
||||||
@@ -125,8 +104,15 @@ namespace lms::scanner
|
|||||||
return res;
|
return res;
|
||||||
|
|
||||||
// Fallback on the artwork already resolved for the release
|
// Fallback on the artwork already resolved for the release
|
||||||
|
const db::ReleaseId releaseId{ track->getReleaseId() };
|
||||||
|
if (!releaseId.isValid())
|
||||||
|
return res;
|
||||||
|
|
||||||
if (const db::Release::pointer release{ db::Release::find(searchContext.session, releaseId) })
|
if (const db::Release::pointer release{ db::Release::find(searchContext.session, releaseId) })
|
||||||
res = release->getPreferredArtworkId();
|
{
|
||||||
|
if (const db::ArtworkId releaseArtworkId{ release->getPreferredArtworkId() }; releaseArtworkId.isValid())
|
||||||
|
res = releaseArtworkId;
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -147,11 +133,15 @@ namespace lms::scanner
|
|||||||
return res;
|
return res;
|
||||||
|
|
||||||
// fallback on another track of the same disc
|
// fallback on another track of the same disc
|
||||||
if (const db::ReleaseId releaseId{ track->getReleaseId() }; releaseId.isValid())
|
const db::ReleaseId releaseId{ track->getReleaseId() };
|
||||||
|
if (!releaseId.isValid())
|
||||||
|
return res;
|
||||||
|
|
||||||
|
if (const auto discNumber{ track->getDiscNumber() })
|
||||||
{
|
{
|
||||||
db::TrackEmbeddedImage::FindParameters params;
|
db::TrackEmbeddedImage::FindParameters params;
|
||||||
params.setRelease(releaseId);
|
params.setRelease(releaseId);
|
||||||
params.setDiscNumber(track->getDiscNumber());
|
params.setDiscNumber(discNumber);
|
||||||
params.setImageTypes({ db::ImageType::Media });
|
params.setImageTypes({ db::ImageType::Media });
|
||||||
params.setSortMethod(db::TrackEmbeddedImageSortMethod::TrackNumberThenSizeDesc);
|
params.setSortMethod(db::TrackEmbeddedImageSortMethod::TrackNumberThenSizeDesc);
|
||||||
params.setRange(db::Range{ .offset = 0, .size = 1 });
|
params.setRange(db::Range{ .offset = 0, .size = 1 });
|
||||||
@@ -171,8 +161,8 @@ namespace lms::scanner
|
|||||||
auto transaction{ searchContext.session.createReadTransaction() };
|
auto transaction{ searchContext.session.createReadTransaction() };
|
||||||
|
|
||||||
db::Track::find(searchContext.session, searchContext.lastRetrievedTrackId, readBatchSize, [&](const db::Track::pointer& track) {
|
db::Track::find(searchContext.session, searchContext.lastRetrievedTrackId, readBatchSize, [&](const db::Track::pointer& track) {
|
||||||
const TrackArtwork preferredArtwork{ computePreferredTrackArtwork(searchContext, track) };
|
|
||||||
const TrackArtwork preferredMediaArtwork{ computePreferredTrackMediaArtwork(searchContext, track) };
|
const TrackArtwork preferredMediaArtwork{ computePreferredTrackMediaArtwork(searchContext, track) };
|
||||||
|
const TrackArtwork preferredArtwork{ computePreferredTrackArtwork(searchContext, track, preferredMediaArtwork) };
|
||||||
|
|
||||||
const db::Artwork::pointer currentPreferredArtwork{ track->getPreferredArtwork() };
|
const db::Artwork::pointer currentPreferredArtwork{ track->getPreferredArtwork() };
|
||||||
const db::Artwork::pointer currentPreferredMediaArtwork{ track->getPreferredMediaArtwork() };
|
const db::Artwork::pointer currentPreferredMediaArtwork{ track->getPreferredMediaArtwork() };
|
||||||
@@ -180,7 +170,7 @@ namespace lms::scanner
|
|||||||
if (!isSameArtwork(preferredArtwork, currentPreferredArtwork)
|
if (!isSameArtwork(preferredArtwork, currentPreferredArtwork)
|
||||||
|| !isSameArtwork(preferredMediaArtwork, currentPreferredMediaArtwork))
|
|| !isSameArtwork(preferredMediaArtwork, currentPreferredMediaArtwork))
|
||||||
{
|
{
|
||||||
TrackArtworksAssociations.push_back(TrackArtworksAssociation{ track, preferredArtwork, preferredMediaArtwork });
|
TrackArtworksAssociations.push_back(TrackArtworksAssociation{ .track = track, .preferredArtwork = preferredArtwork, .preferredMediaArtwork = preferredMediaArtwork });
|
||||||
}
|
}
|
||||||
|
|
||||||
searchContext.processedTrackCount++;
|
searchContext.processedTrackCount++;
|
||||||
@@ -201,7 +191,7 @@ namespace lms::scanner
|
|||||||
// Using track.modify() is quite CPU intensive as the track class has too many fields
|
// Using track.modify() is quite CPU intensive as the track class has too many fields
|
||||||
db::Track::updatePreferredArtwork(session, track->getId(), artwork ? artwork->getId() : db::ArtworkId{});
|
db::Track::updatePreferredArtwork(session, track->getId(), artwork ? artwork->getId() : db::ArtworkId{});
|
||||||
if (artwork)
|
if (artwork)
|
||||||
LMS_LOG(DBUPDATER, DEBUG, "Updated preferred artwork in track " << track->getAbsoluteFilePath() << " with image in " << utils::toPath(session, artwork->getId()));
|
LMS_LOG(DBUPDATER, DEBUG, "Updated preferred artwork in track " << track->getAbsoluteFilePath() << " with image in " << artwork->getAbsoluteFilePath());
|
||||||
else
|
else
|
||||||
LMS_LOG(DBUPDATER, DEBUG, "Removed preferred artwork from track " << track->getAbsoluteFilePath());
|
LMS_LOG(DBUPDATER, DEBUG, "Removed preferred artwork from track " << track->getAbsoluteFilePath());
|
||||||
}
|
}
|
||||||
@@ -217,9 +207,9 @@ namespace lms::scanner
|
|||||||
// Using track.modify() is quite CPU intensive as the track class has too many fields
|
// Using track.modify() is quite CPU intensive as the track class has too many fields
|
||||||
db::Track::updatePreferredMediaArtwork(session, track->getId(), artwork ? artwork->getId() : db::ArtworkId{});
|
db::Track::updatePreferredMediaArtwork(session, track->getId(), artwork ? artwork->getId() : db::ArtworkId{});
|
||||||
if (artwork)
|
if (artwork)
|
||||||
LMS_LOG(DBUPDATER, DEBUG, "Updated preferred media artwork in track '" << track->getAbsoluteFilePath() << "' with image in " << utils::toPath(session, artwork->getId()));
|
LMS_LOG(DBUPDATER, DEBUG, "Updated preferred media artwork in track " << track->getAbsoluteFilePath() << " with image in " << artwork->getAbsoluteFilePath());
|
||||||
else
|
else
|
||||||
LMS_LOG(DBUPDATER, DEBUG, "Removed preferred media artwork from track '" << track->getAbsoluteFilePath() << "'");
|
LMS_LOG(DBUPDATER, DEBUG, "Removed preferred media artwork from track " << track->getAbsoluteFilePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateTrackPreferredArtworks(db::Session& session, const TrackArtworksAssociation& TrackArtworksAssociation)
|
void updateTrackPreferredArtworks(db::Session& session, const TrackArtworksAssociation& TrackArtworksAssociation)
|
||||||
|
|||||||
Reference in New Issue
Block a user