Now using new artwork table everywhere in app and subsonic API to refer to artworks
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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() })
|
||||
|
||||
@@ -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())) };
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 }) };
|
||||
|
||||
Reference in New Issue
Block a user