Added some feedback about the last/current/next media directory scans
This commit is contained in:
@@ -458,16 +458,36 @@ LmsApplication::createHome()
|
||||
});
|
||||
|
||||
// Events from MediaScanner
|
||||
std::string sessionId = LmsApp->sessionId();
|
||||
getService<Scanner::MediaScanner>()->scanComplete().connect([=] (Scanner::MediaScanner::Stats stats)
|
||||
{
|
||||
// Runs from media scanner context
|
||||
Wt::WServer::instance()->post(sessionId, [=]
|
||||
std::string sessionId = LmsApp->sessionId();
|
||||
getService<Scanner::MediaScanner>()->scanComplete().connect(this, [=] (Scanner::MediaScanner::Stats stats)
|
||||
{
|
||||
_events.dbScanned.emit(stats);
|
||||
triggerUpdate();
|
||||
Wt::WServer::instance()->post(sessionId, [=]
|
||||
{
|
||||
_events.dbScanned.emit(stats);
|
||||
triggerUpdate();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
getService<Scanner::MediaScanner>()->scanInProgress().connect(this, [=] (Scanner::MediaScanner::Stats stats)
|
||||
{
|
||||
Wt::WServer::instance()->post(sessionId, [=]
|
||||
{
|
||||
_events.dbScanInProgress.emit(stats);
|
||||
triggerUpdate();
|
||||
});
|
||||
});
|
||||
|
||||
getService<Scanner::MediaScanner>()->scheduled().connect(this, [=] (Wt::WDateTime dateTime)
|
||||
{
|
||||
Wt::WServer::instance()->post(sessionId, [=]
|
||||
{
|
||||
_events.dbScanScheduled.emit(dateTime);
|
||||
triggerUpdate();
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
_events.dbScanned.connect([=] (Scanner::MediaScanner::Stats stats)
|
||||
{
|
||||
|
||||
@@ -55,8 +55,10 @@ struct Events
|
||||
// Unload current track
|
||||
Wt::Signal<> trackUnloaded;
|
||||
|
||||
// A database scan is complete
|
||||
// Database events
|
||||
Wt::Signal<Scanner::MediaScanner::Stats> dbScanned;
|
||||
Wt::Signal<Scanner::MediaScanner::Stats> dbScanInProgress;
|
||||
Wt::Signal<Wt::WDateTime> dbScanScheduled;
|
||||
};
|
||||
|
||||
// Used to classify the message sent to the user
|
||||
|
||||
@@ -19,10 +19,14 @@
|
||||
|
||||
#include "DatabaseSettingsView.hpp"
|
||||
|
||||
#include <ostream>
|
||||
#include <iomanip>
|
||||
|
||||
#include <Wt/WComboBox.h>
|
||||
#include <Wt/WFormModel.h>
|
||||
#include <Wt/WLineEdit.h>
|
||||
#include <Wt/WPushButton.h>
|
||||
#include <Wt/WServer.h>
|
||||
#include <Wt/WString.h>
|
||||
#include <Wt/WTemplateFormView.h>
|
||||
|
||||
@@ -62,7 +66,7 @@ class DatabaseSettingsModel : public Wt::WFormModel
|
||||
addField(SimilarityEngineTypeField);
|
||||
addField(TagsField);
|
||||
|
||||
auto dirValidator = std::make_shared<DirectoryValidator>();
|
||||
auto dirValidator {std::make_shared<DirectoryValidator>()};
|
||||
dirValidator->setMandatory(true);
|
||||
setValidator(MediaDirectoryField, dirValidator);
|
||||
|
||||
@@ -174,6 +178,85 @@ const Wt::WFormModel::Field DatabaseSettingsModel::UpdateStartTimeField = "upda
|
||||
const Wt::WFormModel::Field DatabaseSettingsModel::SimilarityEngineTypeField = "similarity-engine-type";
|
||||
const Wt::WFormModel::Field DatabaseSettingsModel::TagsField = "tags";
|
||||
|
||||
static
|
||||
std::string durationToString(const Wt::WDateTime& begin, const Wt::WDateTime& end)
|
||||
{
|
||||
auto secs {std::chrono::duration_cast<std::chrono::seconds>(end.toTimePoint() - begin.toTimePoint()).count()};
|
||||
|
||||
std::ostringstream oss;
|
||||
|
||||
if (secs >= 3600)
|
||||
oss << secs/3600 << "h";
|
||||
if (secs >= 60)
|
||||
oss << std::setw(2) << std::setfill('0') << (secs % 3600) / 60 << "m";
|
||||
oss << std::setw(2) << std::setfill('0') << (secs % 60) << "s";
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
class DatabaseStatus : public Wt::WTemplate
|
||||
{
|
||||
public:
|
||||
|
||||
DatabaseStatus(): WTemplate {Wt::WString::tr("Lms.Admin.Database.Status.template")}
|
||||
{
|
||||
addFunction("tr", &Wt::WTemplate::Functions::tr);
|
||||
|
||||
using namespace Scanner;
|
||||
|
||||
auto onDbEvent = [&]() { refreshContents(); };
|
||||
|
||||
LmsApp->getEvents().dbScanned.connect(this, onDbEvent);
|
||||
LmsApp->getEvents().dbScanInProgress.connect(this, onDbEvent);
|
||||
LmsApp->getEvents().dbScanScheduled.connect(this, onDbEvent);
|
||||
|
||||
refreshContents();
|
||||
}
|
||||
|
||||
private:
|
||||
void refreshContents()
|
||||
{
|
||||
using namespace Scanner;
|
||||
|
||||
MediaScanner::Status status {getService<MediaScanner>()->getStatus()};
|
||||
|
||||
if (status.lastScanStats)
|
||||
{
|
||||
bindString("last-scan", Wt::WString::tr("Lms.Admin.Database.Status.last-scan-status")
|
||||
.arg(status.lastScanStats->totalFiles)
|
||||
.arg(durationToString(status.lastScanStats->startTime, status.lastScanStats->stopTime))
|
||||
.arg(status.lastScanStats->stopTime.toString())
|
||||
.arg(status.lastScanStats->nbErrors())
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
bindString("last-scan", Wt::WString::tr("Lms.Admin.Database.Status.last-scan-not-available"));
|
||||
}
|
||||
|
||||
switch (status.currentState)
|
||||
{
|
||||
case MediaScanner::State::NotScheduled:
|
||||
bindString("status", Wt::WString::tr("Lms.Admin.Database.Status.status-not-scheduled"));
|
||||
break;
|
||||
case MediaScanner::State::Scheduled:
|
||||
bindString("status", Wt::WString::tr("Lms.Admin.Database.Status.status-scheduled")
|
||||
.arg(status.nextScheduledScan.toString()));
|
||||
break;
|
||||
case MediaScanner::State::InProgress:
|
||||
{
|
||||
std::ostringstream oss;
|
||||
bindString("status", Wt::WString::tr("Lms.Admin.Database.Status.status-in-progress")
|
||||
.arg(status.inProgressStats->nbFiles())
|
||||
.arg(status.inProgressStats->totalFiles)
|
||||
.arg(static_cast<int>(status.inProgressStats->nbFiles() / static_cast<float>(status.inProgressStats->totalFiles ? status.inProgressStats->totalFiles : 1) * 100)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
private:
|
||||
};
|
||||
|
||||
DatabaseSettingsView::DatabaseSettingsView()
|
||||
{
|
||||
wApp->internalPathChanged().connect(std::bind([=]
|
||||
@@ -221,6 +304,8 @@ DatabaseSettingsView::refreshView()
|
||||
Wt::WPushButton *discardBtn = t->bindWidget("discard-btn", std::make_unique<Wt::WPushButton>(Wt::WString::tr("Lms.discard")));
|
||||
Wt::WPushButton *immScanBtn = t->bindWidget("immediate-scan-btn", std::make_unique<Wt::WPushButton>(Wt::WString::tr("Lms.Admin.Database.immediate-scan")));
|
||||
|
||||
t->bindNew<DatabaseStatus>("status");
|
||||
|
||||
saveBtn->clicked().connect([=] ()
|
||||
{
|
||||
t->updateModel(model.get());
|
||||
@@ -229,7 +314,7 @@ DatabaseSettingsView::refreshView()
|
||||
{
|
||||
model->saveData();
|
||||
|
||||
getService<Scanner::MediaScanner>()->reschedule();
|
||||
getService<Scanner::MediaScanner>()->requestReschedule();
|
||||
LmsApp->notifyMsg(MsgType::Success, Wt::WString::tr("Lms.Admin.Database.settings-saved"));
|
||||
}
|
||||
|
||||
@@ -246,7 +331,7 @@ DatabaseSettingsView::refreshView()
|
||||
|
||||
immScanBtn->clicked().connect([=] ()
|
||||
{
|
||||
getService<Scanner::MediaScanner>()->scheduleImmediateScan();
|
||||
getService<Scanner::MediaScanner>()->requestImmediateScan();
|
||||
LmsApp->notifyMsg(MsgType::Info, Wt::WString::tr("Lms.Admin.Database.scan-launched"));
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user