Added relevant indexes using artist sort name. fixes #184

This commit is contained in:
emeric
2022-01-31 21:09:22 +01:00
parent 24d239f1e7
commit 1e0bf58092
2 changed files with 92 additions and 133 deletions
+91 -132
View File
@@ -953,50 +953,6 @@ handleGetArtistInfo2Request(RequestContext& context)
return handleGetArtistInfoRequestCommon(context, true /* id3 */);
}
static
Response
handleGetArtistsRequest(RequestContext& context)
{
Response response {Response::createOkResponse(context.serverProtocolVersion)};
Response::Node& artistsNode {response.createNode("artists")};
artistsNode.setAttribute("ignoredArticles", "");
artistsNode.setAttribute("lastModified", reportedDummyDateULong);
Response::Node& indexNode {artistsNode.createArrayChild("index")};
indexNode.setAttribute("name", "?");
auto transaction {context.dbSession.createSharedTransaction()};
User::pointer user {User::find(context.dbSession, context.userId)};
if (!user)
throw UserNotAuthorizedError {};
Artist::FindParameters findParameters;
findParameters.setSortMethod(ArtistSortMethod::BySortName);
switch (user->getSubsonicArtistListMode())
{
case SubsonicArtistListMode::AllArtists:
break;
case SubsonicArtistListMode::ReleaseArtists:
findParameters.setLinkType(TrackArtistLinkType::ReleaseArtist);
break;
case SubsonicArtistListMode::TrackArtists:
findParameters.setLinkType(TrackArtistLinkType::Artist);
break;
}
const RangeResults<ArtistId> artists {Artist::find(context.dbSession, findParameters)};
for (const ArtistId artistId : artists.results)
{
const auto artist {Artist::find(context.dbSession, artistId)};
indexNode.addArrayChild("artist", artistToResponseNode(user, artist, true /* id3 */));
}
return response;
}
static
Response
handleGetMusicDirectoryRequest(RequestContext& context)
@@ -1079,6 +1035,88 @@ handleGetMusicFoldersRequest(RequestContext& context)
return response;
}
static
Response
handleGetArtistsRequestCommon(RequestContext& context, bool id3)
{
Response response {Response::createOkResponse(context.serverProtocolVersion)};
Response::Node& artistsNode {response.createNode(id3 ? "artists" : "indexes")};
artistsNode.setAttribute("ignoredArticles", "");
artistsNode.setAttribute("lastModified", reportedDummyDateULong);
auto transaction {context.dbSession.createSharedTransaction()};
User::pointer user {User::find(context.dbSession, context.userId)};
if (!user)
throw UserNotAuthorizedError {};
Artist::FindParameters parameters;
parameters.setSortMethod(ArtistSortMethod::BySortName);
switch (user->getSubsonicArtistListMode())
{
case SubsonicArtistListMode::AllArtists:
break;
case SubsonicArtistListMode::ReleaseArtists:
parameters.setLinkType(TrackArtistLinkType::ReleaseArtist);
break;
case SubsonicArtistListMode::TrackArtists:
parameters.setLinkType(TrackArtistLinkType::Artist);
break;
}
Response::Node* currentIndexNode {};
char currentIndex{};
Response::Node* unknownIndexNode {};
auto getOrCreateUnknownIndexNode {[&]
{
if (!unknownIndexNode)
{
unknownIndexNode = &artistsNode.createArrayChild("index");
unknownIndexNode->setAttribute("name", "?");
}
return unknownIndexNode;
}};
auto getOrCreateIndexNode {[&](char first)
{
if (!currentIndexNode || currentIndex != first)
{
currentIndexNode = &artistsNode.createArrayChild("index");
currentIndexNode->setAttribute("name", std::string {first});
currentIndex = first;
}
return currentIndexNode;
}};
const RangeResults<ArtistId> artists {Artist::find(context.dbSession, parameters)};
for (const ArtistId artistId : artists.results)
{
const Artist::pointer artist {Artist::find(context.dbSession, artistId)};
const std::string& sortName {artist->getSortName()};
Response::Node* indexNode{};
if (sortName.empty() || !std::isalpha(sortName[0]))
indexNode = getOrCreateUnknownIndexNode();
else
indexNode = getOrCreateIndexNode(std::toupper(sortName[0]));
indexNode->addArrayChild("artist", artistToResponseNode(user, artist, id3));
}
return response;
}
static
Response
handleGetIndexesRequest(RequestContext& context)
{
return handleGetArtistsRequestCommon(context, false /* no id3 */);
}
static
Response
handleGetGenresRequest(RequestContext& context)
@@ -1103,45 +1141,9 @@ handleGetGenresRequest(RequestContext& context)
static
Response
handleGetIndexesRequest(RequestContext& context)
handleGetArtistsRequest(RequestContext& context)
{
Response response {Response::createOkResponse(context.serverProtocolVersion)};
Response::Node& artistsNode {response.createNode("indexes")};
artistsNode.setAttribute("ignoredArticles", "");
artistsNode.setAttribute("lastModified", reportedDummyDateULong);
Response::Node& indexNode {artistsNode.createArrayChild("index")};
indexNode.setAttribute("name", "?");
auto transaction {context.dbSession.createSharedTransaction()};
User::pointer user {User::find(context.dbSession, context.userId)};
if (!user)
throw UserNotAuthorizedError {};
Artist::FindParameters parameters;
parameters.setSortMethod(ArtistSortMethod::BySortName);
switch (user->getSubsonicArtistListMode())
{
case SubsonicArtistListMode::AllArtists:
break;
case SubsonicArtistListMode::ReleaseArtists:
parameters.setLinkType(TrackArtistLinkType::ReleaseArtist);
break;
case SubsonicArtistListMode::TrackArtists:
parameters.setLinkType(TrackArtistLinkType::Artist);
break;
}
const RangeResults<ArtistId> artists {Artist::find(context.dbSession, parameters)};
for (const ArtistId artistId : artists.results)
{
const Artist::pointer artist {Artist::find(context.dbSession, artistId)};
indexNode.addArrayChild("artist", artistToResponseNode(user, artist, false /* no id3 */));
}
return response;
return handleGetArtistsRequestCommon(context, true /* id3 */);
}
static
@@ -1501,38 +1503,14 @@ handleStarRequest(RequestContext& context)
{
StarParameters params {getStarParameters(context.parameters)};
auto transaction {context.dbSession.createSharedTransaction()};
User::pointer user {User::find(context.dbSession, context.userId)};
if (!user)
throw UserNotAuthorizedError {};
for (const ArtistId id : params.artistIds)
{
Artist::pointer artist {Artist::find(context.dbSession, id)};
if (!artist)
continue;
Service<Scrobbling::IScrobblingService>::get()->star(user->getId(), artist->getId());
}
Service<Scrobbling::IScrobblingService>::get()->star(context.userId, id);
for (const ReleaseId id : params.releaseIds)
{
Release::pointer release {Release::find(context.dbSession, id)};
if (!release)
continue;
Service<Scrobbling::IScrobblingService>::get()->star(user->getId(), release->getId());
}
Service<Scrobbling::IScrobblingService>::get()->star(context.userId, id);
for (const TrackId id : params.trackIds)
{
Track::pointer track {Track::find(context.dbSession, id)};
if (!track)
continue;
Service<Scrobbling::IScrobblingService>::get()->star(user->getId(), track->getId());
}
Service<Scrobbling::IScrobblingService>::get()->star(context.userId, id);
return Response::createOkResponse(context.serverProtocolVersion);
}
@@ -1557,33 +1535,14 @@ handleUnstarRequest(RequestContext& context)
{
StarParameters params {getStarParameters(context.parameters)};
auto transaction {context.dbSession.createSharedTransaction()};
User::pointer user {User::find(context.dbSession, context.userId)};
if (!user)
throw RequestedDataNotFoundError {};
for (const ArtistId artistId : params.artistIds)
Service<Scrobbling::IScrobblingService>::get()->unstar(context.userId, artistId);
for (const ArtistId id : params.artistIds)
Service<Scrobbling::IScrobblingService>::get()->unstar(context.userId, id);
for (const ReleaseId id : params.releaseIds)
{
Release::pointer release {Release::find(context.dbSession, id)};
if (!release)
continue;
Service<Scrobbling::IScrobblingService>::get()->unstar(user->getId(), release->getId());
}
Service<Scrobbling::IScrobblingService>::get()->unstar(context.userId, id);
for (const TrackId id : params.trackIds)
{
Track::pointer track {Track::find(context.dbSession, id)};
if (!track)
continue;
Service<Scrobbling::IScrobblingService>::get()->unstar(user->getId(), track->getId());
}
Service<Scrobbling::IScrobblingService>::get()->unstar(context.userId, id);
return Response::createOkResponse(context.serverProtocolVersion);
}
+1 -1
View File
@@ -128,7 +128,7 @@ bool
RecursiveSharedMutex::isSharedLocked()
{
const auto thisThreadId {std::this_thread::get_id()};
if (_uniqueOwner == thisThreadId )
if (_uniqueOwner == thisThreadId )
return true;
std::scoped_lock lock {_sharedCountMutex};