Use the scrobbling service to get listen count rathen than querying the db directly
This commit is contained in:
@@ -249,29 +249,31 @@ namespace Database
|
||||
return Utils::execQuery<TrackId>(query, range);
|
||||
}
|
||||
|
||||
std::size_t Listen::getCount(Session& session, UserId userId, ScrobblingBackend backend, TrackId trackId)
|
||||
std::size_t Listen::getCount(Session& session, UserId userId, TrackId trackId)
|
||||
{
|
||||
session.checkReadTransaction();
|
||||
|
||||
return session.getDboSession().query<int>("SELECT COUNT(*) from listen l")
|
||||
.join("user u ON u.id = l.user_id")
|
||||
.where("l.track_id = ?").bind(trackId)
|
||||
.where("l.user_id = ?").bind(userId)
|
||||
.where("l.backend = ?").bind(backend)
|
||||
.where("l.backend = u.scrobbling_backend")
|
||||
.resultValue();
|
||||
}
|
||||
|
||||
std::size_t Listen::getCount(Session& session, UserId userId, ScrobblingBackend backend, ReleaseId releaseId)
|
||||
std::size_t Listen::getCount(Session& session, UserId userId, ReleaseId releaseId)
|
||||
{
|
||||
session.checkReadTransaction();
|
||||
|
||||
return session.getDboSession().query<int>("SELECT IFNULL(MIN(count_result), 0)"
|
||||
return session.getDboSession().query<int>(
|
||||
"SELECT IFNULL(MIN(count_result), 0)"
|
||||
" FROM ("
|
||||
" SELECT COUNT(l.track_id) AS count_result"
|
||||
" FROM track t"
|
||||
" LEFT JOIN listen l ON t.id = l.track_id AND l.backend = ? AND l.user_id = ?"
|
||||
" LEFT JOIN listen l ON t.id = l.track_id AND l.backend = (SELECT scrobbling_backend FROM user WHERE id = ?) AND l.user_id = ?"
|
||||
" WHERE t.release_id = ?"
|
||||
" GROUP BY t.id)")
|
||||
.bind(backend)
|
||||
.bind(userId)
|
||||
.bind(userId)
|
||||
.bind(releaseId)
|
||||
.resultValue();
|
||||
|
||||
@@ -73,8 +73,8 @@ namespace Database
|
||||
static RangeResults<ReleaseId> getRecentReleases(Session& session, UserId userId, ScrobblingBackend backend, const std::vector<ClusterId>& clusterIds, std::optional<Range> range = std::nullopt);
|
||||
static RangeResults<TrackId> getRecentTracks(Session& session, UserId userId, ScrobblingBackend backend, const std::vector<ClusterId>& clusterIds, std::optional<Range> range = std::nullopt);
|
||||
|
||||
static std::size_t getCount(Session& session, UserId userId, ScrobblingBackend backend, TrackId trackId);
|
||||
static std::size_t getCount(Session& session, UserId userId, ScrobblingBackend backend, ReleaseId trackId);
|
||||
static std::size_t getCount(Session& session, UserId userId, TrackId trackId); // for the current backend
|
||||
static std::size_t getCount(Session& session, UserId userId, ReleaseId trackId); // for the current backend
|
||||
|
||||
static pointer getMostRecentListen(Session& session, UserId userId, ScrobblingBackend backend, ReleaseId releaseId);
|
||||
static pointer getMostRecentListen(Session& session, UserId userId, ScrobblingBackend backend, TrackId releaseId);
|
||||
|
||||
@@ -881,7 +881,7 @@ TEST_F(DatabaseFixture, Listen_getCount_track)
|
||||
{
|
||||
auto transaction{ session.createReadTransaction() };
|
||||
|
||||
const std::size_t count{ Listen::getCount(session, user->getId(), ScrobblingBackend::Internal, track.getId()) };
|
||||
const std::size_t count{ Listen::getCount(session, user->getId(), track.getId()) };
|
||||
EXPECT_EQ(count, 0);
|
||||
}
|
||||
|
||||
@@ -891,9 +891,21 @@ TEST_F(DatabaseFixture, Listen_getCount_track)
|
||||
{
|
||||
auto transaction{ session.createReadTransaction() };
|
||||
|
||||
const std::size_t count{ Listen::getCount(session, user->getId(), ScrobblingBackend::Internal, track.getId()) };
|
||||
const std::size_t count{ Listen::getCount(session, user->getId(), track.getId()) };
|
||||
EXPECT_EQ(count, 1);
|
||||
}
|
||||
|
||||
{
|
||||
auto transaction{ session.createWriteTransaction() };
|
||||
user.get().modify()->setScrobblingBackend(ScrobblingBackend::ListenBrainz);
|
||||
}
|
||||
|
||||
{
|
||||
auto transaction{ session.createReadTransaction() };
|
||||
const std::size_t count{ Listen::getCount(session, user->getId(), track.getId()) };
|
||||
EXPECT_EQ(count, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST_F(DatabaseFixture, Listen_getCount_release)
|
||||
@@ -906,7 +918,7 @@ TEST_F(DatabaseFixture, Listen_getCount_release)
|
||||
auto getReleaseListenCount{ [&]
|
||||
{
|
||||
auto transaction{ session.createReadTransaction() };
|
||||
return Listen::getCount(session, user->getId(), ScrobblingBackend::Internal, release.getId());
|
||||
return Listen::getCount(session, user->getId(), release.getId());
|
||||
} };
|
||||
|
||||
EXPECT_EQ(getReleaseListenCount(), 0);
|
||||
@@ -936,6 +948,12 @@ TEST_F(DatabaseFixture, Listen_getCount_release)
|
||||
|
||||
ScopedListen listen4{ session, user.lockAndGet(), track1.lockAndGet(), ScrobblingBackend::Internal, dateTime1 };
|
||||
EXPECT_EQ(getReleaseListenCount(), 2);
|
||||
|
||||
{
|
||||
auto transaction{ session.createWriteTransaction() };
|
||||
user.get().modify()->setScrobblingBackend(ScrobblingBackend::ListenBrainz);
|
||||
}
|
||||
EXPECT_EQ(getReleaseListenCount(), 0);
|
||||
}
|
||||
|
||||
TEST_F(DatabaseFixture, Listen_getMostRecentTrack)
|
||||
|
||||
@@ -129,6 +129,20 @@ namespace Scrobbling
|
||||
return res;
|
||||
}
|
||||
|
||||
std::size_t ScrobblingService::getCount(Database::UserId userId, Database::ReleaseId releaseId)
|
||||
{
|
||||
Session& session{ _db.getTLSSession() };
|
||||
auto transaction{ session.createReadTransaction() };
|
||||
return Database::Listen::getCount(session, userId, releaseId);
|
||||
}
|
||||
|
||||
std::size_t ScrobblingService::getCount(Database::UserId userId, Database::TrackId trackId)
|
||||
{
|
||||
Session& session{ _db.getTLSSession() };
|
||||
auto transaction{ session.createReadTransaction() };
|
||||
return Database::Listen::getCount(session, userId, trackId);
|
||||
}
|
||||
|
||||
Wt::WDateTime ScrobblingService::getLastListenDateTime(Database::UserId userId, Database::ReleaseId releaseId)
|
||||
{
|
||||
const auto backend{ getUserBackend(userId) };
|
||||
|
||||
@@ -43,6 +43,9 @@ namespace Scrobbling
|
||||
ReleaseContainer getRecentReleases(Database::UserId userId, const std::vector<Database::ClusterId>& clusterIds,Database::Range range) override;
|
||||
TrackContainer getRecentTracks(Database::UserId userId, const std::vector<Database::ClusterId>& clusterIds, Database::Range range) override;
|
||||
|
||||
std::size_t getCount(Database::UserId userId, Database::ReleaseId releaseId) override;
|
||||
std::size_t getCount(Database::UserId userId, Database::TrackId trackId) override;
|
||||
|
||||
Wt::WDateTime getLastListenDateTime(Database::UserId userId, Database::ReleaseId releaseId) override;
|
||||
Wt::WDateTime getLastListenDateTime(Database::UserId userId, Database::TrackId trackId) override;
|
||||
|
||||
|
||||
@@ -61,6 +61,9 @@ namespace Scrobbling
|
||||
virtual ReleaseContainer getRecentReleases(Database::UserId userId, const std::vector<Database::ClusterId>& clusterIds, Database::Range range) = 0;
|
||||
virtual TrackContainer getRecentTracks(Database::UserId userId, const std::vector<Database::ClusterId>& clusterIds, Database::Range range) = 0;
|
||||
|
||||
virtual std::size_t getCount(Database::UserId userId, Database::ReleaseId releaseId) = 0;
|
||||
virtual std::size_t getCount(Database::UserId userId, Database::TrackId trackId) = 0;
|
||||
|
||||
virtual Wt::WDateTime getLastListenDateTime(Database::UserId userId, Database::ReleaseId releaseId) = 0;
|
||||
virtual Wt::WDateTime getLastListenDateTime(Database::UserId userId, Database::TrackId trackId) = 0;
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
|
||||
#include "services/database/Artist.hpp"
|
||||
#include "services/database/Cluster.hpp"
|
||||
#include "services/database/Listen.hpp"
|
||||
#include "services/database/Release.hpp"
|
||||
#include "services/database/User.hpp"
|
||||
#include "services/feedback/IFeedbackService.hpp"
|
||||
@@ -125,7 +124,7 @@ namespace API::Subsonic
|
||||
}
|
||||
}
|
||||
|
||||
albumNode.setAttribute("playCount", Listen::getCount(context.dbSession, user->getId(), user->getScrobblingBackend(), release->getId()));
|
||||
albumNode.setAttribute("playCount", Service<Scrobbling::IScrobblingService>::get()->getCount(user->getId(), release->getId()));
|
||||
|
||||
// Report the first GENRE for this track
|
||||
const ClusterType::pointer genreClusterType{ ClusterType::find(context.dbSession, "GENRE") };
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#include "av/IAudioFile.hpp"
|
||||
#include "services/database/Artist.hpp"
|
||||
#include "services/database/Cluster.hpp"
|
||||
#include "services/database/Listen.hpp"
|
||||
#include "services/database/Release.hpp"
|
||||
#include "services/database/Track.hpp"
|
||||
#include "services/database/TrackArtistLink.hpp"
|
||||
@@ -108,7 +107,7 @@ namespace API::Subsonic
|
||||
trackResponse.setAttribute("discNumber", *track->getDiscNumber());
|
||||
if (track->getYear())
|
||||
trackResponse.setAttribute("year", *track->getYear());
|
||||
trackResponse.setAttribute("playCount", Listen::getCount(context.dbSession, user->getId(), user->getScrobblingBackend(), track->getId()));
|
||||
trackResponse.setAttribute("playCount", Service<Scrobbling::IScrobblingService>::get()->getCount(user->getId(), track->getId()));
|
||||
trackResponse.setAttribute("path", getTrackPath(track));
|
||||
{
|
||||
// TODO, store this in DB
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include "av/IAudioFile.hpp"
|
||||
#include "services/database/Artist.hpp"
|
||||
#include "services/database/Cluster.hpp"
|
||||
#include "services/database/Listen.hpp"
|
||||
#include "services/database/Release.hpp"
|
||||
#include "services/database/ScanSettings.hpp"
|
||||
#include "services/database/Session.hpp"
|
||||
@@ -35,6 +34,7 @@
|
||||
#include "services/database/TrackArtistLink.hpp"
|
||||
#include "services/database/User.hpp"
|
||||
#include "services/feedback/IFeedbackService.hpp"
|
||||
#include "services/scrobbling/IScrobblingService.hpp"
|
||||
#include "services/recommendation/IRecommendationService.hpp"
|
||||
#include "utils/ILogger.hpp"
|
||||
|
||||
@@ -160,8 +160,7 @@ namespace UserInterface
|
||||
releaseInfo->bindString("bitrate", std::to_string(meanBitrate / 1000) + " kbps");
|
||||
}
|
||||
|
||||
const auto user{ LmsApp->getUser() };
|
||||
releaseInfo->bindInt("playcount", Database::Listen::getCount(LmsApp->getDbSession(), user->getId(), user->getScrobblingBackend(), release->getId()));
|
||||
releaseInfo->bindInt("playcount", Service<Scrobbling::IScrobblingService>::get()->getCount(LmsApp->getUserId(), release->getId()));
|
||||
|
||||
Wt::WPushButton* okBtn{ releaseInfo->bindNew<Wt::WPushButton>("ok-btn", Wt::WString::tr("Lms.ok")) };
|
||||
okBtn->clicked().connect([=]
|
||||
|
||||
@@ -26,13 +26,13 @@
|
||||
|
||||
#include "av/IAudioFile.hpp"
|
||||
#include "services/database/Artist.hpp"
|
||||
#include "services/database/Listen.hpp"
|
||||
#include "services/database/Release.hpp"
|
||||
#include "services/database/Session.hpp"
|
||||
#include "services/database/Track.hpp"
|
||||
#include "services/database/TrackArtistLink.hpp"
|
||||
#include "services/database/User.hpp"
|
||||
#include "services/feedback/IFeedbackService.hpp"
|
||||
#include "services/scrobbling/IScrobblingService.hpp"
|
||||
#include "utils/ILogger.hpp"
|
||||
#include "utils/Service.hpp"
|
||||
|
||||
@@ -143,8 +143,7 @@ namespace UserInterface::TrackListHelpers
|
||||
trackInfo->bindString("bitrate", std::to_string(track->getBitrate() / 1000) + " kbps");
|
||||
}
|
||||
|
||||
const auto user{ LmsApp->getUser() };
|
||||
trackInfo->bindInt("playcount", Database::Listen::getCount(LmsApp->getDbSession(), user->getId(), user->getScrobblingBackend(), track->getId()));
|
||||
trackInfo->bindInt("playcount", Service<Scrobbling::IScrobblingService>::get()->getCount(LmsApp->getUserId(), track->getId()));
|
||||
|
||||
Wt::WContainerWidget* clusterContainer{ trackInfo->bindWidget("clusters", Utils::createClustersForTrack(track, filters)) };
|
||||
if (clusterContainer->count() > 0)
|
||||
|
||||
Reference in New Issue
Block a user