Rework DB session + transactions. Now can handle multiple read only transactions in parallel

This commit is contained in:
emeric
2019-07-16 13:17:23 +02:00
parent 2a1fb0182b
commit 38ce2600d2
79 changed files with 1840 additions and 1369 deletions
+12 -12
View File
@@ -34,21 +34,21 @@ namespace UserInterface {
Auth::Auth()
: Wt::WTemplateFormView(Wt::WString::tr("Lms.Auth.template"))
{
_model = std::make_shared<Wt::Auth::AuthModel>(LmsApp->getDb().getAuthService(), LmsApp->getDb().getUserDatabase());
_model->addPasswordAuth(&Database::Handler::getPasswordService());
_model = std::make_shared<Wt::Auth::AuthModel>(LmsApp->getDbSession().getAuthService(), LmsApp->getDbSession().getUserDatabase());
_model->addPasswordAuth(&Database::Session::getPasswordService());
// LoginName
setFormWidget(Wt::Auth::AuthModel::LoginNameField, std::make_unique<Wt::WLineEdit>());
{
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
auto demoUser = Database::User::getDemo(LmsApp->getDboSession());
auto demoUser = Database::User::getDemo(LmsApp->getDbSession());
if (demoUser)
{
Wt::Auth::User authUser = LmsApp->getDb().getUserDatabase().findWithId(std::to_string(demoUser.id()));
_model->setValue(Wt::Auth::AuthModel::LoginNameField, authUser.identity(Wt::Auth::Identity::LoginName));
_model->setValue(Wt::Auth::AuthModel::PasswordField, authUser.identity(Wt::Auth::Identity::LoginName));
const std::string userName {LmsApp->getDbSession().getUserLoginName(demoUser)};
_model->setValue(Wt::Auth::AuthModel::LoginNameField, userName );
_model->setValue(Wt::Auth::AuthModel::PasswordField, userName);
}
}
@@ -64,9 +64,9 @@ Auth::Auth()
Wt::WPushButton* loginBtn = bindNew<Wt::WPushButton>("login-btn", Wt::WString::tr("Lms.login"));
loginBtn->clicked().connect(this, &Auth::processAuth);
LmsApp->getDb().getLogin().changed().connect(std::bind([=]
LmsApp->getDbSession().getLogin().changed().connect(std::bind([=]
{
if (LmsApp->getDb().getLogin().loggedIn())
if (LmsApp->getDbSession().getLogin().loggedIn())
this->setHidden(true);
}));
@@ -76,7 +76,7 @@ Auth::Auth()
if (user.isValid())
{
LMS_LOG(UI, DEBUG) << "Valid user found from auth token (id = " << user.id() << ")";
_model->loginUser(LmsApp->getDb().getLogin(), user, Wt::Auth::LoginState::Weak);
_model->loginUser(LmsApp->getDbSession().getLogin(), user, Wt::Auth::LoginState::Weak);
}
}
@@ -86,7 +86,7 @@ Auth::processAuth()
updateModel(_model.get());
if (_model->validate())
_model->login(LmsApp->getDb().getLogin());
_model->login(LmsApp->getDbSession().getLogin());
else
updateView(_model.get());
}
@@ -94,7 +94,7 @@ Auth::processAuth()
void
Auth::logout()
{
_model->logout(LmsApp->getDb().getLogin());
_model->logout(LmsApp->getDbSession().getLogin());
}
} // namespace UserInterface
+47 -45
View File
@@ -55,9 +55,9 @@
namespace UserInterface {
std::unique_ptr<Wt::WApplication>
LmsApplication::create(const Wt::WEnvironment& env, Wt::Dbo::SqlConnectionPool& connectionPool, LmsApplicationGroupContainer& appGroups)
LmsApplication::create(const Wt::WEnvironment& env, Database::Database& db, LmsApplicationGroupContainer& appGroups)
{
return std::make_unique<LmsApplication>(env, connectionPool, appGroups);
return std::make_unique<LmsApplication>(env, db.createSession(), appGroups);
}
LmsApplication*
@@ -67,11 +67,11 @@ LmsApplication::instance()
}
LmsApplication::LmsApplication(const Wt::WEnvironment& env,
Wt::Dbo::SqlConnectionPool& connectionPool,
std::unique_ptr<Database::Session> dbSession,
LmsApplicationGroupContainer& appGroups)
: Wt::WApplication(env),
_db(connectionPool),
_appGroups(appGroups)
: Wt::WApplication {env},
_dbSession {std::move(dbSession)},
_appGroups {appGroups}
{
auto bootstrapTheme = std::make_unique<Wt::WBootstrapTheme>();
bootstrapTheme->setVersion(Wt::BootstrapVersion::v3);
@@ -116,12 +116,14 @@ LmsApplication::LmsApplication(const Wt::WEnvironment& env,
setTitle("LMS");
// If here is no account in the database, launch the first connection wizard
bool firstConnection;
{
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
// Handle Media Scanner events and other session events
enableUpdates(true);
firstConnection = (Database::User::getAll(LmsApp->getDboSession()).size() == 0);
// If here is no account in the database, launch the first connection wizard
bool firstConnection {};
{
auto transaction {_dbSession->createSharedTransaction()};
firstConnection = Database::User::getAll(*_dbSession).empty();
}
LMS_LOG(UI, DEBUG) << "Creating root widget. First connection = " << firstConnection;
@@ -132,7 +134,7 @@ LmsApplication::LmsApplication(const Wt::WEnvironment& env,
}
else
{
LmsApp->getDb().getLogin().changed().connect(this, &LmsApplication::handleAuthEvent);
LmsApp->getDbSession().getLogin().changed().connect(this, &LmsApplication::handleAuthEvent);
_auth = root()->addNew<Auth>();
}
}
@@ -260,7 +262,7 @@ handlePathChange(Wt::WStackedWidget* stack, bool isAdmin)
LMS_LOG(UI, DEBUG) << "Internal path changed to '" << wApp->internalPath() << "'";
for (auto& view : views)
for (const auto& view : views)
{
if (wApp->internalPathMatches(view.path))
{
@@ -284,46 +286,46 @@ LmsApplication::getApplicationGroup()
void
LmsApplication::handleAuthEvent()
{
if (!getDbSession().getLogin().loggedIn())
{
LMS_LOG(UI, INFO) << "User '" << _userIdentity << " 'logged out, session = " << sessionId();
goHomeAndQuit();
return;
}
try
{
if (!getDb().getLogin().loggedIn())
// post([this]
// {
_userIdentity = getAuthUser().identity(Wt::Auth::Identity::LoginName);
const 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]
{
LMS_LOG(UI, INFO) << "User '" << _userIdentity << " 'logged out, session = " << sessionId();
LmsApp->getEvents().appOpen(info);
});
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->getEvents().appOpen(info);
});
createHome();
}
createHome();
triggerUpdate();
// });
}
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
throw LmsException {"Internal error"}; // Do not put details here at it appears on the user rendered html
}
}
void
LmsApplication::createHome()
{
// Handle Media Scanner events and other session events
enableUpdates(true);
{
Wt::Dbo::Transaction transaction (LmsApp->getDboSession());
auto transaction {_dbSession->createSharedTransaction()};
_isAdmin = LmsApp->getUser()->isAdmin();
}
@@ -332,14 +334,14 @@ LmsApplication::createHome()
setConfirmCloseMessage(Wt::WString::tr("Lms.quit-confirm"));
Wt::WTemplate* main = root()->addWidget(std::make_unique<Wt::WTemplate>(Wt::WString::tr("Lms.template")));
Wt::WTemplate* main {root()->addWidget(std::make_unique<Wt::WTemplate>(Wt::WString::tr("Lms.template")))};
// Navbar
Wt::WNavigationBar* navbar = main->bindNew<Wt::WNavigationBar>("navbar-top");
navbar->setTitle("LMS", Wt::WLink(Wt::LinkType::InternalPath, "/artists"));
navbar->setResponsive(true);
Wt::WMenu* menu = navbar->addMenu(std::make_unique<Wt::WMenu>());
Wt::WMenu* menu {navbar->addMenu(std::make_unique<Wt::WMenu>())};
{
auto menuItem = menu->insertItem(0, Wt::WString::tr("Lms.Explore.artists"));
menuItem->setLink(Wt::WLink(Wt::LinkType::InternalPath, "/artists"));
@@ -417,14 +419,14 @@ LmsApplication::createHome()
mainStack->addNew<UserView>();
}
explore->tracksAdd.connect([=] (std::vector<Database::Track::pointer> tracks)
explore->tracksAdd.connect([=] (const std::vector<Database::IdType>& trackIds)
{
playqueue->addTracks(tracks);
playqueue->addTracks(trackIds);
});
explore->tracksPlay.connect([=] (std::vector<Database::Track::pointer> tracks)
explore->tracksPlay.connect([=] (const std::vector<Database::IdType>& trackIds)
{
playqueue->playTracks(tracks);
playqueue->playTracks(trackIds);
});
@@ -459,7 +461,7 @@ LmsApplication::createHome()
// Events from MediaScanner
{
std::string sessionId = LmsApp->sessionId();
const std::string sessionId {LmsApp->sessionId()};
getService<Scanner::MediaScanner>()->scanComplete().connect(this, [=] (Scanner::MediaScanner::Stats stats)
{
Wt::WServer::instance()->post(sessionId, [=]
@@ -551,7 +553,7 @@ static std::string msgTypeToString(MsgType type)
void
LmsApplication::post(std::function<void()> func)
{
Wt::WServer::instance()->post(LmsApp->sessionId(), func);
Wt::WServer::instance()->post(LmsApp->sessionId(), std::move(func));
}
static std::string escape(std::string str)
+16 -18
View File
@@ -23,9 +23,8 @@
#include <boost/optional.hpp>
#include <Wt/WApplication.h>
#include <Wt/Dbo/SqlConnectionPool.h>
#include "database/DatabaseHandler.hpp"
#include "database/Database.hpp"
#include "scanner/MediaScanner.hpp"
#include "LmsApplicationGroup.hpp"
@@ -35,6 +34,7 @@ namespace Database {
class Artist;
class Cluster;
class Release;
class User;
}
namespace UserInterface {
@@ -73,20 +73,18 @@ enum class MsgType
class LmsApplication : public Wt::WApplication
{
public:
LmsApplication(const Wt::WEnvironment& env, Wt::Dbo::SqlConnectionPool& connectionPool, LmsApplicationGroupContainer& appGroups);
LmsApplication(const Wt::WEnvironment& env, std::unique_ptr<Database::Session> dbSession, LmsApplicationGroupContainer& appGroups);
static std::unique_ptr<Wt::WApplication> create(const Wt::WEnvironment& env,
Wt::Dbo::SqlConnectionPool& connectionPool, LmsApplicationGroupContainer& appGroups);
static std::unique_ptr<Wt::WApplication> create(const Wt::WEnvironment& env, Database::Database& db, LmsApplicationGroupContainer& appGroups);
static LmsApplication* instance();
// Session application data
std::shared_ptr<ImageResource> getImageResource() { return _imageResource; }
std::shared_ptr<AudioResource> getAudioResource() { return _audioResource; }
Database::Handler& getDb() { return _db;}
Wt::Dbo::Session& getDboSession() { return _db.getSession();}
Database::Session& getDbSession() { return *_dbSession.get();}
const Wt::Auth::User& getAuthUser() { return _db.getLogin().user(); }
Database::User::pointer getUser() { return _db.getCurrentUser(); }
const Wt::Auth::User& getAuthUser() { return getDbSession().getLogin().user(); }
Wt::Dbo::ptr<Database::User> getUser() { return getDbSession().getLoggedUser(); }
Wt::WString getUserIdentity() { return _userIdentity; }
Events& getEvents() { return _events; }
@@ -118,15 +116,15 @@ class LmsApplication : public Wt::WApplication
void createHome();
Wt::Signal<> _preQuit;
Database::Handler _db;
LmsApplicationGroupContainer& _appGroups;
Events _events;
Wt::WString _userIdentity;
Auth* _auth = nullptr;
std::shared_ptr<ImageResource> _imageResource;
std::shared_ptr<AudioResource> _audioResource;
bool _isAdmin = false;
Wt::Signal<> _preQuit;
std::unique_ptr<Database::Session> _dbSession;
LmsApplicationGroupContainer& _appGroups;
Events _events;
Wt::WString _userIdentity;
Auth* _auth {};
std::shared_ptr<ImageResource> _imageResource;
std::shared_ptr<AudioResource> _audioResource;
bool _isAdmin {};
};
+3 -3
View File
@@ -59,12 +59,12 @@ MediaPlayer::loadTrack(Database::IdType trackId, bool play)
{
LMS_LOG(UI, DEBUG) << "Playing track ID = " << trackId;
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
auto track = Database::Track::getById(LmsApp->getDboSession(), trackId);
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
const auto track {Database::Track::getById(LmsApp->getDbSession(), trackId)};
try
{
Av::MediaFile mediaFile(track->getPath());
const Av::MediaFile mediaFile {track->getPath()};
auto resource = LmsApp->getAudioResource()->getUrl(trackId);
auto imgResource = LmsApp->getImageResource()->getTrackUrl(trackId, 64);
+12 -8
View File
@@ -70,7 +70,7 @@ std::unique_ptr<Wt::WTemplate> createEntry(Database::Track::pointer track)
namespace UserInterface {
PlayHistory::PlayHistory()
: Wt::WTemplate(Wt::WString::tr("Lms.PlayHistory.template"))
: Wt::WTemplate {Wt::WString::tr("Lms.PlayHistory.template")}
{
addFunction("tr", &Wt::WTemplate::Functions::tr);
@@ -86,10 +86,14 @@ PlayHistory::PlayHistory()
LmsApp->getEvents().trackLoaded.connect([=](Database::IdType trackId, bool /* play */)
{
Wt::Dbo::Transaction transaction (LmsApp->getDboSession());
auto transaction {LmsApp->getDbSession().createUniqueTransaction()};
auto trackEntry = LmsApp->getUser()->getPlayedTrackList().modify()->add(trackId);
_entriesContainer->insertWidget(0, createEntry(trackEntry->getTrack()));
Database::Track::pointer track {Database::Track::getById(LmsApp->getDbSession(), trackId)};
if (track)
{
Database::TrackListEntry::create(LmsApp->getDbSession(), track, LmsApp->getUser()->getPlayedTrackList(LmsApp->getDbSession()));
_entriesContainer->insertWidget(0, createEntry(track));
}
});
addSome();
@@ -98,11 +102,11 @@ PlayHistory::PlayHistory()
void
PlayHistory::addSome()
{
Wt::Dbo::Transaction transaction (LmsApp->getDboSession());
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
auto trackList = LmsApp->getUser()->getPlayedTrackList();
auto trackEntries = trackList->getEntriesReverse(_entriesContainer->count(), 50);
for (auto trackEntry : trackEntries)
const Database::TrackList::pointer trackList {LmsApp->getUser()->getPlayedTrackList(LmsApp->getDbSession())};
auto trackEntries {trackList->getEntriesReverse(_entriesContainer->count(), 50)};
for (const auto& trackEntry : trackEntries)
_entriesContainer->addWidget(createEntry(trackEntry->getTrack()));
_showMore->setHidden(static_cast<std::size_t>(_entriesContainer->count()) >= trackList->getCount());
-2
View File
@@ -23,8 +23,6 @@
#include <Wt/WPushButton.h>
#include <Wt/WTemplate.h>
#include "database/Types.hpp"
namespace UserInterface {
class PlayHistory : public Wt::WTemplate
+85 -80
View File
@@ -19,12 +19,15 @@
#include "PlayQueueView.hpp"
#include <Wt/WText.h>
#include <Wt/WText.h>
#include "database/Track.hpp"
#include "database/TrackList.hpp"
#include "main/Service.hpp"
#include "similarity/SimilaritySearcher.hpp"
#include "utils/Logger.hpp"
#include "utils/Utils.hpp"
#include "LmsApplication.hpp"
namespace UserInterface {
@@ -35,7 +38,7 @@ PlayQueue::PlayQueue()
addFunction("tr", &Wt::WTemplate::Functions::tr);
{
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
_repeatAll = LmsApp->getUser()->isRepeatAllSet();
_radioMode = LmsApp->getUser()->isRadioSet();
}
@@ -62,9 +65,15 @@ PlayQueue::PlayQueue()
shuffleBtn->clicked().connect([=]
{
{
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
auto transaction {LmsApp->getDbSession().createUniqueTransaction()};
getTrackList().modify()->shuffle();
Database::TrackList::pointer trackList {getTrackList()};
auto entries {trackList->getEntries()};
shuffleContainer(entries);
getTrackList().modify()->clear();
for (const auto& entry : entries)
Database::TrackListEntry::create(LmsApp->getDbSession(), entry->getTrack(), trackList);
}
_entriesContainer->clear();
addSome();
@@ -77,7 +86,7 @@ PlayQueue::PlayQueue()
_repeatAll = !_repeatAll;
updateRepeatBtn();
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
auto transaction {LmsApp->getDbSession().createUniqueTransaction()};
if (!LmsApp->getUser()->isDemo())
LmsApp->getUser().modify()->setRepeatAll(_repeatAll);
@@ -91,7 +100,7 @@ PlayQueue::PlayQueue()
_radioMode = !_radioMode;
updateRadioBtn();
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
auto transaction {LmsApp->getDbSession().createUniqueTransaction()};
if (!LmsApp->getUser()->isDemo())
LmsApp->getUser().modify()->setRadio(_radioMode);
@@ -102,23 +111,21 @@ PlayQueue::PlayQueue()
LmsApp->preQuit().connect([=]
{
if (_tracklistId)
auto transaction {LmsApp->getDbSession().createUniqueTransaction()};
if (LmsApp->getUser()->isDemo())
{
LMS_LOG(UI, DEBUG) << "Removing tracklist id " << *_tracklistId;
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
auto tracklist = Database::TrackList::getById(LmsApp->getDboSession(), *_tracklistId);
LMS_LOG(UI, DEBUG) << "Removing tracklist id " << _tracklistId;
auto tracklist = Database::TrackList::getById(LmsApp->getDbSession(), _tracklistId);
if (tracklist)
tracklist.remove();
}
});
updateInfo();
addSome();
{
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
auto transaction {LmsApp->getDbSession().createUniqueTransaction()};
Database::TrackList::pointer trackList;
if (!LmsApp->getUser()->isDemo())
{
@@ -126,8 +133,19 @@ PlayQueue::PlayQueue()
{
load(LmsApp->getUser()->getCurPlayingTrackPos(), false);
});
trackList = LmsApp->getUser()->getQueuedTrackList(LmsApp->getDbSession());
}
else
{
static const std::string currentPlayQueueName {"__current__playqueue__"};
trackList = Database::TrackList::create(LmsApp->getDbSession(), currentPlayQueueName, Database::TrackList::Type::Internal, false, LmsApp->getUser());
}
_tracklistId = trackList.id();
}
updateInfo();
addSome();
}
void
@@ -145,32 +163,17 @@ PlayQueue::updateRadioBtn()
Database::TrackList::pointer
PlayQueue::getTrackList()
{
Database::TrackList::pointer res;
if (LmsApp->getUser()->isDemo())
{
static const std::string currentPlayQueueName = "__current__playqueue__";
if (!_tracklistId)
{
res = Database::TrackList::create(LmsApp->getDboSession(), currentPlayQueueName, Database::TrackList::Type::Internal, false, LmsApp->getUser());
LmsApp->getDboSession().flush();
_tracklistId = res.id();
return res;
}
return Database::TrackList::getById(LmsApp->getDboSession(), *_tracklistId);
}
return LmsApp->getUser()->getQueuedTrackList();
return Database::TrackList::getById(LmsApp->getDbSession(), _tracklistId);
}
void
PlayQueue::clearTracks()
{
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
{
auto transaction {LmsApp->getDbSession().createUniqueTransaction()};
getTrackList().modify()->clear();
}
getTrackList().modify()->clear();
_showMore->setHidden(true);
_entriesContainer->clear();
updateInfo();
@@ -189,11 +192,12 @@ PlayQueue::load(std::size_t pos, bool play)
{
updateCurrentTrack(false);
Database::IdType trackId;
Database::IdType trackId {};
bool addRadioTrack {};
{
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
auto tracklist = getTrackList();
Database::TrackList::pointer tracklist {getTrackList()};
// If out of range, stop playing
if (pos >= tracklist->getCount())
@@ -209,19 +213,22 @@ PlayQueue::load(std::size_t pos, bool play)
// If last and radio mode, fill the next song
if (_radioMode && pos == tracklist->getCount() - 1)
addRadioTrack();
addRadioTrack = true;
_trackPos = pos;
auto track = tracklist->getEntry(*_trackPos)->getTrack();
trackId = track.id();
updateCurrentTrack(true);
if (!LmsApp->getUser()->isDemo())
LmsApp->getUser().modify()->setCurPlayingTrackPos(pos);
}
if (addRadioTrack)
enqueueRadioTrack();
updateCurrentTrack(true);
loadTrack.emit(trackId, play);
}
@@ -252,7 +259,7 @@ PlayQueue::playNext()
void
PlayQueue::updateInfo()
{
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
_nbTracks->setText(Wt::WString::tr("Lms.PlayQueue.nb-tracks").arg(static_cast<unsigned>(getTrackList()->getCount())));
}
@@ -274,55 +281,58 @@ PlayQueue::updateCurrentTrack(bool selected)
}
void
PlayQueue::enqueueTracks(const std::vector<Database::Track::pointer>& tracks)
PlayQueue::enqueueTracks(const std::vector<Database::IdType>& trackIds)
{
// Use a "session" playqueue in order to store the current playqueue
// so that the user can disconnect and get its playqueue back
{
auto transaction {LmsApp->getDbSession().createUniqueTransaction()};
auto tracklist = getTrackList();
auto tracklist = getTrackList();
for (Database::IdType trackId : trackIds)
{
Database::Track::pointer track {Database::Track::getById(LmsApp->getDbSession(), trackId)};
if (!track)
continue;
for (auto track : tracks)
Database::TrackListEntry::create(LmsApp->getDboSession(), track, tracklist);
Database::TrackListEntry::create(LmsApp->getDbSession(), track, tracklist);
}
}
updateInfo();
addSome();
}
void
PlayQueue::enqueueTrack(Database::Track::pointer track)
PlayQueue::enqueueTrack(Database::IdType trackId)
{
enqueueTracks(std::vector<Database::Track::pointer>(1, track));
enqueueTracks({trackId});
}
void
PlayQueue::addTracks(const std::vector<Database::Track::pointer>& tracks)
PlayQueue::addTracks(const std::vector<Database::IdType>& trackIds)
{
enqueueTracks(tracks);
LmsApp->notifyMsg(MsgType::Info, Wt::WString::trn("Lms.PlayQueue.nb-tracks-added", tracks.size()).arg(tracks.size()), std::chrono::milliseconds(2000));
enqueueTracks(trackIds);
LmsApp->notifyMsg(MsgType::Info, Wt::WString::trn("Lms.PlayQueue.nb-tracks-added", trackIds.size()).arg(trackIds.size()), std::chrono::milliseconds(2000));
}
void
PlayQueue::playTracks(const std::vector<Database::Track::pointer>& tracks)
PlayQueue::playTracks(const std::vector<Database::IdType>& trackIds)
{
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
clearTracks();
enqueueTracks(tracks);
enqueueTracks(trackIds);
load(0, true);
LmsApp->notifyMsg(MsgType::Info, Wt::WString::trn("Lms.PlayQueue.nb-tracks-playing", tracks.size()).arg(tracks.size()), std::chrono::milliseconds(2000));
LmsApp->notifyMsg(MsgType::Info, Wt::WString::trn("Lms.PlayQueue.nb-tracks-playing", trackIds.size()).arg(trackIds.size()), std::chrono::milliseconds(2000));
}
void
PlayQueue::addSome()
{
Wt::Dbo::Transaction transaction (LmsApp->getDboSession());
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
auto tracklist = getTrackList();
auto tracklistEntries = tracklist->getEntries(_entriesContainer->count(), 50);
for (auto tracklistEntry : tracklistEntries)
for (const Database::TrackListEntry::pointer& tracklistEntry : tracklistEntries)
{
auto tracklistEntryId = tracklistEntry.id();
auto track = tracklistEntry->getTrack();
@@ -367,15 +377,15 @@ PlayQueue::addSome()
{
// Remove the entry n both the widget tree and the playqueue
{
Wt::Dbo::Transaction transaction (LmsApp->getDboSession());
auto transaction {LmsApp->getDbSession().createUniqueTransaction()};
auto entryToRemove = Database::TrackListEntry::getById(LmsApp->getDboSession(), tracklistEntryId);
Database::TrackListEntry::pointer entryToRemove {Database::TrackListEntry::getById(LmsApp->getDbSession(), tracklistEntryId)};
entryToRemove.remove();
}
if (_trackPos)
{
auto pos = _entriesContainer->indexOf(entry);
auto pos {_entriesContainer->indexOf(entry)};
if (pos > 0 && *_trackPos >= static_cast<std::size_t>(pos))
(*_trackPos)--;
}
@@ -391,28 +401,23 @@ PlayQueue::addSome()
}
void
PlayQueue::addRadioTrack()
PlayQueue::enqueueRadioTrack()
{
auto tracklist = getTrackList();
std::vector<Database::IdType> trackIds;
{
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
Database::TrackList::pointer tracklist {getTrackList()};
trackIds = getTrackList()->getTrackIds();
}
std::vector<Database::IdType> trackIds = getTrackList()->getTrackIds();
if (trackIds.empty())
return;
auto res = getService<Similarity::Searcher>()->getSimilarTracks(LmsApp->getDboSession(), std::set<Database::IdType>(trackIds.begin(), trackIds.end()), 1);
for (auto trackId : res)
{
auto trackToAdd = Database::Track::getById(LmsApp->getDboSession(), trackId);
enqueueTrack(trackToAdd);
}
const std::vector<Database::IdType> trackToAddIds {getService<Similarity::Searcher>()->getSimilarTracks(LmsApp->getDbSession(), std::set<Database::IdType>(std::cbegin(trackIds), std::cend(trackIds)), 1)};
enqueueTracks(trackToAddIds);
}
void addRadioTrackFromSimilarity(std::shared_ptr<Similarity::Searcher> similaritySearcher)
{
}
} // namespace UserInterface
+20 -20
View File
@@ -19,23 +19,23 @@
#pragma once
#include <Wt/WCheckBox.h>
#include <Wt/WContainerWidget.h>
#include <Wt/WPushButton.h>
#include <Wt/WSignal.h>
#include <Wt/WTemplate.h>
#include <Wt/WText.h>
#include <boost/optional.hpp>
#include "database/TrackList.hpp"
#include "database/Track.hpp"
#include "database/Types.hpp"
namespace Similarity
{
namespace Similarity {
class Finder;
}
namespace Database {
class TrackList;
}
namespace UserInterface {
class PlayQueue : public Wt::WTemplate
@@ -43,8 +43,8 @@ class PlayQueue : public Wt::WTemplate
public:
PlayQueue();
void addTracks(const std::vector<Database::Track::pointer>& tracks);
void playTracks(const std::vector<Database::Track::pointer>& tracks);
void addTracks(const std::vector<Database::IdType>& trackIds);
void playTracks(const std::vector<Database::IdType>& trackIds);
// play the next track in the queue
void playNext();
@@ -59,13 +59,13 @@ class PlayQueue : public Wt::WTemplate
Wt::Signal<> trackUnload;
private:
Database::TrackList::pointer getTrackList();
Wt::Dbo::ptr<Database::TrackList> getTrackList();
void clearTracks();
void enqueueTracks(const std::vector<Database::Track::pointer>& tracks);
void enqueueTrack(Database::Track::pointer track);
void enqueueTracks(const std::vector<Database::IdType>& trackIds);
void enqueueTrack(Database::IdType trackId);
void addSome();
void addRadioTrack();
void enqueueRadioTrack();
void updateInfo();
void updateCurrentTrack(bool selected);
void updateRepeatBtn();
@@ -77,14 +77,14 @@ class PlayQueue : public Wt::WTemplate
void addRadioTrackFromSimilarity(std::shared_ptr<Similarity::Finder> similarityFinder);
void addRadioTrackFromClusters();
bool _repeatAll = false;
bool _radioMode = false;
boost::optional<Database::IdType> _tracklistId;
Wt::WContainerWidget* _entriesContainer = nullptr;
Wt::WPushButton* _showMore = nullptr;
Wt::WText* _nbTracks = nullptr;
Wt::WText* _repeatBtn = nullptr;
Wt::WText* _radioBtn = nullptr;
bool _repeatAll {};
bool _radioMode {};
Database::IdType _tracklistId {};
Wt::WContainerWidget* _entriesContainer {};
Wt::WPushButton* _showMore {};
Wt::WText* _nbTracks {};
Wt::WText* _repeatBtn {};
Wt::WText* _radioBtn {};
boost::optional<std::size_t> _trackPos; // current track position, if set
};
+7 -7
View File
@@ -69,7 +69,7 @@ class SettingsModel : public Wt::WFormModel
void saveData()
{
Wt::Dbo::Transaction transaction {LmsApp->getDboSession()};
auto transaction {LmsApp->getDbSession().createUniqueTransaction()};
LmsApp->getUser().modify()->setAudioTranscodeEnable(Wt::asNumber(value(TranscodeEnableField)));
@@ -82,12 +82,12 @@ class SettingsModel : public Wt::WFormModel
LmsApp->getUser().modify()->setAudioTranscodeFormat(_transcodeFormatModel->getValue(*transcodeFormatRow));
if (!valueText(PasswordField).empty())
Handler::getPasswordService().updatePassword(LmsApp->getAuthUser(), valueText(PasswordField));
Session::getPasswordService().updatePassword(LmsApp->getAuthUser(), valueText(PasswordField));
}
void loadData()
{
Wt::Dbo::Transaction transaction {LmsApp->getDboSession()};
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
setValue(TranscodeEnableField, LmsApp->getUser()->getAudioTranscodeEnable());
if (!LmsApp->getUser()->getAudioTranscodeEnable())
@@ -116,7 +116,7 @@ class SettingsModel : public Wt::WFormModel
if (!valueText(PasswordField).empty())
{
// Evaluate the strength of the password
auto res = Handler::getPasswordService().strengthValidator()->evaluateStrength(valueText(PasswordField), LmsApp->getUserIdentity(), "");
auto res = Session::getPasswordService().strengthValidator()->evaluateStrength(valueText(PasswordField), LmsApp->getUserIdentity(), "");
if (!res.isValid())
error = res.message();
@@ -148,12 +148,12 @@ class SettingsModel : public Wt::WFormModel
{
Bitrate maxAudioBitrate;
{
Wt::Dbo::Transaction transaction {LmsApp->getDboSession()};
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
maxAudioBitrate = LmsApp->getUser()->getMaxAudioTranscodeBitrate();
}
_transcodeBitrateModel = std::make_shared<ValueStringModel<Bitrate>>();
for (Bitrate bitrate : User::audioTranscodeAllowedBitrates)
for (const Bitrate bitrate : User::audioTranscodeAllowedBitrates)
{
if (bitrate > maxAudioBitrate)
break;
@@ -243,7 +243,7 @@ SettingsView::refreshView()
{
{
Wt::Dbo::Transaction transaction {LmsApp->getDboSession()};
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
if (LmsApp->getUser()->isDemo())
{
+8 -8
View File
@@ -85,10 +85,10 @@ class DatabaseSettingsModel : public Wt::WFormModel
void loadData()
{
Wt::Dbo::Transaction transaction {LmsApp->getDboSession()};
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
auto scanSettings {ScanSettings::get(LmsApp->getDboSession())};
auto similaritySettings {SimilaritySettings::get(LmsApp->getDboSession())};
const ScanSettings::pointer scanSettings {ScanSettings::get(LmsApp->getDbSession())};
const SimilaritySettings::pointer similaritySettings {SimilaritySettings::get(LmsApp->getDbSession())};
setValue(MediaDirectoryField, scanSettings->getMediaDirectory().string());
@@ -108,17 +108,17 @@ class DatabaseSettingsModel : public Wt::WFormModel
if (!clusterTypes.empty())
{
std::vector<std::string> names;
std::transform(clusterTypes.begin(), clusterTypes.end(),std::back_inserter(names), [](auto clusterType) { return clusterType->getName(); });
std::transform(clusterTypes.begin(), clusterTypes.end(), std::back_inserter(names), [](auto clusterType) { return clusterType->getName(); });
setValue(TagsField, joinStrings(names, " "));
}
}
void saveData()
{
Wt::Dbo::Transaction transaction {LmsApp->getDboSession()};
auto transaction {LmsApp->getDbSession().createUniqueTransaction()};
auto scanSettings {ScanSettings::get(LmsApp->getDboSession())};
auto similaritySettings {SimilaritySettings::get(LmsApp->getDboSession())};
ScanSettings::pointer scanSettings {ScanSettings::get(LmsApp->getDbSession())};
SimilaritySettings::pointer similaritySettings {SimilaritySettings::get(LmsApp->getDbSession())};
scanSettings.modify()->setMediaDirectory(valueText(MediaDirectoryField).toUTF8());
@@ -135,7 +135,7 @@ class DatabaseSettingsModel : public Wt::WFormModel
similaritySettings.modify()->setEngineType(_similarityEngineTypeModel->getValue(*similarityEngineTypeRow));
auto clusterTypes {splitString(valueText(TagsField).toUTF8(), " ")};
scanSettings.modify()->setClusterTypes(std::set<std::string>(clusterTypes.begin(), clusterTypes.end()));
scanSettings.modify()->setClusterTypes(LmsApp->getDbSession(), std::set<std::string>(clusterTypes.begin(), clusterTypes.end()));
}
private:
+4 -11
View File
@@ -54,21 +54,14 @@ class InitWizardModel : public Wt::WFormModel
void saveData()
{
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
auto transaction(LmsApp->getDbSession().createUniqueTransaction());
// Check if a user already exist
// If it's the case, just do nothing
if (!Database::User::getAll(LmsApp->getDboSession()).empty())
if (!Database::User::getAll(LmsApp->getDbSession()).empty())
throw LmsException("Admin user already created");
// Create user
Wt::Auth::User authUser = LmsApp->getDb().getUserDatabase().registerNew();
Database::User::pointer user = LmsApp->getDb().createUser(authUser);
// Account
authUser.setIdentity(Wt::Auth::Identity::LoginName, valueText(AdminLoginField));
Database::Handler::getPasswordService().updatePassword(authUser, valueText(PasswordField));
Database::User::pointer user {LmsApp->getDbSession().createUser(valueText(AdminLoginField).toUTF8(), valueText(PasswordField).toUTF8())};
user.modify()->setType(Database::User::Type::ADMIN);
}
@@ -81,7 +74,7 @@ class InitWizardModel : public Wt::WFormModel
if (!valueText(PasswordField).empty())
{
// Evaluate the strength of the password
auto res = Database::Handler::getPasswordService().strengthValidator()->evaluateStrength(valueText(PasswordField),
auto res = Database::Session::getPasswordService().strengthValidator()->evaluateStrength(valueText(PasswordField),
valueText(AdminLoginField), "");
if (!res.isValid())
+26 -32
View File
@@ -78,17 +78,16 @@ class UserModel : public Wt::WFormModel
void saveData()
{
Wt::Dbo::Transaction transaction {LmsApp->getDboSession()};
auto transaction {LmsApp->getDbSession().createUniqueTransaction()};
if (_userId)
{
// Update user
Wt::Auth::User authUser = LmsApp->getDb().getUserDatabase().findWithId( std::to_string(*_userId) );
Database::User::pointer user = LmsApp->getDb().getUser( authUser );
Database::User::pointer user {Database::User::getById(LmsApp->getDbSession(), *_userId)};
// Account
if (!valueText(PasswordField).empty())
Database::Handler::getPasswordService().updatePassword(authUser, valueText(PasswordField));
LmsApp->getDbSession().updateUserPassword(user, valueText(PasswordField).toUTF8());
auto transcodeBitrateLimitRow {_bitrateModel->getRowFromString(valueText(AudioTranscodeBitrateLimitField))};
if (transcodeBitrateLimitRow)
@@ -97,12 +96,7 @@ class UserModel : public Wt::WFormModel
else
{
// Create user
Wt::Auth::User authUser = LmsApp->getDb().getUserDatabase().registerNew();
Database::User::pointer user = LmsApp->getDb().createUser(authUser);
// Account
authUser.setIdentity(Wt::Auth::Identity::LoginName, valueText(LoginField));
Database::Handler::getPasswordService().updatePassword(authUser, valueText(PasswordField));
Database::User::pointer user = LmsApp->getDbSession().createUser(valueText(LoginField).toUTF8(), valueText(PasswordField).toUTF8());
auto transcodeBitrateLimitRow {_bitrateModel->getRowFromString(valueText(AudioTranscodeBitrateLimitField))};
if (transcodeBitrateLimitRow )
@@ -120,11 +114,9 @@ class UserModel : public Wt::WFormModel
if (!_userId)
return;
Wt::Dbo::Transaction transaction {LmsApp->getDboSession()};
auto authUser {LmsApp->getDb().getUserDatabase().findWithId( std::to_string(*_userId) )};
auto user {LmsApp->getDb().getUser(authUser)};
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");
@@ -133,12 +125,14 @@ class UserModel : public Wt::WFormModel
setValue(AudioTranscodeBitrateLimitField, _bitrateModel->getString(*transcodeBitrateLimitRow));
}
Wt::WString getLogin() const
Wt::WString getLoginName() const
{
if (_userId)
{
auto authUser = LmsApp->getDb().getUserDatabase().findWithId( std::to_string(*_userId) );
return authUser.identity(Wt::Auth::Identity::LoginName);
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
const Database::User::pointer user {Database::User::getById(LmsApp->getDbSession(), *_userId)};
return LmsApp->getDbSession().getUserLoginName(user);
}
else
return valueText(LoginField);
@@ -150,8 +144,8 @@ class UserModel : public Wt::WFormModel
if (field == LoginField)
{
auto user = LmsApp->getDb().getUserDatabase().findWithIdentity(Wt::Auth::Identity::LoginName, valueText(LoginField));
if (user.isValid())
const Database::User::pointer user {LmsApp->getDbSession().getUser(valueText(LoginField).toUTF8())};
if (user)
error = Wt::WString::tr("Lms.Admin.User.user-already-exists");
}
else if (field == PasswordField)
@@ -161,13 +155,13 @@ class UserModel : public Wt::WFormModel
if (Wt::asNumber(value(DemoField)))
{
//Demo account: password must be the same as the login name
if (valueText(PasswordField) != getLogin())
if (valueText(PasswordField) != getLoginName())
error = Wt::WString::tr("Lms.Admin.User.demo-password-invalid");
}
else
{
// Evaluate the strength of the password for non demo accounts
auto res = Database::Handler::getPasswordService().strengthValidator()->evaluateStrength(valueText(PasswordField), getLogin(), "");
auto res = Database::Session::getPasswordService().strengthValidator()->evaluateStrength(valueText(PasswordField), getLoginName(), "");
if (!res.isValid())
error = res.message();
@@ -176,9 +170,9 @@ class UserModel : public Wt::WFormModel
}
else if (field == DemoField)
{
Wt::Dbo::Transaction transaction {LmsApp->getDboSession()};
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
if (Wt::asNumber(value(DemoField)) && Database::User::getDemo(LmsApp->getDboSession()))
if (Wt::asNumber(value(DemoField)) && Database::User::getDemo(LmsApp->getDbSession()))
error = Wt::WString::tr("Lms.Admin.User.demo-account-already-exists");
}
@@ -226,23 +220,23 @@ UserView::refreshView()
auto userId = readAs<Database::IdType>(wApp->internalPathNextPart("/admin/user/"));
LMS_LOG(UI, DEBUG) << "userId = " << (userId ? std::to_string(*userId) : "none");
clear();
Wt::WTemplateFormView* t = addNew<Wt::WTemplateFormView>(Wt::WString::tr("Lms.Admin.User.template"));
Wt::WTemplateFormView* t {addNew<Wt::WTemplateFormView>(Wt::WString::tr("Lms.Admin.User.template"))};
auto model = std::make_shared<UserModel>(userId);
auto model {std::make_shared<UserModel>(userId)};
if (userId)
{
auto authUser = LmsApp->getDb().getUserDatabase().findWithId( std::to_string(*userId) );
auto name = authUser.identity(Wt::Auth::Identity::LoginName);
t->bindString("title", Wt::WString::tr("Lms.Admin.User.user-edit").arg(name), Wt::TextFormat::Plain);
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
const Database::User::pointer user {Database::User::getById(LmsApp->getDbSession(), *userId)};
const std::string loginName {LmsApp->getDbSession().getUserLoginName(user)};
t->bindString("title", Wt::WString::tr("Lms.Admin.User.user-edit").arg(loginName), Wt::TextFormat::Plain);
t->setCondition("if-has-last-login-attempt", true);
Wt::WLineEdit *lastLoginAttempt = t->bindNew<Wt::WLineEdit>("last-login-attempt");
lastLoginAttempt->setText(authUser.lastLoginAttempt().toString());
Wt::WLineEdit *lastLoginAttempt {t->bindNew<Wt::WLineEdit>("last-login-attempt")};
lastLoginAttempt->setText(LmsApp->getDbSession().getUserLastLoginAttempt(user).toString());
lastLoginAttempt->setEnabled(false);
}
else
+13 -17
View File
@@ -59,22 +59,16 @@ UsersView::refreshView()
_container->clear();
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
auto users = Database::User::getAll(LmsApp->getDboSession());
for (auto user : users)
auto users = Database::User::getAll(LmsApp->getDbSession());
for (const auto& user : users)
{
auto userId = std::to_string(user.id());
Wt::WTemplate* entry = _container->addNew<Wt::WTemplate>(Wt::WString::tr("Lms.Admin.Users.template.entry"));
const Database::IdType userId {user.id()};
Wt::Auth::User authUser = LmsApp->getDb().getUserDatabase().findWithId(userId);
if (!authUser.isValid()) {
LMS_LOG(UI, ERROR) << "Skipping invalid userId = " << user.id();
continue;
}
Wt::WTemplate* entry {_container->addNew<Wt::WTemplate>(Wt::WString::tr("Lms.Admin.Users.template.entry"))};
auto login = authUser.identity(Wt::Auth::Identity::LoginName);
entry->bindString("name", login, Wt::TextFormat::Plain);
entry->bindString("name", LmsApp->getDbSession().getUserLoginName(user), Wt::TextFormat::Plain);
// Create tag
if (user->isAdmin() || user->isDemo())
@@ -106,16 +100,18 @@ UsersView::refreshView()
{
if (btn == Wt::StandardButton::Yes)
{
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
auto transaction {LmsApp->getDbSession().createUniqueTransaction()};
Database::User::pointer user {Database::User::getById(LmsApp->getDbSession(), userId)};
if (user)
LmsApp->getDbSession().removeUser(user);
auto authUser = LmsApp->getDb().getUserDatabase().findWithId(userId);
auto user = LmsApp->getDb().getUser(authUser);
LmsApp->getDb().getUserDatabase().deleteUser( authUser );
user.remove();
_container->removeWidget(entry);
}
else
{
delBtn->removeChild(msgBox);
}
});
msgBox->show();
+7 -10
View File
@@ -63,21 +63,18 @@ ArtistInfo::refresh()
if (!artistId)
return;
auto artistsIds = getService<Similarity::Searcher>()->getSimilarArtists(LmsApp->getDboSession(), *artistId, 5);
const std::vector<Database::IdType> artistsIds {getService<Similarity::Searcher>()->getSimilarArtists(LmsApp->getDbSession(), *artistId, 5)};
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
std::vector<Database::Artist::pointer> artists;
for (auto artistId : artistsIds)
for (Database::IdType artistId : artistsIds)
{
auto artist = Database::Artist::getById(LmsApp->getDboSession(), artistId);
Database::Artist::pointer artist {Database::Artist::getById(LmsApp->getDbSession(), artistId)};
if (!artist)
continue;
if (artist)
artists.push_back(artist);
}
for (auto artist : artists)
_similarArtistsContainer->addNew<ArtistLink>(artist);
}
}
} // namespace UserInterface
+4 -4
View File
@@ -66,22 +66,22 @@ Artist::refresh()
if (!artistId)
return;
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
auto artist = Database::Artist::getById(LmsApp->getDboSession(), *artistId);
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
const Database::Artist::pointer artist = Database::Artist::getById(LmsApp->getDbSession(), *artistId);
if (!artist)
{
LmsApp->goHome();
return;
}
Wt::WTemplate* t = addNew<Wt::WTemplate>(Wt::WString::tr("Lms.Explore.Artist.template"));
Wt::WTemplate* t {addNew<Wt::WTemplate>(Wt::WString::tr("Lms.Explore.Artist.template"))};
t->addFunction("tr", &Wt::WTemplate::Functions::tr);
Wt::WContainerWidget* clusterContainers = t->bindNew<Wt::WContainerWidget>("clusters");
{
auto clusterTypes = ScanSettings::get(LmsApp->getDboSession())->getClusterTypes();
auto clusterTypes = ScanSettings::get(LmsApp->getDbSession())->getClusterTypes();
auto clusterGroups = artist->getClusterGroups(clusterTypes, 3);
for (auto clusters : clusterGroups)
+7 -6
View File
@@ -58,22 +58,23 @@ ArtistsInfo::refreshRecentlyAdded()
{
auto after = Wt::WLocalDateTime::currentServerDateTime().toUTC().addMonths(-1);
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
auto artists = Artist::getLastAdded(LmsApp->getDboSession(), after, 5);
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
const std::vector<Database::Artist::pointer> artists {Artist::getLastAdded(LmsApp->getDbSession(), after, 5)};
_recentlyAddedContainer->clear();
for (auto artist : artists)
for (const Database::Artist::pointer& artist : artists)
_recentlyAddedContainer->addNew<ArtistLink>(artist);
}
void
ArtistsInfo::refreshMostPlayed()
{
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
auto artists = LmsApp->getUser()->getPlayedTrackList()->getTopArtists(5);
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
const std::vector<Database::Artist::pointer> artists {LmsApp->getUser()->getPlayedTrackList(LmsApp->getDbSession())->getTopArtists(5)};
_mostPlayedContainer->clear();
for (auto artist : artists)
for (const Database::Artist::pointer& artist : artists)
_mostPlayedContainer->addNew<ArtistLink>(artist);
}
+6 -6
View File
@@ -73,17 +73,17 @@ Artists::addSome()
auto clusterIds = _filters->getClusterIds();
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
bool moreResults;
auto artists = Artist::getByFilter(LmsApp->getDboSession(),
bool moreResults {};
const std::vector<Artist::pointer> artists {Artist::getByFilter(LmsApp->getDbSession(),
clusterIds,
searchKeywords,
_container->count(), 20, moreResults);
_container->count(), 20, moreResults)};
for (auto artist : artists)
for (const auto& artist : artists)
{
Wt::WTemplate* entry = _container->addNew<Wt::WTemplate>(Wt::WString::tr("Lms.Explore.Artists.template.entry"));
Wt::WTemplate* entry {_container->addNew<Wt::WTemplate>(Wt::WString::tr("Lms.Explore.Artists.template.entry"))};
entry->bindWidget("name", LmsApplication::createArtistAnchor(artist));
}
+43 -42
View File
@@ -25,6 +25,7 @@
#include "database/Artist.hpp"
#include "database/Release.hpp"
#include "database/Track.hpp"
#include "utils/Logger.hpp"
#include "LmsApplication.hpp"
@@ -66,9 +67,7 @@ handleContentsPathChange(Wt::WStackedWidget* stack)
{ "/tracks", IdxTracks },
};
LMS_LOG(UI, DEBUG) << "Internal path changed to '" << wApp->internalPath() << "'";
for (auto index : indexes)
for (const auto& index : indexes)
{
if (wApp->internalPathMatches(index.first))
{
@@ -182,102 +181,104 @@ Explore::Explore()
handleInfoPathChange(infoStack);
}
// TODO SQL this?
static std::vector<Database::Track::pointer> getArtistTracks(Wt::Dbo::Session& session, Database::IdType artistId, std::set<Database::IdType> clusters)
static
std::vector<Database::IdType>
getArtistTracks(Database::Session& session, Database::IdType artistId, const std::set<Database::IdType>& clusters)
{
std::vector<Database::Track::pointer> res;
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
auto artist = Database::Artist::getById(session, artistId);
Database::Artist::pointer artist {Database::Artist::getById(session, artistId)};
if (!artist)
return res;
return {};
res = artist->getTracks();
// TODO handle clusters here
const std::vector<Database::Track::pointer> tracks {artist->getTracks()};
std::vector<Database::IdType> res;
res.reserve(tracks.size());
std::transform(std::cbegin(tracks), std::cend(tracks), std::back_inserter(res), [](const Database::Track::pointer& track) { return track.id(); });
return res;
}
static std::vector<Database::Track::pointer> getReleaseTracks(Wt::Dbo::Session& session, Database::IdType releaseId, std::set<Database::IdType> clusters)
static
std::vector<Database::IdType>
getReleaseTracks(Database::Session& session, Database::IdType releaseId, std::set<Database::IdType> clusters)
{
std::vector<Database::Track::pointer> res;
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
auto release = Database::Release::getById(session, releaseId);
Database::Release::pointer release {Database::Release::getById(session, releaseId)};
if (!release)
return res;
return {};
res = release->getTracks(clusters);
const std::vector<Database::Track::pointer> tracks {release->getTracks(clusters)};
std::vector<Database::IdType> res;
res.reserve(tracks.size());
std::transform(std::cbegin(tracks), std::cend(tracks), std::back_inserter(res), [](const Database::Track::pointer& track) { return track.id(); });
return res;
}
static std::vector<Database::Track::pointer> getTrack(Wt::Dbo::Session& session, Database::IdType trackId)
static
std::vector<Database::IdType>
getTrack(Database::Session& session, Database::IdType trackId)
{
std::vector<Database::Track::pointer> res;
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
auto track = Database::Track::getById(session, trackId);
if (track)
res.push_back(track);
Database::Track::pointer track {Database::Track::getById(session, trackId)};
if (!track)
return {};
return res;
return {track.id()};
}
void
Explore::handleArtistAdd(Database::IdType id)
{
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
tracksAdd.emit(getArtistTracks(LmsApp->getDboSession(), id, _filters->getClusterIds()));
tracksAdd.emit(getArtistTracks(LmsApp->getDbSession(), id, _filters->getClusterIds()));
}
void
Explore::handleArtistPlay(Database::IdType id)
{
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
tracksPlay.emit(getArtistTracks(LmsApp->getDboSession(), id, _filters->getClusterIds()));
tracksPlay.emit(getArtistTracks(LmsApp->getDbSession(), id, _filters->getClusterIds()));
}
void
Explore::handleReleaseAdd(Database::IdType id)
{
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
tracksAdd.emit(getReleaseTracks(LmsApp->getDboSession(), id, _filters->getClusterIds()));
tracksAdd.emit(getReleaseTracks(LmsApp->getDbSession(), id, _filters->getClusterIds()));
}
void
Explore::handleReleasePlay(Database::IdType id)
{
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
tracksPlay.emit(getReleaseTracks(LmsApp->getDboSession(), id, _filters->getClusterIds()));
tracksPlay.emit(getReleaseTracks(LmsApp->getDbSession(), id, _filters->getClusterIds()));
}
void
Explore::handleTrackAdd(Database::IdType id)
{
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
tracksAdd.emit(getTrack(LmsApp->getDboSession(), id));
tracksAdd.emit(getTrack(LmsApp->getDbSession(), id));
}
void
Explore::handleTrackPlay(Database::IdType id)
{
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
tracksPlay.emit(getTrack(LmsApp->getDboSession(), id));
tracksPlay.emit(getTrack(LmsApp->getDbSession(), id));
}
void
Explore::handleTracksAdd(std::vector<Database::Track::pointer> tracks)
Explore::handleTracksAdd(const std::vector<Database::IdType>& trackIds)
{
tracksAdd.emit(tracks);
tracksAdd.emit(trackIds);
}
void
Explore::handleTracksPlay(std::vector<Database::Track::pointer> tracks)
Explore::handleTracksPlay(const std::vector<Database::IdType>& trackIds)
{
tracksPlay.emit(tracks);
tracksPlay.emit(trackIds);
}
} // namespace UserInterface
+10 -11
View File
@@ -21,7 +21,6 @@
#include <Wt/WTemplate.h>
#include "database/Track.hpp"
#include "database/Types.hpp"
namespace UserInterface {
@@ -33,19 +32,19 @@ class Explore : public Wt::WTemplate
public:
Explore();
Wt::Signal<std::vector<Database::Track::pointer>> tracksAdd;
Wt::Signal<std::vector<Database::Track::pointer>> tracksPlay;
Wt::Signal<std::vector<Database::IdType>> tracksAdd;
Wt::Signal<std::vector<Database::IdType>> tracksPlay;
private:
void handleArtistAdd(Database::IdType id);
void handleArtistPlay(Database::IdType id);
void handleReleaseAdd(Database::IdType id);
void handleReleasePlay(Database::IdType id);
void handleTrackAdd(Database::IdType id);
void handleTrackPlay(Database::IdType id);
void handleTracksAdd(std::vector<Database::Track::pointer> tracks);
void handleTracksPlay(std::vector<Database::Track::pointer> tracks);
void handleArtistAdd(Database::IdType artistId);
void handleArtistPlay(Database::IdType artistId);
void handleReleaseAdd(Database::IdType releaseId);
void handleReleasePlay(Database::IdType releaseId);
void handleTrackAdd(Database::IdType trackId);
void handleTrackPlay(Database::IdType trackId);
void handleTracksAdd(const std::vector<Database::IdType>& trackIds);
void handleTracksPlay(const std::vector<Database::IdType>& trackIds);
Filters* _filters;
};
+23 -25
View File
@@ -49,43 +49,41 @@ Filters::showDialog()
// Populate data
{
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
auto types = Database::ClusterType::getAll(LmsApp->getDboSession());
for (auto type : types)
const auto types {Database::ClusterType::getAll(LmsApp->getDbSession())};
for (const Database::ClusterType::pointer& type : types)
typeCombo->addItem(Wt::WString::fromUTF8(type->getName()));
if (!types.empty())
{
auto values = types.front()->getClusters();
const auto values {types.front()->getClusters()};
for (auto value : values)
for (const Database::Cluster::pointer& value : values)
{
if (_filterIds.find(value.id()) == _filterIds.end())
valueCombo->addItem(Wt::WString::fromUTF8(value->getName()));
}
}
}
typeCombo->changed().connect(std::bind([=]
typeCombo->changed().connect([=]
{
auto name = typeCombo->valueText().toUTF8();
const std::string name {typeCombo->valueText().toUTF8()};
valueCombo->clear();
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
auto clusterType = Database::ClusterType::getByName(LmsApp->getDboSession(), name);
auto clusterType = Database::ClusterType::getByName(LmsApp->getDbSession(), name);
auto values = clusterType->getClusters();
for (auto value : values)
const auto values = clusterType->getClusters();
for (const Database::Cluster::pointer& value : values)
{
if (_filterIds.find(value.id()) == _filterIds.end())
valueCombo->addItem(Wt::WString::fromUTF8(value->getName()));
}
}));
});
dialog->setModal(true);
dialog->setMovable(false);
@@ -93,26 +91,26 @@ Filters::showDialog()
dialog->setResizable(false);
dialog->setClosable(false);
dialog->finished().connect(std::bind([=]
dialog->finished().connect([=]
{
if (dialog->result() != Wt::DialogCode::Accepted)
return;
auto type = typeCombo->valueText().toUTF8();
auto value = valueCombo->valueText().toUTF8();
const std::string type {typeCombo->valueText().toUTF8()};
const std::string value {valueCombo->valueText().toUTF8()};
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
auto clusterType = Database::ClusterType::getByName(LmsApp->getDboSession(), type);
Database::ClusterType::pointer clusterType {Database::ClusterType::getByName(LmsApp->getDbSession(), type)};
if (!clusterType)
return;
auto cluster = clusterType->getCluster(value);
Database::Cluster::pointer cluster {clusterType->getCluster(value)};
if (!cluster)
return;
add(cluster.id());
}));
});
dialog->show();
}
@@ -120,17 +118,17 @@ Filters::showDialog()
void
Filters::add(Database::IdType clusterId)
{
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
auto cluster = Database::Cluster::getById(LmsApp->getDboSession(), clusterId);
Database::Cluster::pointer cluster {Database::Cluster::getById(LmsApp->getDbSession(), clusterId)};
if (!cluster)
return;
auto res = _filterIds.insert(clusterId);
auto res {_filterIds.insert(clusterId)};
if (!res.second)
return;
auto filter = _filters->addWidget(LmsApp->createCluster(cluster, true));
auto filter {_filters->addWidget(LmsApp->createCluster(cluster, true))};
filter->clicked().connect(std::bind([=]
{
_filters->removeWidget(filter);
+5 -5
View File
@@ -68,11 +68,11 @@ ReleaseInfo::refresh()
if (!releaseId)
return;
std::vector<Database::IdType> releasesIds {getService<Similarity::Searcher>()->getSimilarReleases(LmsApp->getDboSession(), *releaseId, 5)};
const std::vector<Database::IdType> releasesIds {getService<Similarity::Searcher>()->getSimilarReleases(LmsApp->getDbSession(), *releaseId, 5)};
Wt::Dbo::Transaction transaction {LmsApp->getDboSession()};
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
Database::Release::pointer release {Database::Release::getById(LmsApp->getDboSession(), *releaseId)};
Database::Release::pointer release {Database::Release::getById(LmsApp->getDbSession(), *releaseId)};
if (!release)
return;
@@ -102,13 +102,13 @@ ReleaseInfo::refresh()
std::vector<Database::Release::pointer> similarReleases;
for (Database::IdType id : releasesIds)
{
Database::Release::pointer similarRelease {Database::Release::getById(LmsApp->getDboSession(), id)};
Database::Release::pointer similarRelease {Database::Release::getById(LmsApp->getDbSession(), id)};
if (similarRelease)
similarReleases.emplace_back(similarRelease);
}
for (const auto& similarRelease : similarReleases)
for (const Database::Release::pointer& similarRelease : similarReleases)
_similarReleasesContainer->addNew<ReleaseLink>(similarRelease);
}
+6 -6
View File
@@ -67,9 +67,9 @@ Release::refresh()
if (!releaseId)
return;
Wt::Dbo::Transaction transaction {LmsApp->getDboSession()};
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
auto release {Database::Release::getById(LmsApp->getDboSession(), *releaseId)};
const Database::Release::pointer release {Database::Release::getById(LmsApp->getDbSession(), *releaseId)};
if (!release)
{
LmsApp->goHome();
@@ -118,12 +118,12 @@ Release::refresh()
Wt::WContainerWidget* clusterContainers {t->bindNew<Wt::WContainerWidget>("clusters")};
{
auto clusterTypes {ScanSettings::get(LmsApp->getDboSession())->getClusterTypes()};
auto clusterGroups {release->getClusterGroups(clusterTypes, 3)};
const auto clusterTypes {ScanSettings::get(LmsApp->getDbSession())->getClusterTypes()};
const auto clusterGroups {release->getClusterGroups(clusterTypes, 3)};
for (auto clusters : clusterGroups)
for (const auto& clusters : clusterGroups)
{
for (auto cluster : clusters)
for (const auto& cluster : clusters)
{
auto clusterId {cluster.id()};
auto entry {clusterContainers->addWidget(LmsApp->createCluster(cluster))};
+6 -6
View File
@@ -58,24 +58,24 @@ ReleasesInfo::refreshRecentlyAdded()
{
auto after = Wt::WLocalDateTime::currentServerDateTime().toUTC().addMonths(-1);
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
auto releases {Release::getLastAdded(LmsApp->getDboSession(), after, 0, 5)};
const auto releases {Release::getLastAdded(LmsApp->getDbSession(), after, 0, 5)};
_recentlyAddedContainer->clear();
for (auto release : releases)
for (const Database::Release::pointer& release : releases)
_recentlyAddedContainer->addNew<ReleaseLink>(release);
}
void
ReleasesInfo::refreshMostPlayed()
{
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
auto releases = LmsApp->getUser()->getPlayedTrackList()->getTopReleases(5);
const auto releases {LmsApp->getUser()->getPlayedTrackList(LmsApp->getDbSession())->getTopReleases(5)};
_mostPlayedContainer->clear();
for (auto release : releases)
for (const Database::Release::pointer& release : releases)
_mostPlayedContainer->addNew<ReleaseLink>(release);
}
+6 -7
View File
@@ -71,18 +71,17 @@ Releases::refresh()
void
Releases::addSome()
{
auto searchKeywords = splitString(_search->text().toUTF8(), " ");
const auto searchKeywords {splitString(_search->text().toUTF8(), " ")};
const auto clusterIds {_filters->getClusterIds()};
auto clusterIds = _filters->getClusterIds();
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
bool moreResults;
auto releases = Release::getByFilter(LmsApp->getDboSession(), clusterIds, searchKeywords, _container->count(), 20, moreResults);
const auto releases {Release::getByFilter(LmsApp->getDbSession(), clusterIds, searchKeywords, _container->count(), 20, moreResults)};
for (auto release : releases)
for (const Database::Release::pointer& release : releases)
{
auto releaseId = release.id();
const Database::IdType releaseId {release.id()};
Wt::WTemplate* entry = _container->addNew<Wt::WTemplate>(Wt::WString::tr("Lms.Explore.Releases.template.entry"));
entry->addFunction("tr", Wt::WTemplate::Functions::tr);
+5 -5
View File
@@ -74,10 +74,10 @@ TracksInfo::TracksInfo()
void
TracksInfo::refreshRecentlyAdded()
{
auto after = Wt::WLocalDateTime::currentServerDateTime().toUTC().addMonths(-1);
const auto after {Wt::WLocalDateTime::currentServerDateTime().toUTC().addMonths(-1)};
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
auto tracks = Track::getLastAdded(LmsApp->getDboSession(), after, 5);
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
const auto tracks {Track::getLastAdded(LmsApp->getDbSession(), after, 5)};
_recentlyAddedContainer->clear();
addEntries(_recentlyAddedContainer, tracks);
@@ -86,8 +86,8 @@ TracksInfo::refreshRecentlyAdded()
void
TracksInfo::refreshMostPlayed()
{
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
auto tracks = LmsApp->getUser()->getPlayedTrackList()->getTopTracks(5);
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
const auto tracks {LmsApp->getUser()->getPlayedTrackList(LmsApp->getDbSession())->getTopTracks(5)};
_mostPlayedContainer->clear();
addEntries(_mostPlayedContainer, tracks);
+18 -13
View File
@@ -52,14 +52,12 @@ _filters(filters)
Wt::WText* playBtn = bindNew<Wt::WText>("play-btn", Wt::WString::tr("Lms.Explore.template.play-btn"), Wt::TextFormat::XHTML);
playBtn->clicked().connect(std::bind([=]
{
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
tracksPlay.emit(getTracks());
}));
Wt::WText* addBtn = bindNew<Wt::WText>("add-btn", Wt::WString::tr("Lms.Explore.template.add-btn"), Wt::TextFormat::XHTML);
addBtn->clicked().connect(std::bind([=]
{
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
tracksAdd.emit(getTracks());
}));
@@ -76,18 +74,24 @@ _filters(filters)
filters->updated().connect(this, &Tracks::refresh);
}
std::vector<Database::Track::pointer>
std::vector<Database::IdType>
Tracks::getTracks(boost::optional<std::size_t> offset, boost::optional<std::size_t> size, bool& moreResults)
{
auto searchKeywords {splitString(_search->text().toUTF8(), " ")};
auto clusterIds {_filters->getClusterIds()};
const auto searchKeywords {splitString(_search->text().toUTF8(), " ")};
const auto clusterIds {_filters->getClusterIds()};
Wt::Dbo::Transaction transaction {LmsApp->getDboSession()};
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
const auto tracks {Track::getByFilter(LmsApp->getDbSession(), clusterIds, searchKeywords, offset, size, moreResults)};
std::vector<Database::IdType> res;
res.reserve(tracks.size());
std::transform(std::cbegin(tracks), std::cend(tracks), std::back_inserter(res), [](const Database::Track::pointer& track) { return track.id(); });
return res;
return Track::getByFilter(LmsApp->getDboSession(), clusterIds, searchKeywords, offset, size, moreResults);
}
std::vector<Database::Track::pointer>
std::vector<Database::IdType>
Tracks::getTracks()
{
bool moreResults;
@@ -104,14 +108,15 @@ Tracks::refresh()
void
Tracks::addSome()
{
Wt::Dbo::Transaction transaction {LmsApp->getDboSession()};
bool moreResults;
auto tracks {getTracks(_tracksContainer->count(), 20, moreResults)};
const std::vector<Database::IdType> trackIds {getTracks(_tracksContainer->count(), 20, moreResults)};
for (auto track : tracks)
for (const Database::IdType trackId : trackIds)
{
auto trackId {track.id()};
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
const Database::Track::pointer track {Database::Track::getById(LmsApp->getDbSession(), trackId)};
Wt::WTemplate* entry {_tracksContainer->addNew<Wt::WTemplate>(Wt::WString::tr("Lms.Explore.Tracks.template.entry"))};
entry->bindString("name", Wt::WString::fromUTF8(track->getName()), Wt::TextFormat::Plain);
+6 -5
View File
@@ -19,13 +19,14 @@
#pragma once
#include <boost/optional.hpp>
#include <Wt/WContainerWidget.h>
#include <Wt/WLineEdit.h>
#include <Wt/WPushButton.h>
#include <Wt/WTemplate.h>
#include "database/Types.hpp"
#include "database/Track.hpp"
namespace UserInterface {
@@ -38,15 +39,15 @@ class Tracks : public Wt::WTemplate
Wt::Signal<Database::IdType> trackAdd;
Wt::Signal<Database::IdType> trackPlay;
Wt::Signal<std::vector<Database::Track::pointer>> tracksAdd;
Wt::Signal<std::vector<Database::Track::pointer>> tracksPlay;
Wt::Signal<std::vector<Database::IdType>> tracksAdd;
Wt::Signal<std::vector<Database::IdType>> tracksPlay;
private:
void refresh();
void addSome();
std::vector<Database::Track::pointer> getTracks(boost::optional<std::size_t> offset, boost::optional<std::size_t> size, bool& moreResults);
std::vector<Database::Track::pointer> getTracks();
std::vector<Database::IdType> getTracks(boost::optional<std::size_t> offset, boost::optional<std::size_t> size, bool& moreResults);
std::vector<Database::IdType> getTracks();
Wt::WContainerWidget* _tracksContainer;
Wt::WPushButton* _showMore;
+4 -8
View File
@@ -38,9 +38,7 @@ AudioResource:: ~AudioResource()
std::string
AudioResource::getUrl(Database::IdType trackId) const
{
std::string res = url()+ "&trackid=" + std::to_string(trackId);
return res;
return url()+ "&trackid=" + std::to_string(trackId);
}
void
@@ -82,14 +80,12 @@ AudioResource::handleRequest(const Wt::Http::Request& request,
return;
}
// transactions are not thread safe
// DbSession are not thread safe
{
Wt::WApplication::UpdateLock lock(LmsApp);
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
Database::Track::pointer track = Database::Track::getById(LmsApp->getDboSession(), trackId);
const Database::Track::pointer track {Database::Track::getById(LmsApp->getDbSession(), trackId)};
if (!track)
{
LMS_LOG(UI, ERROR) << "Missing track";
-1
View File
@@ -23,7 +23,6 @@
#include "av/AvTranscoder.hpp"
#include "database/DatabaseHandler.hpp"
#include "database/Types.hpp"
+9 -9
View File
@@ -65,7 +65,7 @@ ImageResource::handleRequest(const Wt::Http::Request& request, Wt::Http::Respons
if (!sizeStr)
return;
auto size = readAs<std::size_t>(*sizeStr);
const auto size {readAs<std::size_t>(*sizeStr)};
if (!size || *size > maxSize)
return;
@@ -73,26 +73,26 @@ ImageResource::handleRequest(const Wt::Http::Request& request, Wt::Http::Respons
if (trackIdStr)
{
auto trackId = readAs<Database::IdType>(*trackIdStr);
const auto trackId {readAs<Database::IdType>(*trackIdStr)};
if (!trackId)
return;
// transactions are not thread safe
// DbSession are not thread safe
{
Wt::WApplication::UpdateLock lock(LmsApp);
cover = getService<CoverArt::Grabber>()->getFromTrack(LmsApp->getDboSession(), *trackId, Image::Format::JPEG, *size);
Wt::WApplication::UpdateLock lock {LmsApp};
cover = getService<CoverArt::Grabber>()->getFromTrack(LmsApp->getDbSession(), *trackId, Image::Format::JPEG, *size);
}
}
else if (releaseIdStr)
{
auto releaseId = readAs<Database::IdType>(*releaseIdStr);
const auto releaseId {readAs<Database::IdType>(*releaseIdStr)};
if (!releaseId)
return;
// transactions are not thread safe
// DbSession are not thread safe
{
Wt::WApplication::UpdateLock lock(LmsApp);
cover = getService<CoverArt::Grabber>()->getFromRelease(LmsApp->getDboSession(), *releaseId, Image::Format::JPEG, *size);
Wt::WApplication::UpdateLock lock {LmsApp};
cover = getService<CoverArt::Grabber>()->getFromRelease(LmsApp->getDbSession(), *releaseId, Image::Format::JPEG, *size);
}
}
else
+1 -2
View File
@@ -24,7 +24,6 @@
#include <Wt/WResource.h>
#include "database/DatabaseHandler.hpp"
#include "database/Types.hpp"
#include "image/Image.hpp"
@@ -35,7 +34,7 @@ namespace UserInterface {
class ImageResource : public Wt::WResource
{
public:
static const std::size_t maxSize = 512;
static const std::size_t maxSize {512};
~ImageResource();