Make recetnly played/most played info update

This commit is contained in:
emeric
2018-06-08 16:01:03 +02:00
parent 1e68ccce2a
commit 49f92ba0f9
13 changed files with 134 additions and 40 deletions
+26
View File
@@ -44,6 +44,19 @@ TrackStats::getMostPlayedArtists(Wt::Dbo::Session& session, User::pointer user,
return std::vector<Artist::pointer>(res.begin(), res.end());
}
std::vector<Artist::pointer>
TrackStats::getLastPlayedArtists(Wt::Dbo::Session& session, User::pointer user, int limit)
{
Wt::Dbo::collection<Artist::pointer> res = session.query<Artist::pointer>
("SELECT a FROM artist a INNER JOIN track t ON a.id = t.artist_id INNER JOIN track_stats t_s ON t.id = t_s.track_id")
.where("t_s.user_id = ?").bind(user.id())
.groupBy("a.id")
.orderBy("t_s.last_played DESC")
.limit(limit);
return std::vector<Artist::pointer>(res.begin(), res.end());
}
std::vector<Release::pointer>
TrackStats::getMostPlayedReleases(Wt::Dbo::Session& session, User::pointer user, int limit)
{
@@ -57,6 +70,19 @@ TrackStats::getMostPlayedReleases(Wt::Dbo::Session& session, User::pointer user,
return std::vector<Release::pointer>(res.begin(), res.end());
}
std::vector<Release::pointer>
TrackStats::getLastPlayedReleases(Wt::Dbo::Session& session, User::pointer user, int limit)
{
Wt::Dbo::collection<Release::pointer> res = session.query<Release::pointer>
("SELECT r FROM release r INNER JOIN track t ON r.id = t.release_id INNER JOIN track_stats t_s ON t.id = t_s.track_id")
.where("t_s.user_id = ?").bind(user.id())
.groupBy("r.id")
.orderBy("t_s.last_played DESC")
.limit(limit);
return std::vector<Release::pointer>(res.begin(), res.end());
}
TrackStats::pointer
TrackStats::get(Wt::Dbo::Session& session, Track::pointer track, User::pointer user)
{
+7
View File
@@ -20,6 +20,7 @@
#pragma once
#include <Wt/Dbo/Dbo.h>
#include <Wt/WDateTime.h>
#include <string>
@@ -41,17 +42,22 @@ class TrackStats
TrackStats(Wt::Dbo::ptr<Track> track, Wt::Dbo::ptr<User> user);
static std::vector<Wt::Dbo::ptr<Artist>> getMostPlayedArtists(Wt::Dbo::Session& session, Wt::Dbo::ptr<User>, int limit = 1);
static std::vector<Wt::Dbo::ptr<Artist>> getLastPlayedArtists(Wt::Dbo::Session& session, Wt::Dbo::ptr<User>, int limit = 1);
static std::vector<Wt::Dbo::ptr<Release>> getMostPlayedReleases(Wt::Dbo::Session& session, Wt::Dbo::ptr<User>, int limit = 1);
static std::vector<Wt::Dbo::ptr<Release>> getLastPlayedReleases(Wt::Dbo::Session& session, Wt::Dbo::ptr<User>, int limit = 1);
// Get utility (will create if does not exist)
static pointer get(Wt::Dbo::Session& session, Wt::Dbo::ptr<Track> track, Wt::Dbo::ptr<User> user);
void incPlayCount() { _playCount++; }
void setLastPlayed(Wt::WDateTime lastPlayed) { _lastPlayed = lastPlayed; }
template<class Action>
void persist(Action& a)
{
Wt::Dbo::field(a, _playCount, "play_count");
Wt::Dbo::field(a, _lastPlayed, "last_played");
Wt::Dbo::belongsTo(a, _track, "track", Wt::Dbo::OnDeleteCascade);
Wt::Dbo::belongsTo(a, _user, "user", Wt::Dbo::OnDeleteCascade);
}
@@ -59,6 +65,7 @@ class TrackStats
private:
int _playCount = 0;
Wt::WDateTime _lastPlayed;
Wt::Dbo::ptr<Track> _track;
Wt::Dbo::ptr<User> _user;
};
+20 -7
View File
@@ -384,16 +384,20 @@ LmsApplication::handleAuthEvent(void)
}));
// Events from the PlayQueue
playqueue->playTrack.connect(explore, &Explore::handleTrackPlayed);
playqueue->playTrack.connect(player, &MediaPlayer::playTrack);
playqueue->playbackStop.connect(player, &MediaPlayer::stop);
// Events from MediaScanner
if (_isAdmin)
std::string sessionId = this->sessionId();
_scanner.scanComplete().connect([=] (Scanner::MediaScanner::Stats stats)
{
std::string sessionId = this->sessionId();
_scanner.scanComplete().connect(std::bind([=] (Scanner::MediaScanner::Stats stats)
Wt::WServer::instance()->post(sessionId, [=]
{
Wt::WServer::instance()->post(sessionId, [=]
bool changes = false;
if (_isAdmin)
{
notifyMsg(Wt::WString::tr("Lms.Admin.Database.scan-complete")
.arg(static_cast<unsigned>(stats.nbFiles()))
@@ -402,10 +406,19 @@ LmsApplication::handleAuthEvent(void)
.arg(static_cast<unsigned>(stats.deletions))
.arg(static_cast<unsigned>(stats.nbDuplicates()))
.arg(static_cast<unsigned>(stats.nbErrors())));
changes = true;
}
if (stats.nbChanges() > 0)
{
explore->handleDbChanged();
changes = true;
}
if (changes)
triggerUpdate();
});
}, std::placeholders::_1));
}
});
});
internalPathChanged().connect(std::bind([=]
{
+5 -1
View File
@@ -23,6 +23,7 @@
#include <Wt/WAnchor.h>
#include <Wt/WImage.h>
#include <Wt/WLocalDateTime.h>
#include <Wt/WText.h>
#include "utils/Logger.hpp"
@@ -121,7 +122,10 @@ PlayQueue::play(std::size_t pos)
trackId = track.id();
Database::TrackStats::get(LmsApp->getDboSession(), track, LmsApp->getCurrentUser()).modify()->incPlayCount();
auto stats = Database::TrackStats::get(LmsApp->getDboSession(), track, LmsApp->getCurrentUser());
stats.modify()->incPlayCount();
stats.modify()->setLastPlayed(Wt::WLocalDateTime::currentServerDateTime().toUTC());
updateCurrentTrack(true);
}
+13 -14
View File
@@ -22,7 +22,6 @@
#include <Wt/WAnchor.h>
#include <Wt/WLineEdit.h>
#include <Wt/WLocalDateTime.h>
#include <Wt/WServer.h>
#include <Wt/WTemplate.h>
#include "database/Artist.hpp"
@@ -68,6 +67,7 @@ Artists::Artists(Filters* filters)
_container = bindNew<Wt::WContainerWidget>("artists");
_mostPlayedContainer = bindNew<Wt::WContainerWidget>("most-played-artists");
_recentlyAddedContainer = bindNew<Wt::WContainerWidget>("recently-added-artists");
_recentlyPlayedContainer = bindNew<Wt::WContainerWidget>("recently-played-artists");
_showMore = bindNew<Wt::WTemplate>("show-more", Wt::WString::tr("Lms.Explore.template.show-more"));
_showMore->addFunction("tr", &Wt::WTemplate::Functions::tr);
@@ -80,21 +80,9 @@ Artists::Artists(Filters* filters)
refresh();
refreshMostPlayed();
refreshRecentlyAdded();
refreshRecentlyPlayed();
filters->updated().connect(this, &Artists::refresh);
std::string sessionId = LmsApp->sessionId();
LmsApp->getMediaScanner().scanComplete().connect([=] (Scanner::MediaScanner::Stats stats)
{
if (stats.nbChanges() > 0)
{
Wt::WServer::instance()->post(sessionId, [=]
{
refreshRecentlyAdded();
LmsApp->triggerUpdate();
});
}
});
}
void
@@ -109,6 +97,17 @@ Artists::refreshRecentlyAdded()
addCompactEntries(_recentlyAddedContainer, artists);
}
void
Artists::refreshRecentlyPlayed()
{
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
auto artists = TrackStats::getLastPlayedArtists(LmsApp->getDboSession(), LmsApp->getCurrentUser(), 5);
_recentlyPlayedContainer->clear();
addCompactEntries(_recentlyPlayedContainer, artists);
}
void
Artists::refreshMostPlayed()
{
+4 -1
View File
@@ -38,9 +38,11 @@ class Artists : public Wt::WTemplate
Wt::Signal<Database::IdType> artistAdd;
Wt::Signal<Database::IdType> artistPlay;
private:
void refreshRecentlyAdded();
void refreshRecentlyPlayed();
void refreshMostPlayed();
private:
void refresh();
void addSome();
@@ -50,6 +52,7 @@ class Artists : public Wt::WTemplate
Wt::WContainerWidget* _container;
Wt::WContainerWidget* _mostPlayedContainer;
Wt::WContainerWidget* _recentlyAddedContainer;
Wt::WContainerWidget* _recentlyPlayedContainer;
};
} // namespace UserInterface
+17
View File
@@ -79,6 +79,7 @@ Explore::Explore()
Wt::WStackedWidget* stack = bindNew<Wt::WStackedWidget>("contents");
auto artists = std::make_unique<Artists>(_filters);
auto artists_raw = artists.get();
artists->artistAdd.connect(this, &Explore::handleArtistAdd);
artists->artistPlay.connect(this, &Explore::handleArtistPlay);
stack->addWidget(std::move(artists));
@@ -91,6 +92,7 @@ Explore::Explore()
stack->addWidget(std::move(artist));
auto releases = std::make_unique<Releases>(_filters);
auto releases_raw = releases.get();
releases->releaseAdd.connect(this, &Explore::handleReleaseAdd);
releases->releasePlay.connect(this, &Explore::handleReleasePlay);
stack->addWidget(std::move(releases));
@@ -102,6 +104,21 @@ Explore::Explore()
release->trackPlay.connect(this, &Explore::handleTrackPlay);
stack->addWidget(std::move(release));
_dbChanged.connect([=]
{
artists_raw->refreshRecentlyAdded();
releases_raw->refreshRecentlyAdded();
});
_trackPlayed.connect([=]
{
artists_raw->refreshMostPlayed();
artists_raw->refreshRecentlyPlayed();
releases_raw->refreshMostPlayed();
releases_raw->refreshRecentlyPlayed();
});
auto tracks = std::make_unique<Tracks>(_filters);
tracks->trackAdd.connect(this, &Explore::handleTrackAdd);
tracks->trackPlay.connect(this, &Explore::handleTrackPlay);
+6
View File
@@ -36,6 +36,9 @@ class Explore : public Wt::WTemplate
Wt::Signal<std::vector<Database::Track::pointer>> tracksAdd;
Wt::Signal<std::vector<Database::Track::pointer>> tracksPlay;
void handleDbChanged() { _dbChanged.emit(); };
void handleTrackPlayed(Database::IdType trackId) { _trackPlayed.emit(); }
private:
void handleArtistAdd(Database::IdType id);
@@ -48,6 +51,9 @@ class Explore : public Wt::WTemplate
void handleTracksPlay(std::vector<Database::Track::pointer> tracks);
Filters* _filters;
Wt::Signal<> _dbChanged;
Wt::Signal<> _trackPlayed;
};
} // namespace UserInterface
+18 -14
View File
@@ -18,7 +18,6 @@
*/
#include "ReleasesView.hpp"
#include <Wt/WServer.h>
#include <Wt/WAnchor.h>
#include <Wt/WImage.h>
@@ -87,6 +86,7 @@ _filters(filters)
_container = bindNew<Wt::WContainerWidget>("releases");
_mostPlayedContainer = bindNew<Wt::WContainerWidget>("most-played-releases");
_recentlyAddedContainer = bindNew<Wt::WContainerWidget>("recently-added-releases");
_recentlyPlayedContainer = bindNew<Wt::WContainerWidget>("recently-played-releases");
_showMore = bindNew<Wt::WTemplate>("show-more", Wt::WString::tr("Lms.Explore.show-more"));
_showMore->addFunction("tr", &Wt::WTemplate::Functions::tr);
@@ -96,28 +96,18 @@ _filters(filters)
}));
refreshRecentlyAdded();
refreshRecentlyPlayed();
refreshMostPlayed();
refresh();
filters->updated().connect(this, &Releases::refresh);
std::string sessionId = LmsApp->sessionId();
LmsApp->getMediaScanner().scanComplete().connect([=] (Scanner::MediaScanner::Stats stats)
{
if (stats.nbChanges() > 0)
{
Wt::WServer::instance()->post(sessionId, [=]
{
refreshRecentlyAdded();
LmsApp->triggerUpdate();
});
}
});
}
void
Releases::refreshRecentlyAdded()
{
LMS_LOG(UI, DEBUG) << "Refreshing recently added releases";
auto after = Wt::WLocalDateTime::currentServerDateTime().toUTC().addMonths(-1);
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
@@ -128,9 +118,23 @@ Releases::refreshRecentlyAdded()
addCompactEntries(_recentlyAddedContainer, releases);
}
void
Releases::refreshRecentlyPlayed()
{
LMS_LOG(UI, DEBUG) << "Refreshing recently played releases";
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
auto releases = TrackStats::getLastPlayedReleases(LmsApp->getDboSession(), LmsApp->getCurrentUser(), 5);
_recentlyPlayedContainer->clear();
addCompactEntries(_recentlyPlayedContainer, releases);
}
void
Releases::refreshMostPlayed()
{
LMS_LOG(UI, DEBUG) << "Refreshing most played releases";
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
+4 -1
View File
@@ -38,9 +38,11 @@ class Releases : public Wt::WTemplate
Wt::Signal<Database::IdType> releaseAdd;
Wt::Signal<Database::IdType> releasePlay;
private:
void refreshRecentlyAdded();
void refreshRecentlyPlayed();
void refreshMostPlayed();
private:
void refresh();
void addSome();
@@ -50,6 +52,7 @@ class Releases : public Wt::WTemplate
Wt::WContainerWidget* _container;
Wt::WContainerWidget* _mostPlayedContainer;
Wt::WContainerWidget* _recentlyAddedContainer;
Wt::WContainerWidget* _recentlyPlayedContainer;
};
} // namespace UserInterface