Various UI small improvements (better error reporting in case of bad url, made the password change fields more explicit)
This commit is contained in:
@@ -82,6 +82,7 @@ lms_SOURCES = \
|
||||
$(srcdir)/ui/Auth.hpp \
|
||||
$(srcdir)/ui/LmsApplication.cpp \
|
||||
$(srcdir)/ui/LmsApplication.hpp \
|
||||
$(srcdir)/ui/LmsApplicationException.hpp \
|
||||
$(srcdir)/ui/LmsApplicationGroup.cpp \
|
||||
$(srcdir)/ui/LmsApplicationGroup.hpp \
|
||||
$(srcdir)/ui/MediaPlayer.cpp \
|
||||
|
||||
@@ -92,8 +92,11 @@ networkToCacheFile(const SOM::Network& network, std::filesystem::path path)
|
||||
|
||||
static
|
||||
std::optional<SOM::Network>
|
||||
createNetworkFromCacheFile(std::filesystem::path path)
|
||||
createNetworkFromCacheFile(const std::filesystem::path& path)
|
||||
{
|
||||
if (!std::filesystem::exists(path))
|
||||
return std::nullopt;
|
||||
|
||||
try
|
||||
{
|
||||
LMS_LOG(SIMILARITY, INFO) << "Reading network from cache...";
|
||||
|
||||
+46
-22
@@ -48,6 +48,7 @@
|
||||
#include "resource/ImageResource.hpp"
|
||||
#include "resource/AudioResource.hpp"
|
||||
#include "Auth.hpp"
|
||||
#include "LmsApplicationException.hpp"
|
||||
#include "MediaPlayer.hpp"
|
||||
#include "PlayHistoryView.hpp"
|
||||
#include "PlayQueueView.hpp"
|
||||
@@ -134,6 +135,7 @@ LmsApplication::LmsApplication(const Wt::WEnvironment& env,
|
||||
messageResourceBundle().use(appRoot() + "artistlink");
|
||||
messageResourceBundle().use(appRoot() + "artists");
|
||||
messageResourceBundle().use(appRoot() + "artistsinfo");
|
||||
messageResourceBundle().use(appRoot() + "error");
|
||||
messageResourceBundle().use(appRoot() + "explore");
|
||||
messageResourceBundle().use(appRoot() + "login");
|
||||
messageResourceBundle().use(appRoot() + "mediaplayer");
|
||||
@@ -178,7 +180,20 @@ LmsApplication::LmsApplication(const Wt::WEnvironment& env,
|
||||
const auto userId {processAuthToken(env)};
|
||||
if (userId)
|
||||
{
|
||||
handleUserLoggedIn(*userId, false);
|
||||
try
|
||||
{
|
||||
handleUserLoggedIn(*userId, false);
|
||||
}
|
||||
catch (LmsApplicationException& e)
|
||||
{
|
||||
LMS_LOG(UI, WARNING) << "Caught a LmsApplication exception: " << e.what();
|
||||
handleException(e);
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
LMS_LOG(UI, ERROR) << "Caught exception: " << e.what();
|
||||
throw LmsException {"Internal error"}; // Do not put details here at it may appear on the user rendered html
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -267,9 +282,19 @@ LmsApplication::createCluster(Database::Cluster::pointer cluster, bool canDelete
|
||||
}
|
||||
|
||||
void
|
||||
LmsApplication::goHome()
|
||||
LmsApplication::handleException(LmsApplicationException& e)
|
||||
{
|
||||
setInternalPath("/artists", true);
|
||||
root()->clear();
|
||||
Wt::WTemplate* t {root()->addNew<Wt::WTemplate>(Wt::WString::tr("Lms.Error.template"))};
|
||||
t->addFunction("tr", &Wt::WTemplate::Functions::tr);
|
||||
|
||||
t->bindString("error", e.what());
|
||||
Wt::WPushButton* btn {t->bindNew<Wt::WPushButton>("btn-go-home", Wt::WString::tr("Lms.Error.go-home"))};
|
||||
btn->clicked().connect([this]()
|
||||
{
|
||||
setConfirmCloseMessage("");
|
||||
redirect("/");
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
@@ -359,25 +384,17 @@ LmsApplication::handleUserLoggedIn(Database::IdType userId, bool strongAuth)
|
||||
|
||||
root()->clear();
|
||||
|
||||
try
|
||||
const LmsApplicationInfo info {LmsApplicationInfo::fromEnvironment(environment())};
|
||||
|
||||
LMS_LOG(UI, INFO) << "User '" << getUserLoginName() << "' logged in from '" << environment().clientAddress() << "', user agent = " << environment().userAgent();
|
||||
getApplicationGroup().join(info);
|
||||
|
||||
getApplicationGroup().postOthers([info]
|
||||
{
|
||||
const LmsApplicationInfo info {LmsApplicationInfo::fromEnvironment(environment())};
|
||||
LmsApp->getEvents().appOpen(info);
|
||||
});
|
||||
|
||||
LMS_LOG(UI, INFO) << "User '" << getUserLoginName() << "' logged in from '" << environment().clientAddress() << "', user agent = " << environment().userAgent();
|
||||
getApplicationGroup().join(info);
|
||||
|
||||
getApplicationGroup().postOthers([info]
|
||||
{
|
||||
LmsApp->getEvents().appOpen(info);
|
||||
});
|
||||
|
||||
createHome();
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
LMS_LOG(UI, ERROR) << "Error while handling auth event: " << e.what();
|
||||
throw LmsException {"Internal error"}; // Do not put details here at it appears on the user rendered html
|
||||
}
|
||||
createHome();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -581,10 +598,15 @@ LmsApplication::notify(const Wt::WEvent& event)
|
||||
{
|
||||
WApplication::notify(event);
|
||||
}
|
||||
catch (LmsApplicationException& e)
|
||||
{
|
||||
LMS_LOG(UI, WARNING) << "Caught a LmsApplication exception: " << e.what();
|
||||
handleException(e);
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
LMS_LOG(UI, ERROR) << "Caught exception: " << e.what();
|
||||
throw LmsException("Internal error"); // Do not put details here at it appears on the user rendered html
|
||||
throw LmsException {"Internal error"}; // Do not put details here at it may appear on the user rendered html
|
||||
}
|
||||
}
|
||||
|
||||
@@ -606,7 +628,9 @@ LmsApplication::post(std::function<void()> func)
|
||||
Wt::WServer::instance()->post(LmsApp->sessionId(), std::move(func));
|
||||
}
|
||||
|
||||
static std::string escape(std::string str)
|
||||
static
|
||||
std::string
|
||||
escape(const std::string& str)
|
||||
{
|
||||
return replaceInString(std::move(str), "\'", "\\\'");
|
||||
}
|
||||
|
||||
@@ -38,8 +38,9 @@ namespace Database {
|
||||
namespace UserInterface {
|
||||
|
||||
class AudioResource;
|
||||
class ImageResource;
|
||||
class Auth;
|
||||
class ImageResource;
|
||||
class LmsApplicationException;
|
||||
|
||||
// Events that can be listen from anywhere in the application
|
||||
struct Events
|
||||
@@ -91,9 +92,6 @@ class LmsApplication : public Wt::WApplication
|
||||
Events& getEvents() { return _events; }
|
||||
|
||||
// Utils
|
||||
void goHome();
|
||||
void goHomeAndQuit();
|
||||
|
||||
void post(std::function<void()> func);
|
||||
void notifyMsg(MsgType type, const Wt::WString& message, std::chrono::milliseconds duration = std::chrono::milliseconds(4000));
|
||||
|
||||
@@ -108,6 +106,9 @@ class LmsApplication : public Wt::WApplication
|
||||
|
||||
private:
|
||||
|
||||
void handleException(LmsApplicationException& e);
|
||||
void goHomeAndQuit();
|
||||
|
||||
LmsApplicationGroup& getApplicationGroup();
|
||||
|
||||
// Signal slots
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Emeric Poupon
|
||||
*
|
||||
* This file is part of LMS.
|
||||
*
|
||||
* LMS is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* LMS is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "database/Types.hpp"
|
||||
#include "utils/Exception.hpp"
|
||||
|
||||
namespace UserInterface {
|
||||
|
||||
|
||||
class LmsApplicationException : public LmsException
|
||||
{
|
||||
public:
|
||||
LmsApplicationException(const Wt::WString& error) : LmsException {error.toUTF8()} {}
|
||||
};
|
||||
|
||||
class ArtistNotFoundException : public LmsApplicationException
|
||||
{
|
||||
public:
|
||||
ArtistNotFoundException(Database::IdType artistId) : LmsApplicationException {Wt::WString::tr("Lms.Error.artist-not-found").arg(artistId)} {}
|
||||
};
|
||||
|
||||
class ReleaseNotFoundException : public LmsApplicationException
|
||||
{
|
||||
public:
|
||||
ReleaseNotFoundException(Database::IdType releaseId) : LmsApplicationException {Wt::WString::tr("Lms.Error.release-not-found").arg(releaseId)} {}
|
||||
};
|
||||
|
||||
class UserNotFoundException : public LmsApplicationException
|
||||
{
|
||||
public:
|
||||
UserNotFoundException(Database::IdType userId) : LmsApplicationException {Wt::WString::tr("Lms.Error.user-not-found").arg(userId)} {}
|
||||
};
|
||||
|
||||
class UserNotAllowedException : public LmsApplicationException
|
||||
{
|
||||
public:
|
||||
UserNotAllowedException() : LmsApplicationException {Wt::WString::tr("Lms.Error.user-not-allowed")} {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "common/Validators.hpp"
|
||||
#include "common/ValueStringModel.hpp"
|
||||
#include "LmsApplication.hpp"
|
||||
#include "LmsApplicationException.hpp"
|
||||
|
||||
namespace UserInterface {
|
||||
|
||||
@@ -54,8 +55,7 @@ class UserModel : public Wt::WFormModel
|
||||
static const Field DemoField;
|
||||
|
||||
UserModel(std::optional<Database::IdType> userId)
|
||||
: Wt::WFormModel(),
|
||||
_userId(userId)
|
||||
: _userId {userId}
|
||||
{
|
||||
if (!_userId)
|
||||
{
|
||||
@@ -126,8 +126,10 @@ class UserModel : public Wt::WFormModel
|
||||
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
|
||||
|
||||
const Database::User::pointer user {Database::User::getById(LmsApp->getDbSession(), *_userId)};
|
||||
if (user == LmsApp->getUser())
|
||||
throw LmsException("Cannot edit ourselves");
|
||||
if (!user)
|
||||
throw UserNotFoundException {*_userId};
|
||||
else if (user == LmsApp->getUser())
|
||||
throw UserNotAllowedException {};
|
||||
|
||||
auto transcodeBitrateLimitRow {_bitrateModel->getRowFromValue(user->getMaxAudioTranscodeBitrate())};
|
||||
if (transcodeBitrateLimitRow)
|
||||
@@ -240,12 +242,13 @@ UserView::refreshView()
|
||||
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
|
||||
|
||||
const Database::User::pointer user {Database::User::getById(LmsApp->getDbSession(), *userId)};
|
||||
if (!user)
|
||||
throw UserNotFoundException {*userId};
|
||||
|
||||
t->bindString("title", Wt::WString::tr("Lms.Admin.User.user-edit").arg(user->getLoginName()), Wt::TextFormat::Plain);
|
||||
t->setCondition("if-has-last-login", true);
|
||||
|
||||
Wt::WLineEdit *lastLogin {t->bindNew<Wt::WLineEdit>("last-login")};
|
||||
lastLogin->setText(user->getLastLogin().toString());
|
||||
lastLogin->setEnabled(false);
|
||||
t->bindString("last-login", user->getLastLogin().toString(), Wt::TextFormat::Plain);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "resource/ImageResource.hpp"
|
||||
|
||||
#include "LmsApplication.hpp"
|
||||
#include "LmsApplicationException.hpp"
|
||||
#include "Filters.hpp"
|
||||
|
||||
using namespace Database;
|
||||
@@ -70,10 +71,7 @@ Artist::refresh()
|
||||
|
||||
const Database::Artist::pointer artist = Database::Artist::getById(LmsApp->getDbSession(), *artistId);
|
||||
if (!artist)
|
||||
{
|
||||
LmsApp->goHome();
|
||||
return;
|
||||
}
|
||||
throw ArtistNotFoundException {*artistId};
|
||||
|
||||
Wt::WTemplate* t {addNew<Wt::WTemplate>(Wt::WString::tr("Lms.Explore.Artist.template"))};
|
||||
t->addFunction("tr", &Wt::WTemplate::Functions::tr);
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "resource/ImageResource.hpp"
|
||||
|
||||
#include "LmsApplication.hpp"
|
||||
#include "LmsApplicationException.hpp"
|
||||
#include "Filters.hpp"
|
||||
|
||||
using namespace Database;
|
||||
@@ -71,10 +72,7 @@ Release::refresh()
|
||||
|
||||
const Database::Release::pointer release {Database::Release::getById(LmsApp->getDbSession(), *releaseId)};
|
||||
if (!release)
|
||||
{
|
||||
LmsApp->goHome();
|
||||
return;
|
||||
}
|
||||
throw ReleaseNotFoundException {*releaseId};
|
||||
|
||||
Wt::WTemplate* t {addNew<Wt::WTemplate>(Wt::WString::tr("Lms.Explore.Release.template"))};
|
||||
t->addFunction("tr", &Wt::WTemplate::Functions::tr);
|
||||
|
||||
@@ -25,6 +25,6 @@
|
||||
class LmsException : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
LmsException(const std::string& error) : std::runtime_error(error) {}
|
||||
LmsException(const std::string& error = "") : std::runtime_error {error} {}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user