Added an ApplicationGroup system to track the multiple sessions open by a user

This commit is contained in:
emeric
2018-06-22 13:10:19 +02:00
parent ed008533b2
commit c427396623
13 changed files with 274 additions and 71 deletions
+83 -37
View File
@@ -50,13 +50,13 @@
namespace UserInterface {
std::unique_ptr<Wt::WApplication>
LmsApplication::create(const Wt::WEnvironment& env, Wt::Dbo::SqlConnectionPool& connectionPool, Scanner::MediaScanner& scanner)
LmsApplication::create(const Wt::WEnvironment& env, Wt::Dbo::SqlConnectionPool& connectionPool, LmsApplicationGroups& appGroups, Scanner::MediaScanner& scanner)
{
/*
* You could read information from the environment to decide whether
* the user has permission to start a new application
*/
return std::make_unique<LmsApplication>(env, connectionPool, scanner);
return std::make_unique<LmsApplication>(env, connectionPool, appGroups, scanner);
}
LmsApplication*
@@ -71,9 +71,10 @@ LmsApplication::instance()
* constructor so it is typically also an argument for your custom
* application constructor.
*/
LmsApplication::LmsApplication(const Wt::WEnvironment& env, Wt::Dbo::SqlConnectionPool& connectionPool, Scanner::MediaScanner& scanner)
LmsApplication::LmsApplication(const Wt::WEnvironment& env, Wt::Dbo::SqlConnectionPool& connectionPool, LmsApplicationGroups& appGroups, Scanner::MediaScanner& scanner)
: Wt::WApplication(env),
_db(connectionPool),
_appGroups(appGroups),
_scanner(scanner),
_imageResource(nullptr),
_transcodeResource(nullptr)
@@ -125,23 +126,23 @@ LmsApplication::LmsApplication(const Wt::WEnvironment& env, Wt::Dbo::SqlConnecti
}
else
{
LmsApp->getDb().getLogin().changed().connect(std::bind([=]
{
try
{
handleAuthEvent();
}
catch (std::exception& e)
{
LMS_LOG(UI, ERROR) << "Error while handling auth event: " << e.what();
throw std::runtime_error("Internal error");
}
}));
LmsApp->getDb().getLogin().changed().connect(this, &LmsApplication::handleAuthEvent);
_auth = root()->addNew<Auth>();
}
}
LmsApplication::~LmsApplication()
{
LmsApplicationInfo info = LmsApplicationInfo::fromEnvironment(environment());
getApplicationGroup().postOthers([info]
{
LmsApp->getGroupEvents().appClosed(info);
});
getApplicationGroup().leave();
}
std::unique_ptr<Wt::WAnchor>
LmsApplication::createArtistAnchor(Database::Artist::pointer artist, bool addText)
{
@@ -250,25 +251,56 @@ handlePathChange(Wt::WStackedWidget* stack, bool isAdmin)
wApp->setInternalPath("/artists", true);
}
void
LmsApplication::handleAuthEvent(void)
LmsApplicationGroup&
LmsApplication::getApplicationGroup()
{
if (!LmsApp->getDb().getLogin().loggedIn())
return _appGroups[_userIdentity];
}
void
LmsApplication::handleAuthEvent()
{
try
{
LMS_LOG(UI, INFO) << "User logged out, session = " << Wt::WApplication::instance()->sessionId();
if (!getDb().getLogin().loggedIn())
{
LMS_LOG(UI, INFO) << "User '" << _userIdentity << " 'logged out, session = " << sessionId();
goHomeAndQuit();
return;
goHomeAndQuit();
return;
}
else
{
_userIdentity = getAuthUser().identity(Wt::Auth::Identity::LoginName);
LmsApplicationInfo info = LmsApplicationInfo::fromEnvironment(environment());
LMS_LOG(UI, INFO) << "User '" << _userIdentity << "' logged in from '" << environment().clientAddress() << "', user agent = " << environment().userAgent() << ", session = " << sessionId();
getApplicationGroup().join(info);
getApplicationGroup().postOthers([info]
{
LmsApp->getGroupEvents().appOpen(info);
});
createHome();
}
}
catch (std::exception& e)
{
LMS_LOG(UI, ERROR) << "Error while handling auth event: " << e.what();
throw std::runtime_error("Internal error");
}
}
LMS_LOG(UI, INFO) << "User '" << LmsApp->getCurrentAuthUser().identity(Wt::Auth::Identity::LoginName) << "' logged in from '" << Wt::WApplication::instance()->environment().clientAddress() << "', user agent = " << Wt::WApplication::instance()->environment().userAgent() << ", session = " << Wt::WApplication::instance()->sessionId();
// Since we plug into the Media Scanner events, we need to enable updates
void
LmsApplication::createHome()
{
// Handle Media Scanner events and other session events
enableUpdates(true);
{
Wt::Dbo::Transaction transaction (LmsApp->getDboSession());
_isAdmin = LmsApp->getCurrentUser()->isAdmin();
_isAdmin = LmsApp->getUser()->isAdmin();
}
_imageResource = std::make_shared<ImageResource>(_db);
@@ -355,33 +387,33 @@ LmsApplication::handleAuthEvent(void)
mainStack->addNew<UserView>();
}
explore->tracksAdd.connect(std::bind([=] (std::vector<Database::Track::pointer> tracks)
explore->tracksAdd.connect([=] (std::vector<Database::Track::pointer> tracks)
{
playqueue->addTracks(tracks);
}, std::placeholders::_1));
});
explore->tracksPlay.connect(std::bind([=] (std::vector<Database::Track::pointer> tracks)
explore->tracksPlay.connect([=] (std::vector<Database::Track::pointer> tracks)
{
playqueue->playTracks(tracks);
}, std::placeholders::_1));
});
// MediaPlayer
MediaPlayer* player = main->bindNew<MediaPlayer>("player");
// Events from MediaPlayer
player->playNext.connect(std::bind([=]
player->playNext.connect([=]
{
playqueue->playNext();
}));
player->playPrevious.connect(std::bind([=]
});
player->playPrevious.connect([=]
{
playqueue->playPrevious();
}));
player->playbackEnded.connect(std::bind([=]
});
player->playbackEnded.connect([=]
{
playqueue->playNext();
}));
});
// Events from the PlayQueue
playqueue->playTrack.connect(explore, &Explore::handleTrackPlayed);
@@ -390,7 +422,7 @@ LmsApplication::handleAuthEvent(void)
playqueue->playbackStop.connect(player, &MediaPlayer::stop);
// Events from MediaScanner
std::string sessionId = this->sessionId();
std::string sessionId = LmsApp->sessionId();
_scanner.scanComplete().connect([=] (Scanner::MediaScanner::Stats stats)
{
Wt::WServer::instance()->post(sessionId, [=]
@@ -420,6 +452,19 @@ LmsApplication::handleAuthEvent(void)
});
});
// Events from Application group
_groupEvents.appOpen.connect([=] (LmsApplicationInfo info)
{
// Only one active session by user
setConfirmCloseMessage("");
quit(Wt::WString::tr("Lms.quit-other-session"));
});
_groupEvents.appClosed.connect([=] (LmsApplicationInfo info)
{
;
});
internalPathChanged().connect(std::bind([=]
{
handlePathChange(mainStack, _isAdmin);
@@ -449,6 +494,7 @@ LmsApplication::notifyMsg(const Wt::WString& message)
root()->addNew<Wt::WText>(message);
}
} // namespace UserInterface