Centralized artwork lookup logic for playlists
This commit is contained in:
@@ -260,6 +260,26 @@ namespace lms::cover
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ArtworkService::ImageFindResult ArtworkService::findTrackListImage(db::TrackListId trackListId)
|
||||||
|
{
|
||||||
|
db::Session& session{ _db.getTLSSession() };
|
||||||
|
auto transaction{ session.createReadTransaction() };
|
||||||
|
|
||||||
|
ImageFindResult res;
|
||||||
|
|
||||||
|
db::TrackEmbeddedImage::FindParameters params;
|
||||||
|
params.setTrackList(trackListId);
|
||||||
|
params.setIsPreferred(true);
|
||||||
|
params.setSortMethod(db::TrackEmbeddedImageSortMethod::FrontCoverAndSize);
|
||||||
|
params.setRange(db::Range{ .offset = 0, .size = 1 });
|
||||||
|
|
||||||
|
db::TrackEmbeddedImage::find(session, params, [&](const db::TrackEmbeddedImage::pointer& image) {
|
||||||
|
res = image->getId();
|
||||||
|
});
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<image::IEncodedImage> ArtworkService::getImage(db::ImageId imageId, std::optional<image::ImageSize> width)
|
std::shared_ptr<image::IEncodedImage> ArtworkService::getImage(db::ImageId imageId, std::optional<image::ImageSize> width)
|
||||||
{
|
{
|
||||||
const ImageCache::EntryDesc cacheEntryDesc{ imageId, width };
|
const ImageCache::EntryDesc cacheEntryDesc{ imageId, width };
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ namespace lms::cover
|
|||||||
ImageFindResult findArtistImage(db::ArtistId artistId) override;
|
ImageFindResult findArtistImage(db::ArtistId artistId) override;
|
||||||
ImageFindResult findPreferredTrackImage(db::TrackId trackId) override;
|
ImageFindResult findPreferredTrackImage(db::TrackId trackId) override;
|
||||||
ImageFindResult findReleaseImage(db::ReleaseId releaseId) override;
|
ImageFindResult findReleaseImage(db::ReleaseId releaseId) override;
|
||||||
|
ImageFindResult findTrackListImage(db::TrackListId trackListId) override;
|
||||||
|
|
||||||
std::shared_ptr<image::IEncodedImage> getImage(db::ImageId imageId, std::optional<image::ImageSize> width) override;
|
std::shared_ptr<image::IEncodedImage> getImage(db::ImageId imageId, std::optional<image::ImageSize> width) override;
|
||||||
std::shared_ptr<image::IEncodedImage> getTrackEmbeddedImage(db::TrackEmbeddedImageId trackEmbeddedImageId, std::optional<image::ImageSize> width) override;
|
std::shared_ptr<image::IEncodedImage> getTrackEmbeddedImage(db::TrackEmbeddedImageId trackEmbeddedImageId, std::optional<image::ImageSize> width) override;
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include "database/ReleaseId.hpp"
|
#include "database/ReleaseId.hpp"
|
||||||
#include "database/TrackEmbeddedImageId.hpp"
|
#include "database/TrackEmbeddedImageId.hpp"
|
||||||
#include "database/TrackId.hpp"
|
#include "database/TrackId.hpp"
|
||||||
|
#include "database/TrackListId.hpp"
|
||||||
#include "image/IEncodedImage.hpp"
|
#include "image/IEncodedImage.hpp"
|
||||||
|
|
||||||
namespace lms::db
|
namespace lms::db
|
||||||
@@ -48,6 +49,7 @@ namespace lms::cover
|
|||||||
virtual ImageFindResult findArtistImage(db::ArtistId artistId) = 0;
|
virtual ImageFindResult findArtistImage(db::ArtistId artistId) = 0;
|
||||||
virtual ImageFindResult findPreferredTrackImage(db::TrackId trackId) = 0;
|
virtual ImageFindResult findPreferredTrackImage(db::TrackId trackId) = 0;
|
||||||
virtual ImageFindResult findReleaseImage(db::ReleaseId releaseId) = 0;
|
virtual ImageFindResult findReleaseImage(db::ReleaseId releaseId) = 0;
|
||||||
|
virtual ImageFindResult findTrackListImage(db::TrackListId trackListId) = 0;
|
||||||
|
|
||||||
// Image retrieval
|
// Image retrieval
|
||||||
virtual std::shared_ptr<image::IEncodedImage> getImage(db::ImageId imageId, std::optional<image::ImageSize> width) = 0;
|
virtual std::shared_ptr<image::IEncodedImage> getImage(db::ImageId imageId, std::optional<image::ImageSize> width) = 0;
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ namespace lms::api::subsonic
|
|||||||
Response::Node& playlistsNode{ response.createNode("playlists") };
|
Response::Node& playlistsNode{ response.createNode("playlists") };
|
||||||
|
|
||||||
auto addTrackList{ [&](const db::TrackList::pointer& trackList) {
|
auto addTrackList{ [&](const db::TrackList::pointer& trackList) {
|
||||||
playlistsNode.addArrayChild("playlist", createPlaylistNode(trackList, context.dbSession));
|
playlistsNode.addArrayChild("playlist", createPlaylistNode(context, trackList));
|
||||||
} };
|
} };
|
||||||
|
|
||||||
// First add user's playlists
|
// First add user's playlists
|
||||||
@@ -104,7 +104,7 @@ namespace lms::api::subsonic
|
|||||||
throw RequestedDataNotFoundError{};
|
throw RequestedDataNotFoundError{};
|
||||||
|
|
||||||
Response response{ Response::createOkResponse(context.serverProtocolVersion) };
|
Response response{ Response::createOkResponse(context.serverProtocolVersion) };
|
||||||
Response::Node playlistNode{ createPlaylistNode(trackList, context.dbSession) };
|
Response::Node playlistNode{ createPlaylistNode(context, trackList) };
|
||||||
|
|
||||||
auto entries{ trackList->getEntries() };
|
auto entries{ trackList->getEntries() };
|
||||||
for (const TrackListEntry::pointer& entry : entries.results)
|
for (const TrackListEntry::pointer& entry : entries.results)
|
||||||
@@ -157,7 +157,7 @@ namespace lms::api::subsonic
|
|||||||
}
|
}
|
||||||
|
|
||||||
Response response{ Response::createOkResponse(context.serverProtocolVersion) };
|
Response response{ Response::createOkResponse(context.serverProtocolVersion) };
|
||||||
Response::Node playlistNode{ createPlaylistNode(trackList, context.dbSession) };
|
Response::Node playlistNode{ createPlaylistNode(context, trackList) };
|
||||||
|
|
||||||
auto entries{ trackList->getEntries() };
|
auto entries{ trackList->getEntries() };
|
||||||
for (const TrackListEntry::pointer& entry : entries.results)
|
for (const TrackListEntry::pointer& entry : entries.results)
|
||||||
|
|||||||
@@ -19,17 +19,20 @@
|
|||||||
|
|
||||||
#include "Playlist.hpp"
|
#include "Playlist.hpp"
|
||||||
|
|
||||||
|
#include "core/Service.hpp"
|
||||||
#include "core/String.hpp"
|
#include "core/String.hpp"
|
||||||
#include "database/TrackEmbeddedImage.hpp"
|
#include "database/Image.hpp"
|
||||||
#include "database/TrackList.hpp"
|
#include "database/TrackList.hpp"
|
||||||
#include "database/User.hpp"
|
#include "database/User.hpp"
|
||||||
|
#include "services/artwork/IArtworkService.hpp"
|
||||||
|
|
||||||
#include "CoverArtId.hpp"
|
#include "CoverArtId.hpp"
|
||||||
|
#include "RequestContext.hpp"
|
||||||
#include "SubsonicId.hpp"
|
#include "SubsonicId.hpp"
|
||||||
|
|
||||||
namespace lms::api::subsonic
|
namespace lms::api::subsonic
|
||||||
{
|
{
|
||||||
Response::Node createPlaylistNode(const db::TrackList::pointer& tracklist, db::Session& session)
|
Response::Node createPlaylistNode(RequestContext& context, const db::TrackList::pointer& tracklist)
|
||||||
{
|
{
|
||||||
Response::Node playlistNode;
|
Response::Node playlistNode;
|
||||||
|
|
||||||
@@ -43,16 +46,19 @@ namespace lms::api::subsonic
|
|||||||
if (const db::User::pointer user{ tracklist->getUser() })
|
if (const db::User::pointer user{ tracklist->getUser() })
|
||||||
playlistNode.setAttribute("owner", user->getLoginName());
|
playlistNode.setAttribute("owner", user->getLoginName());
|
||||||
|
|
||||||
db::TrackEmbeddedImage::FindParameters params;
|
{
|
||||||
params.setTrackList(tracklist->getId());
|
const auto imageResult{ core::Service<cover::IArtworkService>::get()->findTrackListImage(tracklist->getId()) };
|
||||||
params.setIsPreferred(true);
|
if (const db::ImageId * imageId{ std::get_if<db::ImageId>(&imageResult) })
|
||||||
params.setSortMethod(db::TrackEmbeddedImageSortMethod::FrontCoverAndSize);
|
{
|
||||||
params.setRange(db::Range{ .offset = 0, .size = 1 });
|
if (const db::Image::pointer image{ db::Image::find(context.dbSession, *imageId) })
|
||||||
|
{
|
||||||
db::TrackEmbeddedImage::find(session, params, [&](const db::TrackEmbeddedImage::pointer& image) {
|
const CoverArtId coverArtId{ *imageId, image->getLastWriteTime().toTime_t() };
|
||||||
const CoverArtId coverArtId{ image->getId() };
|
playlistNode.setAttribute("coverArt", idToString(coverArtId));
|
||||||
playlistNode.setAttribute("coverArt", idToString(coverArtId));
|
}
|
||||||
});
|
}
|
||||||
|
else if (const db::TrackEmbeddedImageId * embeddedImageId{ std::get_if<db::TrackEmbeddedImageId>(&imageResult) })
|
||||||
|
playlistNode.setAttribute("coverArt", idToString(*embeddedImageId));
|
||||||
|
}
|
||||||
|
|
||||||
return playlistNode;
|
return playlistNode;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,10 +26,11 @@
|
|||||||
namespace lms::db
|
namespace lms::db
|
||||||
{
|
{
|
||||||
class TrackList;
|
class TrackList;
|
||||||
class Session;
|
|
||||||
} // namespace lms::db
|
} // namespace lms::db
|
||||||
|
|
||||||
namespace lms::api::subsonic
|
namespace lms::api::subsonic
|
||||||
{
|
{
|
||||||
Response::Node createPlaylistNode(const db::ObjectPtr<db::TrackList>& tracklist, db::Session& session);
|
struct RequestContext;
|
||||||
}
|
|
||||||
|
Response::Node createPlaylistNode(RequestContext& context, const db::ObjectPtr<db::TrackList>& tracklist);
|
||||||
|
} // namespace lms::api::subsonic
|
||||||
Reference in New Issue
Block a user