Subsonic API: handled the scrobble call (just put in the common played list for now, no scrobble on external services for now)
This commit is contained in:
@@ -479,7 +479,7 @@ userToResponseNode(const User::pointer& user)
|
|||||||
Response::Node userNode;
|
Response::Node userNode;
|
||||||
|
|
||||||
userNode.setAttribute("username", user->getLoginName());
|
userNode.setAttribute("username", user->getLoginName());
|
||||||
userNode.setAttribute("scrobblingEnabled", false);
|
userNode.setAttribute("scrobblingEnabled", true);
|
||||||
userNode.setAttribute("adminRole", user->isAdmin());
|
userNode.setAttribute("adminRole", user->isAdmin());
|
||||||
userNode.setAttribute("settingsRole", true);
|
userNode.setAttribute("settingsRole", true);
|
||||||
userNode.setAttribute("downloadRole", true);
|
userNode.setAttribute("downloadRole", true);
|
||||||
@@ -704,11 +704,13 @@ Response
|
|||||||
handleGetAlbumListRequestCommon(const RequestContext& context, bool id3)
|
handleGetAlbumListRequestCommon(const RequestContext& context, bool id3)
|
||||||
{
|
{
|
||||||
// Mandatory params
|
// Mandatory params
|
||||||
std::string type {getMandatoryParameterAs<std::string>(context.parameters, "type")};
|
const std::string type {getMandatoryParameterAs<std::string>(context.parameters, "type")};
|
||||||
|
|
||||||
// Optional params
|
// Optional params
|
||||||
std::size_t size {getParameterAs<std::size_t>(context.parameters, "size").value_or(10)};
|
const std::size_t size {getParameterAs<std::size_t>(context.parameters, "size").value_or(10)};
|
||||||
std::size_t offset {getParameterAs<std::size_t>(context.parameters, "offset").value_or(0)};
|
const std::size_t offset {getParameterAs<std::size_t>(context.parameters, "offset").value_or(0)};
|
||||||
|
|
||||||
|
const Range range {offset, size};
|
||||||
|
|
||||||
std::vector<Release::pointer> releases;
|
std::vector<Release::pointer> releases;
|
||||||
|
|
||||||
@@ -718,36 +720,14 @@ handleGetAlbumListRequestCommon(const RequestContext& context, bool id3)
|
|||||||
if (!user)
|
if (!user)
|
||||||
throw UserNotAuthorizedError {};
|
throw UserNotAuthorizedError {};
|
||||||
|
|
||||||
if (type == "random")
|
if (type == "alphabeticalByName")
|
||||||
{
|
{
|
||||||
// Random results are paginated, but there is no acceptable way to handle the pagination params without repeating some albums
|
releases = Release::getAll(context.dbSession, range);
|
||||||
releases = Release::getAllRandom(context.dbSession, {}, size);
|
|
||||||
}
|
|
||||||
else if (type == "newest")
|
|
||||||
{
|
|
||||||
bool moreResults {};
|
|
||||||
releases = Release::getLastWritten(context.dbSession, std::nullopt, {}, Range {offset, size}, moreResults);
|
|
||||||
}
|
|
||||||
else if (type == "alphabeticalByName")
|
|
||||||
{
|
|
||||||
releases = Release::getAll(context.dbSession, Range {offset, size});
|
|
||||||
}
|
}
|
||||||
else if (type == "alphabeticalByArtist")
|
else if (type == "alphabeticalByArtist")
|
||||||
{
|
{
|
||||||
releases = Release::getAllOrderedByArtist(context.dbSession, offset, size);
|
releases = Release::getAllOrderedByArtist(context.dbSession, offset, size);
|
||||||
}
|
}
|
||||||
else if (type == "byYear")
|
|
||||||
{
|
|
||||||
int fromYear {getMandatoryParameterAs<int>(context.parameters, "fromYear")};
|
|
||||||
int toYear {getMandatoryParameterAs<int>(context.parameters, "toYear")};
|
|
||||||
|
|
||||||
releases = Release::getByYear(context.dbSession, fromYear, toYear, offset, size);
|
|
||||||
}
|
|
||||||
else if (type == "starred")
|
|
||||||
{
|
|
||||||
bool moreResults {};
|
|
||||||
releases = Release::getStarred(context.dbSession, user, {}, Range {offset, size}, moreResults);
|
|
||||||
}
|
|
||||||
else if (type == "byGenre")
|
else if (type == "byGenre")
|
||||||
{
|
{
|
||||||
// Mandatory param
|
// Mandatory param
|
||||||
@@ -760,10 +740,42 @@ handleGetAlbumListRequestCommon(const RequestContext& context, bool id3)
|
|||||||
if (cluster)
|
if (cluster)
|
||||||
{
|
{
|
||||||
bool more;
|
bool more;
|
||||||
releases = Release::getByFilter(context.dbSession, {cluster.id()}, {}, Range {offset, size}, more);
|
releases = Release::getByFilter(context.dbSession, {cluster.id()}, {}, range, more);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (type == "byYear")
|
||||||
|
{
|
||||||
|
int fromYear {getMandatoryParameterAs<int>(context.parameters, "fromYear")};
|
||||||
|
int toYear {getMandatoryParameterAs<int>(context.parameters, "toYear")};
|
||||||
|
|
||||||
|
releases = Release::getByYear(context.dbSession, fromYear, toYear, range);
|
||||||
|
}
|
||||||
|
else if (type == "frequent")
|
||||||
|
{
|
||||||
|
bool moreResults {};
|
||||||
|
releases = user->getPlayedTrackList(context.dbSession)->getTopReleases({}, range, moreResults);
|
||||||
|
}
|
||||||
|
else if (type == "newest")
|
||||||
|
{
|
||||||
|
bool moreResults {};
|
||||||
|
releases = Release::getLastWritten(context.dbSession, std::nullopt, {}, range, moreResults);
|
||||||
|
}
|
||||||
|
else if (type == "random")
|
||||||
|
{
|
||||||
|
// Random results are paginated, but there is no acceptable way to handle the pagination params without repeating some albums
|
||||||
|
releases = Release::getAllRandom(context.dbSession, {}, size);
|
||||||
|
}
|
||||||
|
else if (type == "recent")
|
||||||
|
{
|
||||||
|
bool moreResults {};
|
||||||
|
releases = user->getPlayedTrackList(context.dbSession)->getReleasesReverse({}, range, moreResults);
|
||||||
|
}
|
||||||
|
else if (type == "starred")
|
||||||
|
{
|
||||||
|
bool moreResults {};
|
||||||
|
releases = Release::getStarred(context.dbSession, user, {}, range, moreResults);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
throw NotImplementedGenericError {};
|
throw NotImplementedGenericError {};
|
||||||
|
|
||||||
@@ -1547,6 +1559,34 @@ handleUnstarRequest(RequestContext& context)
|
|||||||
return Response::createOkResponse(context);
|
return Response::createOkResponse(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
Response
|
||||||
|
handleScrobble(RequestContext& context)
|
||||||
|
{
|
||||||
|
const std::vector<Id> ids {getMandatoryMultiParametersAs<Id>(context.parameters, "id")};
|
||||||
|
// TODO handle time in some way (need underlying refacto)
|
||||||
|
|
||||||
|
if (!std::all_of(std::cbegin(ids), std::cend(ids), [](const Id& id) { return id.type == Id::Type::Track; }))
|
||||||
|
throw BadParameterGenericError {"id"};
|
||||||
|
|
||||||
|
auto transaction {context.dbSession.createUniqueTransaction()};
|
||||||
|
|
||||||
|
User::pointer user {User::getByLoginName(context.dbSession, context.userName)};
|
||||||
|
if (!user)
|
||||||
|
throw RequestedDataNotFoundError {};
|
||||||
|
|
||||||
|
for (Id id : ids)
|
||||||
|
{
|
||||||
|
Track::pointer track {Track::getById(context.dbSession, id.value)};
|
||||||
|
if (!track)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
TrackListEntry::create(context.dbSession, track, user->getPlayedTrackList(context.dbSession));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Response::createOkResponse(context);
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
Response
|
Response
|
||||||
handleUpdateUserRequest(RequestContext& context)
|
handleUpdateUserRequest(RequestContext& context)
|
||||||
@@ -1824,10 +1864,10 @@ static std::unordered_map<std::string, RequestEntryPointInfo> requestEntryPoints
|
|||||||
{"getAvatar", {handleNotImplemented, false}},
|
{"getAvatar", {handleNotImplemented, false}},
|
||||||
|
|
||||||
// Media annotation
|
// Media annotation
|
||||||
{"star", {handleStarRequest, false}},
|
{"star", {handleStarRequest, false}},
|
||||||
{"unstar", {handleUnstarRequest, false}},
|
{"unstar", {handleUnstarRequest, false}},
|
||||||
{"setRating", {handleNotImplemented, false}},
|
{"setRating", {handleNotImplemented, false}},
|
||||||
{"scrobble", {handleNotImplemented, false}},
|
{"scrobble", {handleScrobble, false}},
|
||||||
|
|
||||||
// Sharing
|
// Sharing
|
||||||
{"getShares", {handleNotImplemented, false}},
|
{"getShares", {handleNotImplemented, false}},
|
||||||
|
|||||||
Reference in New Issue
Block a user