From 685d1828add27b971aeaf5758ac92d6bdf24f279 Mon Sep 17 00:00:00 2001 From: Kevin Whitaker <eyecreate@gmail.com> Date: Wed, 1 Feb 2017 22:13:40 -0500 Subject: [PATCH] add limits to places where offsets to avoid some syntax problems. Rename grooveplayer class to avoid conflict with official libgroove class. Add admin event. Write start of event loop that picks initial song. --- src/GroovePlayer.cpp | 57 ++++++++++++++++++++++++++++++++------------ src/GroovePlayer.h | 14 +++++------ src/main.cpp | 2 +- 3 files changed, 50 insertions(+), 23 deletions(-) diff --git a/src/GroovePlayer.cpp b/src/GroovePlayer.cpp index 7fcba4c..a53c4f5 100644 --- a/src/GroovePlayer.cpp +++ b/src/GroovePlayer.cpp @@ -27,10 +27,11 @@ #include <Wt/WLogger> #include <Wt/Dbo/Transaction> #include <groovefingerprinter/fingerprinter.h> +#include <grooveplayer/player.h> -std::filesystem::path GroovePlayer::musicScanDir = ""; +std::filesystem::path GroovePlayerMgr::musicScanDir = ""; -GroovePlayer::GroovePlayer(std::string dbFile) : sqliteConnection(dbFile) +GroovePlayerMgr::GroovePlayerMgr (std::string dbFile) : sqliteConnection(dbFile) { sqlSession.setConnection(this->sqliteConnection); sqlSession.mapClass<User>("user"); @@ -50,7 +51,7 @@ GroovePlayer::GroovePlayer(std::string dbFile) : sqliteConnection(dbFile) grooveEvents = new std::thread(grooveEventLoop); } -std::list<const AudioTrack*> GroovePlayer::getNextVoteBatch() +std::list<const AudioTrack*> GroovePlayerMgr::getNextVoteBatch() { /** * This method will attempt to pick 3 tracks that will be up for selection next. @@ -82,13 +83,13 @@ std::list<const AudioTrack*> GroovePlayer::getNextVoteBatch() if(trackAlbumCount > 0 && computerSlightOfHand > 3) { //Pick item from album - Wt::Dbo::ptr<AudioTrack> eligibleTrack = getInstance()->sqlSession.find<AudioTrack>().where("album = ?").offset(rand() % trackAlbumCount).bind(getCurrentTrack()->trackAlbumName); + Wt::Dbo::ptr<AudioTrack> eligibleTrack = getInstance()->sqlSession.find<AudioTrack>().where("album = ?").limit(1).offset(rand() % trackAlbumCount).bind(getCurrentTrack()->trackAlbumName); selectedTracks.push_back(eligibleTrack.get()); } else if(trackArtistCount > 0) { //Pick item from artist - Wt::Dbo::ptr<AudioTrack> eligibleTrack = getInstance()->sqlSession.find<AudioTrack>().where("artist = ?").offset(rand() % trackArtistCount).bind(getCurrentTrack()->trackArtistName); + Wt::Dbo::ptr<AudioTrack> eligibleTrack = getInstance()->sqlSession.find<AudioTrack>().where("artist = ?").limit(1).offset(rand() % trackArtistCount).bind(getCurrentTrack()->trackArtistName); selectedTracks.push_back(eligibleTrack.get()); } @@ -97,7 +98,7 @@ std::list<const AudioTrack*> GroovePlayer::getNextVoteBatch() if(trackGenreCount > 0) { //Pick item from genre - Wt::Dbo::ptr<AudioTrack> eligibleTrack = getInstance()->sqlSession.find<AudioTrack>().where("genre = ?").offset(rand() % trackGenreCount).bind(getCurrentTrack()->trackGenre); + Wt::Dbo::ptr<AudioTrack> eligibleTrack = getInstance()->sqlSession.find<AudioTrack>().where("genre = ?").limit(1).offset(rand() % trackGenreCount).bind(getCurrentTrack()->trackGenre); selectedTracks.push_back(eligibleTrack.get()); } @@ -111,35 +112,61 @@ std::list<const AudioTrack*> GroovePlayer::getNextVoteBatch() else if(trackNotGenreCount > 0) { //Pick from other genre - Wt::Dbo::ptr<AudioTrack> eligibleTrack = getInstance()->sqlSession.find<AudioTrack>().where("genre != ?").offset(rand() % trackNotGenreCount).bind(getCurrentTrack()->trackGenre); + Wt::Dbo::ptr<AudioTrack> eligibleTrack = getInstance()->sqlSession.find<AudioTrack>().where("genre != ?").limit(1).offset(rand() % trackNotGenreCount).bind(getCurrentTrack()->trackGenre); selectedTracks.push_back(eligibleTrack.get()); } else { //Pick randomly - Wt::Dbo::ptr<AudioTrack> eligibleTrack = getInstance()->sqlSession.find<AudioTrack>().offset(rand() % trackCount); + Wt::Dbo::ptr<AudioTrack> eligibleTrack = getInstance()->sqlSession.find<AudioTrack>().limit(1).offset(rand() % trackCount); selectedTracks.push_back(eligibleTrack.get()); } return selectedTracks; } -void GroovePlayer::grooveEventLoop() +void GroovePlayerMgr::grooveEventLoop() { /** - * On first boot, random track that has been played before will start(or random if no track has been played before). + * On first boot, random track that has been voted before will start(or random if no track has been played before). * When voting ends, if no vote was cast, the first will be picked 60% of the time with second being 30% of the time and third being picked 10% of the time. * Exception is if third track is a request, then it is picked. If another song is voted over this, it will be put in back of request queue. */ + + Wt::Dbo::Transaction transaction(getInstance()->sqlSession); + + //Wait until at least one track is in DB. + if(getInstance()->sqlSession.query<int>("select count(fingerprint) from tracks") < 1) + { + while(getInstance()->sqlSession.query<int>("select count(fingerprint) from tracks") < 1){} + } + + //Pick initial track and boostrap player. + int tracksPlayedBefore = getInstance()->sqlSession.query<int>("select count(fingerprint) from tracks as t join actions on (actions.action = 3 or actions.action = 2) and actions.track_id = t.id"); + const AudioTrack* selectedTrack; + if (tracksPlayedBefore > 0) + { + selectedTrack = getInstance()->sqlSession.query<Wt::Dbo::ptr<AudioTrack>>("select t from tracks as t join actions on (actions.action = 3 or actions.action = 2) and actions.track_id = t.id").limit(1).offset(rand() % tracksPlayedBefore).resultValue().get(); + } + else + { + int trackCount = getInstance()->sqlSession.query<int>("select count(fingerprint) from tracks"); + selectedTrack = getInstance()->sqlSession.find<AudioTrack>().limit(1).offset(rand() % trackCount).resultValue().get(); + } + struct GroovePlaylist* playlist = groove_playlist_create(); + struct GroovePlayer* player = groove_player_create(); + if(!player) {return;} + + //TODO } -GroovePlayer::PlayerEvents GroovePlayer::getNextPlayerEvent() +GroovePlayerMgr::PlayerEvents GroovePlayerMgr::getNextPlayerEvent() { //TODO } -Wt::Dbo::ptr<AudioTrack> GroovePlayer::getCurrentTrack() +Wt::Dbo::ptr<AudioTrack> GroovePlayerMgr::getCurrentTrack() { Wt::Dbo::Transaction transaction(getInstance()->sqlSession); Wt::Dbo::ptr<AudioTrack> track = getInstance()->sqlSession.find<AudioTrack>().where("path = ?").bind(currentItem->file->filename); @@ -147,7 +174,7 @@ Wt::Dbo::ptr<AudioTrack> GroovePlayer::getCurrentTrack() } -bool GroovePlayer::addFileToTrackDBIfTagged(std::filesystem::path file) +bool GroovePlayerMgr::addFileToTrackDBIfTagged(std::filesystem::path file) { //Now check if tags exist and put into DB. struct GrooveFile* gfile = groove_file_open(file.c_str()); @@ -202,7 +229,7 @@ bool GroovePlayer::addFileToTrackDBIfTagged(std::filesystem::path file) return true; } -void GroovePlayer::removeOrphanedTracks() +void GroovePlayerMgr::removeOrphanedTracks() { Wt::Dbo::Transaction transaction(getInstance()->sqlSession); Wt::Dbo::collection<Wt::Dbo::ptr<AudioTrack>> tracks = getInstance()->sqlSession.find<AudioTrack>(); @@ -219,7 +246,7 @@ void GroovePlayer::removeOrphanedTracks() -void GroovePlayer::grooveAudioScannerLoop() +void GroovePlayerMgr::grooveAudioScannerLoop() { if(!std::filesystem::exists(musicScanDir)) { diff --git a/src/GroovePlayer.h b/src/GroovePlayer.h index 71939d3..57845e5 100644 --- a/src/GroovePlayer.h +++ b/src/GroovePlayer.h @@ -32,21 +32,21 @@ namespace std { namespace filesystem = experimental::filesystem; } -class GroovePlayer +class GroovePlayerMgr { public: static std::filesystem::path musicScanDir; - static GroovePlayer* getInstance() { - static GroovePlayer instance("music.db"); + static GroovePlayerMgr* getInstance() { + static GroovePlayerMgr instance("music.db"); musicScanDir = std::filesystem::path("music"); return &instance; }; - GroovePlayer(GroovePlayer const&) = delete; - void operator=(GroovePlayer const&) = delete; + GroovePlayerMgr ( GroovePlayerMgr const&) = delete; + void operator=( GroovePlayerMgr const&) = delete; private: - enum PlayerEvents {NOTHING, GROOVE_NOWPLAYING, VOTING_ENDED, VOTE_CAST, PLAYING_PAUSED, PLAYING_RESUMED, SKIP_REQUESTED, SKIP_VOTE_CAST, SKIP_VOTING_ENDED}; + enum PlayerEvents {NOTHING, GROOVE_NOWPLAYING, VOTING_ENDED, VOTE_CAST, PLAYING_PAUSED, PLAYING_RESUMED, SKIP_REQUESTED, SKIP_VOTE_CAST, SKIP_VOTING_ENDED, ADMIN_FORCE_SKIP}; - GroovePlayer(std::string dbFile); + GroovePlayerMgr (std::string dbFile); Wt::Dbo::backend::Sqlite3 sqliteConnection; Wt::Dbo::Session sqlSession; diff --git a/src/main.cpp b/src/main.cpp index 62d3171..6ddfe8c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -17,7 +17,7 @@ int main ( int argc, char** argv ) server.addEntryPoint(Wt::Application, createApplication); if(server.start()) { - GroovePlayer::getInstance(); + GroovePlayerMgr::getInstance(); int sig = Wt::WServer::waitForShutdown(argv[0]); server.stop(); } -- GitLab