Subsonic API: Added an option to only list album artists. fixes #27

This commit is contained in:
emeric
2020-04-17 23:36:34 +02:00
parent e207f337fe
commit 9a3dcbdcbf
16 changed files with 470 additions and 21 deletions
+1
View File
@@ -11,6 +11,7 @@ add_library(lmsdatabase SHARED
impl/Session.cpp
impl/SessionPool.cpp
impl/SqlQuery.cpp
impl/SubsonicSettings.cpp
impl/Track.cpp
impl/TrackBookmark.cpp
impl/User.cpp
+14 -1
View File
@@ -31,6 +31,7 @@
#include "database/Db.hpp"
#include "database/Release.hpp"
#include "database/ScanSettings.hpp"
#include "database/SubsonicSettings.hpp"
#include "database/Track.hpp"
#include "database/TrackBookmark.hpp"
#include "database/TrackArtistLink.hpp"
@@ -40,7 +41,7 @@
namespace Database {
#define LMS_DATABASE_VERSION 18
#define LMS_DATABASE_VERSION 19
using Version = std::size_t;
@@ -206,6 +207,16 @@ CREATE TABLE "release_backup" (
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
ScanSettings::get(*this).modify()->incScanVersion();
}
else if (version == 18)
{
_session.execute(R"(
CREATE TABLE IF NOT EXISTS "subsonic_settings" (
"id" integer primary key autoincrement,
"version" integer not null,
"api_enabled" boolean not null,
"artist_list_mode" integer not null
))");
}
else
{
LMS_LOG(DB, ERROR) << "Database version " << version << " cannot be handled using migration";
@@ -228,6 +239,7 @@ Session::Session(Db& db)
_session.mapClass<ClusterType>("cluster_type");
_session.mapClass<Release>("release");
_session.mapClass<ScanSettings>("scan_settings");
_session.mapClass<SubsonicSettings>("subsonic_settings");
_session.mapClass<Track>("track");
_session.mapClass<TrackBookmark>("track_bookmark");
_session.mapClass<TrackArtistLink>("track_artist_link");
@@ -353,6 +365,7 @@ Session::prepareTables()
auto uniqueTransaction {createUniqueTransaction()};
ScanSettings::init(*this);
SubsonicSettings::init(*this);
}
}
@@ -0,0 +1,48 @@
/*
* Copyright (C) 2020 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 "database/SubsonicSettings.hpp"
#include "database/Session.hpp"
namespace Database {
void
SubsonicSettings::init(Session& session)
{
session.checkUniqueLocked();
pointer settings {get(session)};
if (settings)
return;
settings = session.getDboSession().add(std::make_unique<SubsonicSettings>());
}
SubsonicSettings::pointer
SubsonicSettings::get(Session& session)
{
session.checkSharedLocked();
return session.getDboSession().find<SubsonicSettings>();
}
} // ns Database
@@ -0,0 +1,69 @@
/*
* Copyright (C) 2020 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 <Wt/Dbo/Dbo.h>
namespace Database {
class Session;
class SubsonicSettings : public Wt::Dbo::Dbo<SubsonicSettings>
{
public:
using pointer = Wt::Dbo::ptr<SubsonicSettings>;
enum class ArtistListMode
{
AllArtists,
ReleaseArtists,
};
static inline constexpr bool defaultSubsonicAPIEnabled {true};
static inline constexpr ArtistListMode defaultArtistListMode {ArtistListMode::AllArtists};
static void init(Session& session);
static pointer get(Session& session);
// Getters
bool isAPIEnabled() const { return _isAPIEnabled; }
ArtistListMode getArtistListMode() const { return _artistListMode; }
// Setters
void setAPIEnabled(bool enabled) { _isAPIEnabled = enabled; }
void setArtistListMode(ArtistListMode mode) {_artistListMode = mode; }
template<class Action>
void persist(Action& a)
{
Wt::Dbo::field(a, _isAPIEnabled, "api_enabled");
Wt::Dbo::field(a, _artistListMode, "artist_list_mode");
}
private:
bool _isAPIEnabled {defaultSubsonicAPIEnabled};
ArtistListMode _artistListMode {defaultArtistListMode};
};
} // namespace Database
+37 -4
View File
@@ -30,6 +30,7 @@
#include "database/Db.hpp"
#include "database/Release.hpp"
#include "database/Session.hpp"
#include "database/SubsonicSettings.hpp"
#include "database/Track.hpp"
#include "database/TrackBookmark.hpp"
#include "database/TrackList.hpp"
@@ -901,7 +902,23 @@ handleGetArtistsRequest(RequestContext& context)
if (!user)
throw UserNotAuthorizedError {};
auto artists {Artist::getAll(context.dbSession, Artist::SortMethod::BySortName)};
std::optional<TrackArtistLink::Type> linkType;
switch (SubsonicSettings::get(context.dbSession)->getArtistListMode())
{
case SubsonicSettings::ArtistListMode::AllArtists:
break;
case SubsonicSettings::ArtistListMode::ReleaseArtists:
linkType = TrackArtistLink::Type::ReleaseArtist;
break;
}
bool more {};
const std::vector<Artist::pointer> artists {Artist::getByFilter(context.dbSession,
{},
{},
linkType,
Artist::SortMethod::BySortName,
{}, {}, more)};
for (const Artist::pointer& artist : artists)
indexNode.addArrayChild("artist", artistToResponseNode(user, artist, true /* id3 */));
@@ -1028,7 +1045,23 @@ handleGetIndexesRequest(RequestContext& context)
if (!user)
throw UserNotAuthorizedError {};
auto artists {Artist::getAll(context.dbSession, Artist::SortMethod::BySortName)};
std::optional<TrackArtistLink::Type> linkType;
switch (SubsonicSettings::get(context.dbSession)->getArtistListMode())
{
case SubsonicSettings::ArtistListMode::AllArtists:
break;
case SubsonicSettings::ArtistListMode::ReleaseArtists:
linkType = TrackArtistLink::Type::ReleaseArtist;
break;
}
bool more {};
const std::vector<Artist::pointer> artists {Artist::getByFilter(context.dbSession,
{},
{},
linkType,
Artist::SortMethod::BySortName,
{}, {}, more)};
for (const Artist::pointer& artist : artists)
indexNode.addArrayChild("artist", artistToResponseNode(user, artist, false /* no id3 */));
@@ -1752,7 +1785,7 @@ static std::unordered_map<std::string, RequestEntryPointInfo> requestEntryPoints
{"search", {handleNotImplemented, false}},
{"search2", {handleSearch2Request, false}},
{"search3", {handleSearch3Request, false}},
// Playlists
{"getPlaylists", {handleGetPlaylistsRequest, false}},
{"getPlaylist", {handleGetPlaylistRequest, false}},
@@ -1796,7 +1829,7 @@ static std::unordered_map<std::string, RequestEntryPointInfo> requestEntryPoints
{"createInternetRadioStation", {handleNotImplemented, false}},
{"updateInternetRadioStation", {handleNotImplemented, false}},
{"deleteInternetRadioStation", {handleNotImplemented, false}},
// Chat
{"getChatMessages", {handleNotImplemented, false}},
{"addChatMessages", {handleNotImplemented, false}},