Removed session parameters from scrobbling service

This commit is contained in:
emeric
2021-10-02 20:24:28 +02:00
parent 00c756f7e1
commit 3f229dbbe3
7 changed files with 233 additions and 149 deletions
+103 -45
View File
@@ -19,8 +19,11 @@
#include "Scrobbling.hpp"
#include "database/Artist.hpp"
#include "database/Db.hpp"
#include "database/Release.hpp"
#include "database/Session.hpp"
#include "database/Track.hpp"
#include "database/TrackList.hpp"
#include "database/User.hpp"
@@ -29,13 +32,15 @@
namespace Scrobbling
{
using namespace Database;
std::unique_ptr<IScrobbling>
createScrobbling(boost::asio::io_context& ioContext, Database::Db& db)
createScrobbling(boost::asio::io_context& ioContext, Db& db)
{
return std::make_unique<Scrobbling>(ioContext, db);
}
Scrobbling::Scrobbling(boost::asio::io_context& ioContext, Database::Db& db)
Scrobbling::Scrobbling(boost::asio::io_context& ioContext, Db& db)
: _db {db}
{
_scrobblers.emplace(Database::Scrobbler::Internal, std::make_unique<InternalScrobbler>(_db));
@@ -68,116 +73,169 @@ namespace Scrobbling
{
std::optional<Database::Scrobbler> scrobbler;
Database::Session& session {_db.getTLSSession()};
Session& session {_db.getTLSSession()};
auto transaction {session.createSharedTransaction()};
if (const Database::User::pointer user {Database::User::getById(session, userId)})
if (const User::pointer user {User::getById(session, userId)})
scrobbler = user->getScrobbler();
return scrobbler;
}
std::vector<Database::ObjectPtr<Database::Artist>>
Scrobbling::getRecentArtists(Database::Session& session,
Database::ObjectPtr<Database::User> user,
const std::vector<Database::ClusterId>& clusterIds,
std::optional<Database::TrackArtistLinkType> linkType,
std::optional<Database::Range> range,
Scrobbling::ArtistContainer
Scrobbling::getRecentArtists(UserId userId,
const std::vector<ClusterId>& clusterIds,
std::optional<TrackArtistLinkType> linkType,
std::optional<Range> range,
bool& moreResults)
{
const Database::ObjectPtr<Database::TrackList> history {getListensTrackList(session, user)};
ArtistContainer res;
std::vector<Database::ObjectPtr<Database::Artist>> res;
Session& session {_db.getTLSSession()};
auto transaction {session.createSharedTransaction()};
const User::pointer user {User::getById(session, userId)};
if (!user)
return res;
const ObjectPtr<TrackList> history {getListensTrackList(session, user)};
if (history)
res = history->getArtistsReverse(clusterIds, linkType, range, moreResults);
{
for (const Artist::pointer& artist : history->getArtistsReverse(clusterIds, linkType, range, moreResults))
res.push_back(artist->getId());
}
return res;
}
std::vector<Database::ObjectPtr<Database::Release>>
Scrobbling::getRecentReleases(Database::Session& session,
Database::ObjectPtr<Database::User> user,
Scrobbling::ReleaseContainer
Scrobbling::getRecentReleases(Database::UserId userId,
const std::vector<Database::ClusterId>& clusterIds,
std::optional<Database::Range> range,
bool& moreResults)
{
const Database::ObjectPtr<Database::TrackList> history {getListensTrackList(session, user)};
ReleaseContainer res;
std::vector<Database::ObjectPtr<Database::Release>> res;
Session& session {_db.getTLSSession()};
auto transaction {session.createSharedTransaction()};
const User::pointer user {User::getById(session, userId)};
if (!user)
return res;
const ObjectPtr<TrackList> history {getListensTrackList(session, user)};
if (history)
res = history->getReleasesReverse(clusterIds, range, moreResults);
{
for (const Release::pointer& release : history->getReleasesReverse(clusterIds, range, moreResults))
res.push_back(release->getId());
}
return res;
}
std::vector<Database::ObjectPtr<Database::Track>>
Scrobbling::getRecentTracks(Database::Session& session,
Database::ObjectPtr<Database::User> user,
Scrobbling::TrackContainer
Scrobbling::getRecentTracks(Database::UserId userId,
const std::vector<Database::ClusterId>& clusterIds,
std::optional<Database::Range> range,
bool& moreResults)
{
const Database::ObjectPtr<Database::TrackList> history {getListensTrackList(session, user)};
TrackContainer res;
std::vector<Database::ObjectPtr<Database::Track>> res;
Session& session {_db.getTLSSession()};
auto transaction {session.createSharedTransaction()};
const User::pointer user {User::getById(session, userId)};
if (!user)
return res;
const ObjectPtr<TrackList> history {getListensTrackList(session, user)};
if (history)
res = history->getTracksReverse(clusterIds, range, moreResults);
{
for (const Track::pointer& track : history->getTracksReverse(clusterIds, range, moreResults))
res.push_back(track->getId());
}
return res;
}
// Top
std::vector<Database::ObjectPtr<Database::Artist>>
Scrobbling::getTopArtists(Database::Session& session,
Database::ObjectPtr<Database::User> user,
Scrobbling::ArtistContainer
Scrobbling::getTopArtists(UserId userId,
const std::vector<Database::ClusterId>& clusterIds,
std::optional<Database::TrackArtistLinkType> linkType,
std::optional<Database::Range> range,
bool& moreResults)
{
const Database::ObjectPtr<Database::TrackList> history {getListensTrackList(session, user)};
ArtistContainer res;
std::vector<Database::ObjectPtr<Database::Artist>> res;
Session& session {_db.getTLSSession()};
auto transaction {session.createSharedTransaction()};
const User::pointer user {User::getById(session, userId)};
if (!user)
return res;
const ObjectPtr<TrackList> history {getListensTrackList(session, user)};
if (history)
res = history->getTopArtists(clusterIds, linkType, range, moreResults);
{
for (const Artist::pointer& artist : history->getTopArtists(clusterIds, linkType, range, moreResults))
res.push_back(artist->getId());
}
return res;
}
std::vector<Database::ObjectPtr<Database::Release>>
Scrobbling::getTopReleases(Database::Session& session,
Database::ObjectPtr<Database::User> user,
Scrobbling::ReleaseContainer
Scrobbling::getTopReleases(Database::UserId userId,
const std::vector<Database::ClusterId>& clusterIds,
std::optional<Database::Range> range,
bool& moreResults)
{
const Database::ObjectPtr<Database::TrackList> history {getListensTrackList(session, user)};
ReleaseContainer res;
std::vector<Database::ObjectPtr<Database::Release>> res;
Session& session {_db.getTLSSession()};
auto transaction {session.createSharedTransaction()};
const User::pointer user {User::getById(session, userId)};
if (!user)
return res;
const ObjectPtr<TrackList> history {getListensTrackList(session, user)};
if (history)
res = history->getTopReleases(clusterIds, range, moreResults);
{
for (const Release::pointer& release : history->getTopReleases(clusterIds, range, moreResults))
res.push_back(release->getId());
}
return res;
}
std::vector<Database::ObjectPtr<Database::Track>>
Scrobbling::getTopTracks(Database::Session& session,
Database::ObjectPtr<Database::User> user,
Scrobbling::TrackContainer
Scrobbling::getTopTracks(Database::UserId userId,
const std::vector<Database::ClusterId>& clusterIds,
std::optional<Database::Range> range,
bool& moreResults)
{
const Database::ObjectPtr<Database::TrackList> history {getListensTrackList(session, user)};
TrackContainer res;
std::vector<Database::ObjectPtr<Database::Track>> res;
if (history)
res = history->getTopTracks(clusterIds, range, moreResults);
Session& session {_db.getTLSSession()};
auto transaction {session.createSharedTransaction()};
const User::pointer user {User::getById(session, userId)};
if (!user)
return res;
if (const ObjectPtr<TrackList> history {getListensTrackList(session, user)})
{
for (const Track::pointer& track : history->getTopTracks(clusterIds, range, moreResults))
res.push_back(track->getId());
}
return res;
}
Database::ObjectPtr<Database::TrackList>
Scrobbling::getListensTrackList(Database::Session& session, Database::ObjectPtr<Database::User> user)
Scrobbling::getListensTrackList(Session& session, Database::ObjectPtr<Database::User> user)
{
return _scrobblers[user->getScrobbler()]->getListensTrackList(session, user);
}
+6 -12
View File
@@ -38,40 +38,34 @@ namespace Scrobbling
void listenFinished(const Listen& listen, std::optional<std::chrono::seconds> duration) override;
void addTimedListen(const TimedListen& listen) override;
std::vector<Database::ObjectPtr<Database::Artist>> getRecentArtists(Database::Session& session,
Database::ObjectPtr<Database::User> user,
ArtistContainer getRecentArtists(Database::UserId userId,
const std::vector<Database::ClusterId>& clusterIds,
std::optional<Database::TrackArtistLinkType> linkType,
std::optional<Database::Range> range,
bool& moreResults) override;
std::vector<Database::ObjectPtr<Database::Release>> getRecentReleases(Database::Session& session,
Database::ObjectPtr<Database::User> user,
ReleaseContainer getRecentReleases(Database::UserId userId,
const std::vector<Database::ClusterId>& clusterIds,
std::optional<Database::Range> range,
bool& moreResults) override;
std::vector<Database::ObjectPtr<Database::Track>> getRecentTracks(Database::Session& session,
Database::ObjectPtr<Database::User> user,
TrackContainer getRecentTracks(Database::UserId userId,
const std::vector<Database::ClusterId>& clusterIds,
std::optional<Database::Range> range,
bool& moreResults) override;
std::vector<Database::ObjectPtr<Database::Artist>> getTopArtists(Database::Session& session,
Database::ObjectPtr<Database::User> user,
ArtistContainer getTopArtists(Database::UserId userId,
const std::vector<Database::ClusterId>& clusterIds,
std::optional<Database::TrackArtistLinkType> linkType,
std::optional<Database::Range> range,
bool& moreResults) override;
std::vector<Database::ObjectPtr<Database::Release>> getTopReleases(Database::Session& session,
Database::ObjectPtr<Database::User> user,
ReleaseContainer getTopReleases(Database::UserId userId,
const std::vector<Database::ClusterId>& clusterIds,
std::optional<Database::Range> range,
bool& moreResults) override;
std::vector<Database::ObjectPtr<Database::Track>> getTopTracks(Database::Session& session,
Database::ObjectPtr<Database::User> user,
TrackContainer getTopTracks(Database::UserId userId,
const std::vector<Database::ClusterId>& clusterIds,
std::optional<Database::Range> range,
bool& moreResults) override;
@@ -56,42 +56,42 @@ namespace Scrobbling
virtual void addTimedListen(const TimedListen& listen) = 0;
// Stats
template <typename IdType>
using ResultContainer = std::vector<IdType>;
using ArtistContainer = ResultContainer<Database::ArtistId>;
using ReleaseContainer = ResultContainer<Database::ReleaseId>;
using TrackContainer = ResultContainer<Database::TrackId>;
// From most recent to oldest
virtual std::vector<Database::ObjectPtr<Database::Artist>> getRecentArtists(Database::Session& session,
Database::ObjectPtr<Database::User> user,
virtual ArtistContainer getRecentArtists(Database::UserId userId,
const std::vector<Database::ClusterId>& clusterIds,
std::optional<Database::TrackArtistLinkType> linkType,
std::optional<Database::Range> range,
bool& moreResults) = 0;
virtual std::vector<Database::ObjectPtr<Database::Release>> getRecentReleases(Database::Session& session,
Database::ObjectPtr<Database::User> user,
virtual ReleaseContainer getRecentReleases(Database::UserId userId,
const std::vector<Database::ClusterId>& clusterIds,
std::optional<Database::Range> range,
bool& moreResults) = 0;
virtual std::vector<Database::ObjectPtr<Database::Track>> getRecentTracks(Database::Session& session,
Database::ObjectPtr<Database::User> user,
virtual TrackContainer getRecentTracks(Database::UserId userId,
const std::vector<Database::ClusterId>& clusterIds,
std::optional<Database::Range> range,
bool& moreResults) = 0;
// Top
virtual std::vector<Database::ObjectPtr<Database::Artist>> getTopArtists(Database::Session& session,
Database::ObjectPtr<Database::User> user,
virtual ArtistContainer getTopArtists(Database::UserId userId,
const std::vector<Database::ClusterId>& clusterIds,
std::optional<Database::TrackArtistLinkType> linkType,
std::optional<Database::Range> range,
bool& moreResults) = 0;
virtual std::vector<Database::ObjectPtr<Database::Release>> getTopReleases(Database::Session& session,
Database::ObjectPtr<Database::User> user,
virtual ReleaseContainer getTopReleases(Database::UserId userId,
const std::vector<Database::ClusterId>& clusterIds,
std::optional<Database::Range> range,
bool& moreResults) = 0;
virtual std::vector<Database::ObjectPtr<Database::Track>> getTopTracks(Database::Session& session,
Database::ObjectPtr<Database::User> user,
virtual TrackContainer getTopTracks(Database::UserId userId,
const std::vector<Database::ClusterId>& clusterIds,
std::optional<Database::Range> range,
bool& moreResults) = 0;
+11 -2
View File
@@ -724,6 +724,7 @@ handleGetAlbumListRequestCommon(const RequestContext& context, bool id3)
const Range range {offset, size};
std::vector<Release::pointer> releases;
Scrobbling::IScrobbling& scrobbling {*Service<Scrobbling::IScrobbling>::get()};
auto transaction {context.dbSession.createSharedTransaction()};
@@ -765,7 +766,11 @@ handleGetAlbumListRequestCommon(const RequestContext& context, bool id3)
else if (type == "frequent")
{
bool moreResults {};
releases = Service<Scrobbling::IScrobbling>::get()->getTopReleases(context.dbSession, user, {}, range, moreResults);
for (ReleaseId releaseId : scrobbling.getTopReleases(context.userId, {}, range, moreResults))
{
if (Release::pointer release {Release::getById(context.dbSession, releaseId)})
releases.push_back(release );
}
}
else if (type == "newest")
{
@@ -780,7 +785,11 @@ handleGetAlbumListRequestCommon(const RequestContext& context, bool id3)
else if (type == "recent")
{
bool moreResults {};
releases = Service<Scrobbling::IScrobbling>::get()->getRecentReleases(context.dbSession, user, {}, range, moreResults);
for (ReleaseId releaseId : scrobbling.getRecentReleases(context.userId, {}, range, moreResults))
{
if (Release::pointer release {Release::getById(context.dbSession, releaseId)})
releases.push_back(release );
}
}
else if (type == "starred")
{
+12 -8
View File
@@ -34,6 +34,8 @@ namespace UserInterface
std::vector<Database::ObjectPtr<Database::Artist>>
ArtistCollector::get(std::optional<Database::Range> range, bool& moreResults)
{
Scrobbling::IScrobbling& scrobbling {*Service<Scrobbling::IScrobbling>::get()};
range = getActualRange(range);
std::vector<Artist::pointer> artists;
@@ -53,17 +55,19 @@ namespace UserInterface
break;
case Mode::RecentlyPlayed:
artists = Service<Scrobbling::IScrobbling>::get()->getRecentArtists(LmsApp->getDbSession(), LmsApp->getUser(),
getFilters().getClusterIds(),
_linkType,
range, moreResults);
for (const ArtistId artistId : scrobbling.getRecentArtists(LmsApp->getUserId(), getFilters().getClusterIds(), _linkType, range, moreResults))
{
if (Artist::pointer artist {Artist::getById(LmsApp->getDbSession(), artistId)})
artists.push_back(artist);
}
break;
case Mode::MostPlayed:
artists = Service<Scrobbling::IScrobbling>::get()->getTopArtists(LmsApp->getDbSession(), LmsApp->getUser(),
getFilters().getClusterIds(),
_linkType,
range, moreResults);
for (const ArtistId artistId : scrobbling.getTopArtists(LmsApp->getUserId(), getFilters().getClusterIds(), _linkType, range, moreResults))
{
if (Artist::pointer artist {Artist::getById(LmsApp->getDbSession(), artistId)})
artists.push_back(artist);
}
break;
case Mode::RecentlyAdded:
+12 -2
View File
@@ -37,6 +37,8 @@ namespace UserInterface
std::vector<Release::pointer>
ReleaseCollector::get(std::optional<Database::Range> range, bool& moreResults)
{
Scrobbling::IScrobbling& scrobbling {*Service<Scrobbling::IScrobbling>::get()};
range = getActualRange(range);
std::vector<Release::pointer> releases;
@@ -51,11 +53,19 @@ namespace UserInterface
break;
case ReleaseCollector::Mode::RecentlyPlayed:
releases = Service<Scrobbling::IScrobbling>::get()->getRecentReleases(LmsApp->getDbSession(), LmsApp->getUser(), getFilters().getClusterIds(), range, moreResults);
for (const ReleaseId releaseId : scrobbling.getRecentReleases(LmsApp->getUserId(), getFilters().getClusterIds(), range, moreResults))
{
if (const Release::pointer release {Release::getById(LmsApp->getDbSession(), releaseId)})
releases.push_back(release);
}
break;
case Mode::MostPlayed:
releases = Service<Scrobbling::IScrobbling>::get()->getTopReleases(LmsApp->getDbSession(), LmsApp->getUser(), getFilters().getClusterIds(), range, moreResults);
for (const ReleaseId releaseId : scrobbling.getTopReleases(LmsApp->getUserId(), getFilters().getClusterIds(), range, moreResults))
{
if (const Release::pointer release {Release::getById(LmsApp->getDbSession(), releaseId)})
releases.push_back(release);
}
break;
case Mode::RecentlyAdded:
+23 -14
View File
@@ -37,44 +37,53 @@ namespace UserInterface
std::vector<Track::pointer>
TrackCollector::get(std::optional<Database::Range> range, bool& moreResults)
{
Scrobbling::IScrobbling& scrobbling {*Service<Scrobbling::IScrobbling>::get()};
range = getActualRange(range);
std::vector<Track::pointer> releases;
std::vector<Track::pointer> tracks;
switch (getMode())
{
case Mode::Random:
releases = getRandomTracks(range, moreResults);
tracks = getRandomTracks(range, moreResults);
break;
case Mode::Starred:
releases = Track::getStarred(LmsApp->getDbSession(), LmsApp->getUser(), getFilters().getClusterIds(), range, moreResults);
tracks = Track::getStarred(LmsApp->getDbSession(), LmsApp->getUser(), getFilters().getClusterIds(), range, moreResults);
break;
case TrackCollector::Mode::RecentlyPlayed:
releases = Service<Scrobbling::IScrobbling>::get()->getRecentTracks(LmsApp->getDbSession(), LmsApp->getUser(), getFilters().getClusterIds(), range, moreResults);
for (const TrackId trackId : scrobbling.getRecentTracks(LmsApp->getUserId(), getFilters().getClusterIds(), range, moreResults))
{
if (const Track::pointer track {Track::getById(LmsApp->getDbSession(), trackId)})
tracks.push_back(track);
}
break;
case Mode::MostPlayed:
releases = Service<Scrobbling::IScrobbling>::get()->getTopTracks(LmsApp->getDbSession(), LmsApp->getUser(), getFilters().getClusterIds(), range, moreResults);
for (const TrackId trackId : scrobbling.getTopTracks(LmsApp->getUserId(), getFilters().getClusterIds(), range, moreResults))
{
if (const Track::pointer track {Track::getById(LmsApp->getDbSession(), trackId)})
tracks.push_back(track);
}
break;
case Mode::RecentlyAdded:
releases = Track::getLastWritten(LmsApp->getDbSession(), std::nullopt, getFilters().getClusterIds(), range, moreResults);
tracks = Track::getLastWritten(LmsApp->getDbSession(), std::nullopt, getFilters().getClusterIds(), range, moreResults);
break;
case Mode::Search:
releases = Track::getByFilter(LmsApp->getDbSession(), getFilters().getClusterIds(), getSearchKeywords(), range, moreResults);
tracks = Track::getByFilter(LmsApp->getDbSession(), getFilters().getClusterIds(), getSearchKeywords(), range, moreResults);
break;
case Mode::All:
releases = Track::getByFilter(LmsApp->getDbSession(), getFilters().getClusterIds(), {}, range, moreResults);
tracks = Track::getByFilter(LmsApp->getDbSession(), getFilters().getClusterIds(), {}, range, moreResults);
break;
}
if (range && getMaxCount() && (range->offset + range->limit == *getMaxCount()))
moreResults = false;
return releases;
return tracks;
}
std::vector<Database::TrackId>
@@ -95,7 +104,7 @@ namespace UserInterface
std::vector<Database::Track::pointer>
TrackCollector::getRandomTracks(std::optional<Range> range, bool& moreResults)
{
std::vector<Track::pointer> releases;
std::vector<Track::pointer> tracks;
assert(getMode() == Mode::Random);
@@ -108,15 +117,15 @@ namespace UserInterface
for (auto it {itBegin}; it != itEnd; ++it)
{
Track::pointer release {Track::getById(LmsApp->getDbSession(), *it)};
if (release)
releases.push_back(release);
Track::pointer track {Track::getById(LmsApp->getDbSession(), *it)};
if (track)
tracks.push_back(track);
}
moreResults = (itEnd != std::cend(_randomTracks));
}
return releases;
return tracks;
}
} // ns UserInterface