Do not report OpenSubsonic extra fields for selected legacy clients. This made DSub behave badly. fixes #356

This commit is contained in:
emeric
2023-11-02 23:13:41 +01:00
parent 679d3d358c
commit e339a42883
16 changed files with 90 additions and 59 deletions
+8 -5
View File
@@ -74,7 +74,7 @@ namespace API::Subsonic
}
}
Response::Node createAlbumNode(const Release::pointer& release, Session& dbSession, const User::pointer& user, bool id3)
Response::Node createAlbumNode(RequestContext& context, const Release::pointer& release, const User::pointer& user, bool id3)
{
Response::Node albumNode;
@@ -125,7 +125,7 @@ namespace API::Subsonic
}
// Report the first GENRE for this track
const ClusterType::pointer genreClusterType{ ClusterType::find(dbSession, "GENRE") };
const ClusterType::pointer genreClusterType{ ClusterType::find(context.dbSession, "GENRE") };
if (genreClusterType)
{
auto clusters{ release->getClusterGroups({genreClusterType}, 1) };
@@ -136,6 +136,9 @@ namespace API::Subsonic
if (const Wt::WDateTime dateTime{ Service<Feedback::IFeedbackService>::get()->getStarredDateTime(user->getId(), release->getId()) }; dateTime.isValid())
albumNode.setAttribute("starred", StringUtils::toISO8601String(dateTime));
if (!context.enableOpenSubsonic)
return albumNode;
// OpenSubsonic specific fields (must always be set)
if (!id3)
albumNode.setAttribute("mediaType", "album");
@@ -154,14 +157,14 @@ namespace API::Subsonic
{
albumNode.createEmptyArrayValue(field);
ClusterType::pointer clusterType{ ClusterType::find(dbSession, clusterTypeName) };
ClusterType::pointer clusterType{ ClusterType::find(context.dbSession, clusterTypeName) };
if (clusterType)
{
Cluster::FindParameters params;
params.setRelease(release->getId());
params.setClusterType(clusterType->getId());
for (const auto& cluster : Cluster::find(dbSession, params).results)
for (const auto& cluster : Cluster::find(context.dbSession, params).results)
albumNode.addArrayValue(field, std::get<std::string>(cluster));
}
} };
@@ -176,7 +179,7 @@ namespace API::Subsonic
params.setRelease(release->getId());
params.setClusterType(genreClusterType->getId());
for (const auto& cluster : Cluster::find(dbSession, params).results)
for (const auto& cluster : Cluster::find(context.dbSession, params).results)
albumNode.addArrayChild("genres", createItemGenreNode(std::get<std::string>(cluster)));
}
+1 -1
View File
@@ -31,5 +31,5 @@ namespace Database
namespace API::Subsonic
{
Response::Node createAlbumNode(const Database::ObjectPtr<Database::Release>& release, Database::Session& dbSession, const Database::ObjectPtr<Database::User>& user, bool id3);
Response::Node createAlbumNode(RequestContext& context, const Database::ObjectPtr<Database::Release>& release, const Database::ObjectPtr<Database::User>& user, bool id3);
}
+18 -15
View File
@@ -73,7 +73,7 @@ namespace API::Subsonic
}
}
Response::Node createArtistNode(const Artist::pointer& artist, Session& session, const User::pointer& user, bool id3)
Response::Node createArtistNode(RequestContext& context, const Artist::pointer& artist, const User::pointer& user, bool id3)
{
Response::Node artistNode{ createArtistNode(artist) };
@@ -82,7 +82,7 @@ namespace API::Subsonic
if (id3)
{
const auto releases{ Release::find(session, Release::FindParameters {}.setArtist(artist->getId())) };
const auto releases{ Release::find(context.dbSession, Release::FindParameters {}.setArtist(artist->getId())) };
artistNode.setAttribute("albumCount", releases.results.size());
}
@@ -90,22 +90,25 @@ namespace API::Subsonic
artistNode.setAttribute("starred", StringUtils::toISO8601String(dateTime));
// OpenSubsonic specific fields (must always be set)
if (!id3)
artistNode.setAttribute("mediaType", "artist");
if (context.enableOpenSubsonic)
{
std::optional<UUID> mbid{ artist->getMBID() };
artistNode.setAttribute("musicBrainzId", mbid ? mbid->getAsString() : "");
if (!id3)
artistNode.setAttribute("mediaType", "artist");
{
std::optional<UUID> mbid{ artist->getMBID() };
artistNode.setAttribute("musicBrainzId", mbid ? mbid->getAsString() : "");
}
artistNode.setAttribute("sortName", artist->getSortName());
// roles
Response::Node roles;
artistNode.createEmptyArrayValue("roles");
for (const TrackArtistLinkType linkType : TrackArtistLink::findUsedTypes(context.dbSession, artist->getId()))
artistNode.addArrayValue("roles", Utils::toString(linkType));
}
artistNode.setAttribute("sortName", artist->getSortName());
// roles
Response::Node roles;
artistNode.createEmptyArrayValue("roles");
for (const TrackArtistLinkType linkType : TrackArtistLink::findUsedTypes(session, artist->getId()))
artistNode.addArrayValue("roles", Utils::toString(linkType));
return artistNode;
}
+1 -1
View File
@@ -39,6 +39,6 @@ namespace API::Subsonic
std::string joinArtistNames(const std::vector<Database::ObjectPtr<Database::Artist>>& artists);
std::string_view toString(Database::TrackArtistLinkType type);
}
Response::Node createArtistNode(const Database::ObjectPtr<Database::Artist>& artist, Database::Session& session, const Database::ObjectPtr<Database::User>& user, bool id3);
Response::Node createArtistNode(RequestContext& context, const Database::ObjectPtr<Database::Artist>& artist, const Database::ObjectPtr<Database::User>& user, bool id3);
Response::Node createArtistNode(const Database::ObjectPtr<Database::Artist>& artist); // only minimal info
}
+12 -9
View File
@@ -93,7 +93,7 @@ namespace API::Subsonic
}
}
Response::Node createSongNode(const Track::pointer& track, Session& dbSession, const User::pointer& user)
Response::Node createSongNode(RequestContext& context, const Track::pointer& track, const User::pointer& user)
{
Response::Node trackResponse;
@@ -153,7 +153,7 @@ namespace API::Subsonic
trackResponse.setAttribute("starred", StringUtils::toISO8601String(dateTime));
// Report the first GENRE for this track
const ClusterType::pointer genreClusterType{ ClusterType::find(dbSession, "GENRE") };
const ClusterType::pointer genreClusterType{ ClusterType::find(context.dbSession, "GENRE") };
if (genreClusterType)
{
auto clusters{ track->getClusterGroups({genreClusterType}, 1) };
@@ -162,6 +162,9 @@ namespace API::Subsonic
}
// OpenSubsonic specific fields (must always be set)
if (!context.enableOpenSubsonic)
return trackResponse;
trackResponse.setAttribute("mediaType", "song");
{
@@ -179,9 +182,9 @@ namespace API::Subsonic
TrackArtistLink::FindParameters params;
params.setTrack(track->getId());
for (const TrackArtistLinkId linkId : TrackArtistLink::find(dbSession, params).results)
for (const TrackArtistLinkId linkId : TrackArtistLink::find(context.dbSession, params).results)
{
TrackArtistLink::pointer link{ TrackArtistLink::find(dbSession, linkId) };
TrackArtistLink::pointer link{ TrackArtistLink::find(context.dbSession, linkId) };
// Don't report artists nor release artists as they are set in dedicated fields
if (link && link->getType() != TrackArtistLinkType::Artist && link->getType() != TrackArtistLinkType::ReleaseArtist)
trackResponse.addArrayChild("contributors", createContributorNode(link));
@@ -196,9 +199,9 @@ namespace API::Subsonic
params.setTrack(track->getId());
params.setLinkType(type);
for (const TrackArtistLinkId linkId : TrackArtistLink::find(dbSession, params).results)
for (const TrackArtistLinkId linkId : TrackArtistLink::find(context.dbSession, params).results)
{
TrackArtistLink::pointer link{ TrackArtistLink::find(dbSession, linkId) };
TrackArtistLink::pointer link{ TrackArtistLink::find(context.dbSession, linkId) };
if (link)
trackResponse.addArrayChild(nodeName, createArtistNode(link->getArtist()));
}
@@ -215,14 +218,14 @@ namespace API::Subsonic
{
trackResponse.createEmptyArrayValue(field);
ClusterType::pointer clusterType{ ClusterType::find(dbSession, clusterTypeName) };
ClusterType::pointer clusterType{ ClusterType::find(context.dbSession, clusterTypeName) };
if (clusterType)
{
Cluster::FindParameters params;
params.setTrack(track->getId());
params.setClusterType(clusterType->getId());
for (const auto& cluster : Cluster::find(dbSession, params).results)
for (const auto& cluster : Cluster::find(context.dbSession, params).results)
trackResponse.addArrayValue(field, std::get<std::string>(cluster));
}
} };
@@ -237,7 +240,7 @@ namespace API::Subsonic
params.setTrack(track->getId());
params.setClusterType(genreClusterType->getId());
for (const auto& cluster : Cluster::find(dbSession, params).results)
for (const auto& cluster : Cluster::find(context.dbSession, params).results)
trackResponse.addArrayChild("genres", createItemGenreNode(std::get<std::string>(cluster)));
}
+1 -1
View File
@@ -31,5 +31,5 @@ namespace Database
namespace API::Subsonic
{
Response::Node createSongNode(const Database::ObjectPtr<Database::Track>& track, Database::Session& session, const Database::ObjectPtr<Database::User>& user);
Response::Node createSongNode(RequestContext& context, const Database::ObjectPtr<Database::Track>& track, const Database::ObjectPtr<Database::User>& user);
}