Subsonic API: added 'contributor' in song entries
This commit is contained in:
@@ -12,6 +12,7 @@ add_library(lmssubsonic SHARED
|
|||||||
impl/responses/Album.cpp
|
impl/responses/Album.cpp
|
||||||
impl/responses/Artist.cpp
|
impl/responses/Artist.cpp
|
||||||
impl/responses/Bookmark.cpp
|
impl/responses/Bookmark.cpp
|
||||||
|
impl/responses/Contributor.cpp
|
||||||
impl/responses/Genre.cpp
|
impl/responses/Genre.cpp
|
||||||
impl/responses/Playlist.cpp
|
impl/responses/Playlist.cpp
|
||||||
impl/responses/Song.cpp
|
impl/responses/Song.cpp
|
||||||
|
|||||||
@@ -73,6 +73,15 @@ namespace API::Subsonic
|
|||||||
_children[key].emplace_back(std::move(node));
|
_children[key].emplace_back(std::move(node));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Response::Node::createEmptyArrayChild(const std::string& key)
|
||||||
|
{
|
||||||
|
if (_value)
|
||||||
|
throw LmsException{ "Node already has a value" };
|
||||||
|
|
||||||
|
_childrenArrays.emplace(key, std::vector<Node>{});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void Response::Node::addArrayChild(const std::string& key, Node node)
|
void Response::Node::addArrayChild(const std::string& key, Node node)
|
||||||
{
|
{
|
||||||
if (_value)
|
if (_value)
|
||||||
@@ -81,7 +90,7 @@ namespace API::Subsonic
|
|||||||
_childrenArrays[key].emplace_back(std::move(node));
|
_childrenArrays[key].emplace_back(std::move(node));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Response::Node::createArrayValue(const std::string& key)
|
void Response::Node::createEmptyArrayValue(const std::string& key)
|
||||||
{
|
{
|
||||||
if (_value)
|
if (_value)
|
||||||
throw LmsException{ "Node already has a value" };
|
throw LmsException{ "Node already has a value" };
|
||||||
|
|||||||
@@ -209,8 +209,9 @@ namespace API::Subsonic
|
|||||||
Node& createArrayChild(const std::string& key);
|
Node& createArrayChild(const std::string& key);
|
||||||
|
|
||||||
void addChild(const std::string& key, Node node);
|
void addChild(const std::string& key, Node node);
|
||||||
|
void createEmptyArrayChild(const std::string& key);
|
||||||
void addArrayChild(const std::string& key, Node node);
|
void addArrayChild(const std::string& key, Node node);
|
||||||
void createArrayValue(const std::string& key);
|
void createEmptyArrayValue(const std::string& key);
|
||||||
void addArrayValue(const std::string& key, std::string_view value);
|
void addArrayValue(const std::string& key, std::string_view value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -56,17 +56,17 @@ namespace API::Subsonic
|
|||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case TrackArtistLinkType::Arranger: return "arranger";
|
case TrackArtistLinkType::Arranger: return "arranger";
|
||||||
case TrackArtistLinkType::Artist: return "artist";
|
case TrackArtistLinkType::Artist: return "artist";
|
||||||
case TrackArtistLinkType::Composer: return "composer";
|
case TrackArtistLinkType::Composer: return "composer";
|
||||||
case TrackArtistLinkType::Conductor: return "conductor";
|
case TrackArtistLinkType::Conductor: return "conductor";
|
||||||
case TrackArtistLinkType::Lyricist: return "lyricist";
|
case TrackArtistLinkType::Lyricist: return "lyricist";
|
||||||
case TrackArtistLinkType::Mixer: return "mixer";
|
case TrackArtistLinkType::Mixer: return "mixer";
|
||||||
case TrackArtistLinkType::Performer: return "performer";
|
case TrackArtistLinkType::Performer: return "performer";
|
||||||
case TrackArtistLinkType::Producer: return "producrer";
|
case TrackArtistLinkType::Producer: return "producrer";
|
||||||
case TrackArtistLinkType::ReleaseArtist: return "albumartist";
|
case TrackArtistLinkType::ReleaseArtist: return "albumartist";
|
||||||
case TrackArtistLinkType::Remixer: return "remixer";
|
case TrackArtistLinkType::Remixer: return "remixer";
|
||||||
case TrackArtistLinkType::Writer: return "writer";
|
case TrackArtistLinkType::Writer: return "writer";
|
||||||
}
|
}
|
||||||
|
|
||||||
return "unknown";
|
return "unknown";
|
||||||
@@ -75,7 +75,7 @@ namespace API::Subsonic
|
|||||||
|
|
||||||
Response::Node createArtistNode(const Artist::pointer& artist, Session& session, const User::pointer& user, bool id3)
|
Response::Node createArtistNode(const Artist::pointer& artist, Session& session, const User::pointer& user, bool id3)
|
||||||
{
|
{
|
||||||
Response::Node artistNode;
|
Response::Node artistNode{ createArtistNode(artist) };
|
||||||
|
|
||||||
artistNode.setAttribute("id", idToString(artist->getId()));
|
artistNode.setAttribute("id", idToString(artist->getId()));
|
||||||
artistNode.setAttribute("name", artist->getName());
|
artistNode.setAttribute("name", artist->getName());
|
||||||
@@ -91,18 +91,28 @@ namespace API::Subsonic
|
|||||||
|
|
||||||
// OpenSubsonic specific fields (must always be set)
|
// OpenSubsonic specific fields (must always be set)
|
||||||
{
|
{
|
||||||
std::optional<UUID> mbid {artist->getMBID()};
|
std::optional<UUID> mbid{ artist->getMBID() };
|
||||||
artistNode.setAttribute("musicBrainzId", mbid ? mbid->getAsString() : "");
|
artistNode.setAttribute("musicBrainzId", mbid ? mbid->getAsString() : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
artistNode.setAttribute("sortName", artist->getSortName());
|
artistNode.setAttribute("sortName", artist->getSortName());
|
||||||
|
|
||||||
// roles
|
// roles
|
||||||
Response::Node roles;
|
Response::Node roles;
|
||||||
artistNode.createArrayValue("roles");
|
artistNode.createEmptyArrayValue("roles");
|
||||||
for (const TrackArtistLinkType linkType : TrackArtistLink::findUsedTypes(session, artist->getId()))
|
for (const TrackArtistLinkType linkType : TrackArtistLink::findUsedTypes(session, artist->getId()))
|
||||||
artistNode.addArrayValue("roles", Utils::toString(linkType));
|
artistNode.addArrayValue("roles", Utils::toString(linkType));
|
||||||
|
|
||||||
return artistNode;
|
return artistNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Response::Node createArtistNode(const Artist::pointer& artist)
|
||||||
|
{
|
||||||
|
Response::Node artistNode;
|
||||||
|
|
||||||
|
artistNode.setAttribute("id", idToString(artist->getId()));
|
||||||
|
artistNode.setAttribute("name", artist->getName());
|
||||||
|
|
||||||
|
return artistNode;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -40,4 +40,5 @@ namespace API::Subsonic
|
|||||||
std::string_view toString(Database::TrackArtistLinkType type);
|
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(const Database::ObjectPtr<Database::Artist>& artist, Database::Session& session, const Database::ObjectPtr<Database::User>& user, bool id3);
|
||||||
|
Response::Node createArtistNode(const Database::ObjectPtr<Database::Artist>& artist); // only minimal info
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Emeric Poupon
|
||||||
|
*
|
||||||
|
* This file is part of LMS.
|
||||||
|
*
|
||||||
|
* LMS is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* LMS is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "responses/Contributor.hpp"
|
||||||
|
|
||||||
|
#include "services/database/Object.hpp"
|
||||||
|
#include "services/database/TrackArtistLink.hpp"
|
||||||
|
#include "SubsonicResponse.hpp"
|
||||||
|
#include "responses/Artist.hpp"
|
||||||
|
|
||||||
|
namespace API::Subsonic
|
||||||
|
{
|
||||||
|
Response::Node createContributorNode(const Database::ObjectPtr<Database::TrackArtistLink>& trackArtistLink)
|
||||||
|
{
|
||||||
|
Response::Node contributorNode;
|
||||||
|
|
||||||
|
contributorNode.setAttribute("role", Utils::toString(trackArtistLink->getType()));
|
||||||
|
if (!trackArtistLink->getSubType().empty())
|
||||||
|
contributorNode.setAttribute("subRole", trackArtistLink->getSubType());
|
||||||
|
contributorNode.addChild("artist", createArtistNode(trackArtistLink->getArtist()));
|
||||||
|
|
||||||
|
return contributorNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Emeric Poupon
|
||||||
|
*
|
||||||
|
* This file is part of LMS.
|
||||||
|
*
|
||||||
|
* LMS is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* LMS is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "services/database/Object.hpp"
|
||||||
|
#include "SubsonicResponse.hpp"
|
||||||
|
|
||||||
|
namespace Database
|
||||||
|
{
|
||||||
|
class TrackArtistLink;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace API::Subsonic
|
||||||
|
{
|
||||||
|
Response::Node createContributorNode(const Database::ObjectPtr<Database::TrackArtistLink>& trackArtistLink);
|
||||||
|
}
|
||||||
@@ -25,11 +25,13 @@
|
|||||||
#include "services/database/Cluster.hpp"
|
#include "services/database/Cluster.hpp"
|
||||||
#include "services/database/Release.hpp"
|
#include "services/database/Release.hpp"
|
||||||
#include "services/database/Track.hpp"
|
#include "services/database/Track.hpp"
|
||||||
|
#include "services/database/TrackArtistLink.hpp"
|
||||||
#include "services/database/User.hpp"
|
#include "services/database/User.hpp"
|
||||||
#include "services/scrobbling/IScrobblingService.hpp"
|
#include "services/scrobbling/IScrobblingService.hpp"
|
||||||
#include "utils/Service.hpp"
|
#include "utils/Service.hpp"
|
||||||
#include "utils/String.hpp"
|
#include "utils/String.hpp"
|
||||||
#include "responses/Artist.hpp"
|
#include "responses/Artist.hpp"
|
||||||
|
#include "responses/Contributor.hpp"
|
||||||
#include "SubsonicId.hpp"
|
#include "SubsonicId.hpp"
|
||||||
#include "Utils.hpp"
|
#include "Utils.hpp"
|
||||||
|
|
||||||
@@ -159,6 +161,14 @@ namespace API::Subsonic
|
|||||||
trackResponse.setAttribute("musicBrainzId", mbid ? mbid->getAsString() : "");
|
trackResponse.setAttribute("musicBrainzId", mbid ? mbid->getAsString() : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trackResponse.createEmptyArrayChild("contributors");
|
||||||
|
for (const TrackArtistLinkId linkId : TrackArtistLink::find(dbSession, TrackArtistLink::FindParameters{}.setTrack(track->getId())).results)
|
||||||
|
{
|
||||||
|
TrackArtistLink::pointer link{ TrackArtistLink::find(dbSession, linkId) };
|
||||||
|
if (link)
|
||||||
|
trackResponse.addArrayChild("contributors", createContributorNode(link));
|
||||||
|
}
|
||||||
|
|
||||||
return trackResponse;
|
return trackResponse;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user