Now using new artwork table everywhere in app and subsonic API to refer to artworks

This commit is contained in:
emeric
2025-06-22 16:49:54 +02:00
parent 93b446e124
commit c251c2a924
34 changed files with 475 additions and 478 deletions
+19 -44
View File
@@ -22,8 +22,7 @@
#include <cassert>
#include "core/String.hpp"
#include "database/ImageId.hpp"
#include "database/TrackEmbeddedImageId.hpp"
#include "database/ArtworkId.hpp"
namespace lms::api::subsonic
{
@@ -31,14 +30,9 @@ namespace lms::api::subsonic
{
constexpr char timestampSeparatorChar{ '-' };
std::string idToString(db::ImageId id)
std::string idToString(db::ArtworkId id)
{
return "im-" + id.toString();
}
std::string idToString(db::TrackEmbeddedImageId id)
{
return "trim-" + id.toString();
return "art-" + id.toString();
}
} // namespace
@@ -46,19 +40,10 @@ namespace lms::api::subsonic
{
std::string res;
// produce "type-id[-timestamp]"
if (db::TrackEmbeddedImageId * imageId{ std::get_if<db::TrackEmbeddedImageId>(&coverId.id) })
{
res = idToString(*imageId);
assert(!coverId.timestamp.has_value());
}
else if (db::ImageId * imageId{ std::get_if<db::ImageId>(&coverId.id) })
{
res = idToString(*imageId);
res += timestampSeparatorChar;
assert(coverId.timestamp.has_value());
res += std::to_string(*coverId.timestamp);
}
// produce "art-id-timestamp"
res = idToString(coverId.id);
res += timestampSeparatorChar;
res += std::to_string(coverId.timestamp);
assert(!res.empty());
return res;
@@ -74,30 +59,20 @@ namespace lms::core::stringUtils
std::optional<api::subsonic::CoverArtId> res;
std::vector<std::string_view> values{ core::stringUtils::splitString(str, '-') };
if (values.size() <= 1)
// expect "art-id-timestamp"
if (values.size() != 3)
return res;
if (values[0] != "art")
return res;
const auto value{ core::stringUtils::readAs<db::ArtworkId::ValueType>(values[1]) };
const auto timestamp{ core::stringUtils::readAs<std::time_t>(values[2]) };
if (!value || !timestamp)
return std::nullopt;
if (values[0] == "trim")
{
// expect "trim-id"
if (values.size() == 2)
{
if (const auto value{ core::stringUtils::readAs<db::TrackEmbeddedImageId::ValueType>(values[1]) })
res.emplace(db::TrackEmbeddedImageId{ *value });
}
}
else if (values[0] == "im")
{
// expect "im-id-timestamp"
if (values.size() == 3)
{
const auto imageId{ core::stringUtils::readAs<db::ImageId::ValueType>(values[1]) };
const auto timestamp{ core::stringUtils::readAs<std::time_t>(values[2]) };
if (imageId && timestamp)
res.emplace(db::ImageId{ *imageId }, *timestamp);
}
}
res.emplace(api::subsonic::CoverArtId{ *value, *timestamp });
return res;
}
+3 -14
View File
@@ -20,24 +20,16 @@
#pragma once
#include <ctime>
#include <variant>
#include "core/String.hpp"
#include "database/ImageId.hpp"
#include "database/TrackEmbeddedImageId.hpp"
#include "database/ArtworkId.hpp"
namespace lms::api::subsonic
{
struct CoverArtId
{
std::variant<db::ImageId, db::TrackEmbeddedImageId> id;
std::optional<std::time_t> timestamp;
CoverArtId(db::ImageId _id, std::time_t _timestamp)
: id{ _id }
, timestamp{ _timestamp } {}
CoverArtId(db::TrackEmbeddedImageId _id)
: id{ _id } {}
db::ArtworkId id;
std::time_t timestamp;
};
std::string idToString(CoverArtId coverId);
@@ -46,9 +38,6 @@ namespace lms::api::subsonic
// Used to parse parameters
namespace lms::core::stringUtils
{
template<>
std::optional<db::ImageId> readAs(std::string_view str);
template<>
std::optional<api::subsonic::CoverArtId> readAs(std::string_view str);
} // namespace lms::core::stringUtils
@@ -336,12 +336,7 @@ namespace lms::api::subsonic
if (size)
*size = core::utils::clamp(*size, std::size_t{ 32 }, std::size_t{ 2048 });
std::shared_ptr<image::IEncodedImage> image;
if (const db::TrackEmbeddedImageId * trackEmbeddedImageId{ std::get_if<db::TrackEmbeddedImageId>(&coverArtId.id) })
image = core::Service<artwork::IArtworkService>::get()->getTrackEmbeddedImage(*trackEmbeddedImageId, size);
else if (const db::ImageId * imageId{ std::get_if<db::ImageId>(&coverArtId.id) })
image = core::Service<artwork::IArtworkService>::get()->getImage(*imageId, size);
std::shared_ptr<image::IEncodedImage> image{ core::Service<artwork::IArtworkService>::get()->getImage(coverArtId.id, size) };
if (!image)
{
response.setStatus(404);
+5 -13
View File
@@ -23,14 +23,13 @@
#include "core/Service.hpp"
#include "core/String.hpp"
#include "database/Artist.hpp"
#include "database/Artwork.hpp"
#include "database/Cluster.hpp"
#include "database/Directory.hpp"
#include "database/Image.hpp"
#include "database/Release.hpp"
#include "database/Track.hpp"
#include "database/Types.hpp"
#include "database/User.hpp"
#include "services/artwork/IArtworkService.hpp"
#include "services/feedback/IFeedbackService.hpp"
#include "services/scrobbling/IScrobblingService.hpp"
@@ -88,19 +87,12 @@ namespace lms::api::subsonic
albumNode.setAttribute("created", core::stringUtils::toISO8601String(release->getAddedTime()));
if (const auto artwork{ release->getPreferredArtwork() })
{
const auto imageResult{ core::Service<artwork::IArtworkService>::get()->findReleaseImage(release->getId()) };
if (const db::ImageId * imageId{ std::get_if<db::ImageId>(&imageResult) })
{
if (const db::Image::pointer image{ db::Image::find(context.dbSession, *imageId) })
{
const CoverArtId coverArtId{ *imageId, image->getLastWriteTime().toTime_t() };
albumNode.setAttribute("coverArt", idToString(coverArtId));
}
}
else if (const db::TrackEmbeddedImageId * embeddedImageId{ std::get_if<db::TrackEmbeddedImageId>(&imageResult) })
albumNode.setAttribute("coverArt", idToString(*embeddedImageId));
CoverArtId coverArtId{ artwork->getId(), artwork->getLastWrittenTime().toTime_t() };
albumNode.setAttribute("coverArt", idToString(coverArtId));
}
if (const auto originalYear{ release->getOriginalYear() })
albumNode.setAttribute("year", *originalYear);
else if (const auto year{ release->getYear() })
+4 -13
View File
@@ -23,11 +23,10 @@
#include "core/Service.hpp"
#include "core/String.hpp"
#include "database/Artist.hpp"
#include "database/Image.hpp"
#include "database/Artwork.hpp"
#include "database/Release.hpp"
#include "database/TrackArtistLink.hpp"
#include "database/User.hpp"
#include "services/artwork/IArtworkService.hpp"
#include "services/feedback/IFeedbackService.hpp"
#include "CoverArtId.hpp"
@@ -96,18 +95,10 @@ namespace lms::api::subsonic
artistNode.setAttribute("id", idToString(artist->getId()));
artistNode.setAttribute("name", artist->getName());
if (const auto artwork{ artist->getPreferredArtwork() })
{
const auto imageResult{ core::Service<artwork::IArtworkService>::get()->findArtistImage(artist->getId()) };
if (const db::ImageId * imageId{ std::get_if<db::ImageId>(&imageResult) })
{
if (const db::Image::pointer image{ db::Image::find(context.dbSession, *imageId) })
{
const CoverArtId coverArtId{ *imageId, image->getLastWriteTime().toTime_t() };
artistNode.setAttribute("coverArt", idToString(coverArtId));
}
}
else if (const db::TrackEmbeddedImageId * embeddedImageId{ std::get_if<db::TrackEmbeddedImageId>(&imageResult) })
artistNode.setAttribute("coverArt", idToString(*embeddedImageId));
CoverArtId coverArtId{ artwork->getId(), artwork->getLastWrittenTime().toTime_t() };
artistNode.setAttribute("coverArt", idToString(coverArtId));
}
const std::size_t count{ Release::getCount(context.dbSession, Release::FindParameters{}.setArtist(artist->getId())) };
+5 -10
View File
@@ -21,7 +21,7 @@
#include "core/Service.hpp"
#include "core/String.hpp"
#include "database/Image.hpp"
#include "database/Artwork.hpp"
#include "database/TrackList.hpp"
#include "database/User.hpp"
#include "services/artwork/IArtworkService.hpp"
@@ -46,18 +46,13 @@ namespace lms::api::subsonic
if (const db::User::pointer user{ tracklist->getUser() })
playlistNode.setAttribute("owner", user->getLoginName());
if (const db::ArtworkId artworkId{ core::Service<artwork::IArtworkService>::get()->findTrackListImage(tracklist->getId()) }; artworkId.isValid())
{
const auto imageResult{ core::Service<artwork::IArtworkService>::get()->findTrackListImage(tracklist->getId()) };
if (const db::ImageId * imageId{ std::get_if<db::ImageId>(&imageResult) })
if (const auto artwork{ db::Artwork::find(context.dbSession, artworkId) })
{
if (const db::Image::pointer image{ db::Image::find(context.dbSession, *imageId) })
{
const CoverArtId coverArtId{ *imageId, image->getLastWriteTime().toTime_t() };
playlistNode.setAttribute("coverArt", idToString(coverArtId));
}
CoverArtId coverArtId{ artwork->getId(), artwork->getLastWrittenTime().toTime_t() };
playlistNode.setAttribute("coverArt", idToString(coverArtId));
}
else if (const db::TrackEmbeddedImageId * embeddedImageId{ std::get_if<db::TrackEmbeddedImageId>(&imageResult) })
playlistNode.setAttribute("coverArt", idToString(*embeddedImageId));
}
return playlistNode;
+8 -14
View File
@@ -21,21 +21,19 @@
#include <string_view>
#include "av/IAudioFile.hpp"
#include "core/ITraceLogger.hpp"
#include "core/MimeTypes.hpp"
#include "core/Service.hpp"
#include "core/String.hpp"
#include "database/Artist.hpp"
#include "database/Artwork.hpp"
#include "database/Cluster.hpp"
#include "database/Directory.hpp"
#include "database/Image.hpp"
#include "database/Release.hpp"
#include "database/Track.hpp"
#include "database/TrackArtistLink.hpp"
#include "database/Types.hpp"
#include "database/User.hpp"
#include "services/artwork/IArtworkService.hpp"
#include "services/feedback/IFeedbackService.hpp"
#include "services/scrobbling/IScrobblingService.hpp"
@@ -111,18 +109,14 @@ namespace lms::api::subsonic
trackResponse.setAttribute("transcodedContentType", core::getMimeType(std::filesystem::path{ "." + fileSuffix }));
}
auto artwork{ track->getPreferredMediaArtwork() };
if (!artwork)
artwork = track->getPreferredArtwork();
if (artwork)
{
const auto imageResult{ core::Service<artwork::IArtworkService>::get()->findTrackImage(track->getId()) };
if (const db::ImageId * imageId{ std::get_if<db::ImageId>(&imageResult) })
{
if (const db::Image::pointer image{ db::Image::find(context.dbSession, *imageId) })
{
const CoverArtId coverArtId{ *imageId, image->getLastWriteTime().toTime_t() };
trackResponse.setAttribute("coverArt", idToString(coverArtId));
}
}
else if (const db::TrackEmbeddedImageId * embeddedImageId{ std::get_if<db::TrackEmbeddedImageId>(&imageResult) })
trackResponse.setAttribute("coverArt", idToString(*embeddedImageId));
CoverArtId coverArtId{ artwork->getId(), artwork->getLastWrittenTime().toTime_t() };
trackResponse.setAttribute("coverArt", idToString(coverArtId));
}
const std::vector<Artist::pointer>& artists{ track->getArtists({ TrackArtistLinkType::Artist }) };