mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
embedded webui + config modification detection (#240)
* implement embedded webui * add detection for changed config, later on used for restart hyperion
This commit is contained in:
parent
ccc50899fb
commit
1cc2f72fa2
@ -14,7 +14,7 @@ table.borderless td,table.borderless th{border: none !important;}
|
|||||||
|
|
||||||
/*Header*/
|
/*Header*/
|
||||||
.navbar-brand{padding: 5px;padding-left:20px;height:60px;}
|
.navbar-brand{padding: 5px;padding-left:20px;height:60px;}
|
||||||
.sidebar{margin-top:91px;}
|
.sidebar{margin-top:61px;padding-top:20px;}
|
||||||
.dropdown{font-size:18px;}
|
.dropdown{font-size:18px;}
|
||||||
@media (max-width: 767px) {.sidebar{margin-top:0px;}}
|
@media (max-width: 767px) {.sidebar{margin-top:0px;}}
|
||||||
|
|
||||||
|
@ -80,7 +80,6 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div id="loading_overlay"></div>
|
<div id="loading_overlay"></div>
|
||||||
|
|
||||||
<div id="wrapper">
|
<div id="wrapper">
|
||||||
|
|
||||||
<!-- Navigation -->
|
<!-- Navigation -->
|
||||||
@ -225,7 +224,16 @@
|
|||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<!-- Page Content -->
|
<!-- Page Content -->
|
||||||
<div id="page-wrapper" />
|
<div id="page-wrapper" style="padding-top:10px">
|
||||||
|
<div id="hyperion_restart_notify" class="alert alert-warning" style="display:none;padding:10px;margin:0">
|
||||||
|
<div class="panel-danger" style="text-align:right">
|
||||||
|
<div style="float:left">Hyperion Configuration is modified. To make it active, restart Hyperion.</div>
|
||||||
|
<button id="btn_hyperion_restart" class="btn btn-danger">Restart Hyperion</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="page-content" />
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<!-- /#wrapper -->
|
<!-- /#wrapper -->
|
||||||
|
@ -20,6 +20,12 @@ $(document).ready( function() {
|
|||||||
parsedServerInfoJSON = event.response;
|
parsedServerInfoJSON = event.response;
|
||||||
currentVersion = parsedServerInfoJSON.info.hyperion[0].version;
|
currentVersion = parsedServerInfoJSON.info.hyperion[0].version;
|
||||||
cleanCurrentVersion = currentVersion.replace(/\./g, '');
|
cleanCurrentVersion = currentVersion.replace(/\./g, '');
|
||||||
|
|
||||||
|
if (parsedServerInfoJSON.info.hyperion[0].config_modified)
|
||||||
|
$("#hyperion_restart_notify").fadeIn("fast");
|
||||||
|
else
|
||||||
|
$("#hyperion_restart_notify").fadeOut("fast");
|
||||||
|
|
||||||
// get active led device
|
// get active led device
|
||||||
var leddevice = parsedServerInfoJSON.info.ledDevices.active;
|
var leddevice = parsedServerInfoJSON.info.ledDevices.active;
|
||||||
$('#dash_leddevice').html(leddevice);
|
$('#dash_leddevice').html(leddevice);
|
||||||
|
@ -149,7 +149,7 @@ $(document).ready(function() {
|
|||||||
isCurrentDevice = (server.info.ledDevices.active == $(this).val());
|
isCurrentDevice = (server.info.ledDevices.active == $(this).val());
|
||||||
|
|
||||||
for(var key in parsedConfJSON.device){
|
for(var key in parsedConfJSON.device){
|
||||||
if (key in generalOptions.properties)
|
if (key != "type" && key in generalOptions.properties)
|
||||||
values_general[key] = parsedConfJSON.device[key];
|
values_general[key] = parsedConfJSON.device[key];
|
||||||
};
|
};
|
||||||
grabber_conf_editor.getEditor("root.generalOptions").setValue( values_general );
|
grabber_conf_editor.getEditor("root.generalOptions").setValue( values_general );
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
|
|
||||||
function bindNavToContent(containerId, fileName, loadNow)
|
function bindNavToContent(containerId, fileName, loadNow)
|
||||||
{
|
{
|
||||||
$("#page-wrapper").off();
|
$("#page-content").off();
|
||||||
$(containerId).on("click", function() {
|
$(containerId).on("click", function() {
|
||||||
$("#page-wrapper").load("/content/"+fileName+".html");
|
$("#page-content").load("/content/"+fileName+".html");
|
||||||
});
|
});
|
||||||
if (loadNow)
|
if (loadNow)
|
||||||
{
|
{
|
||||||
$("#page-wrapper").load("/content/"+fileName+".html");
|
$("#page-content").load("/content/"+fileName+".html");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,8 +195,6 @@
|
|||||||
"webConfig" :
|
"webConfig" :
|
||||||
{
|
{
|
||||||
"enable" : true,
|
"enable" : true,
|
||||||
"document_root" : "/usr/share/hyperion/webconfig",
|
|
||||||
"port" : 8099
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"effects" :
|
"effects" :
|
||||||
|
@ -163,6 +163,8 @@ public:
|
|||||||
|
|
||||||
ComponentRegister& getComponentRegister() { return _componentRegister; };
|
ComponentRegister& getComponentRegister() { return _componentRegister; };
|
||||||
|
|
||||||
|
bool configModified();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
///
|
///
|
||||||
/// Writes a single color to all the leds for the given time and priority
|
/// Writes a single color to all the leds for the given time and priority
|
||||||
@ -386,5 +388,6 @@ private:
|
|||||||
|
|
||||||
/// holds the current priority channel that is manualy selected
|
/// holds the current priority channel that is manualy selected
|
||||||
int _currentSourcePriority;
|
int _currentSourcePriority;
|
||||||
|
|
||||||
|
QByteArray _configHash;
|
||||||
};
|
};
|
||||||
|
@ -26,7 +26,7 @@ private:
|
|||||||
quint16 _port;
|
quint16 _port;
|
||||||
StaticFileServing* _server;
|
StaticFileServing* _server;
|
||||||
|
|
||||||
const std::string WEBCONFIG_DEFAULT_PATH = "/usr/share/hyperion/webconfig";
|
const QString WEBCONFIG_DEFAULT_PATH = ":/webconfig";
|
||||||
const quint16 WEBCONFIG_DEFAULT_PORT = 8099;
|
const quint16 WEBCONFIG_DEFAULT_PORT = 8099;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ CONFIGURE_FILE(${CURRENT_SOURCE_DIR}/EffectEngine.qrc.in ${CMAKE_BINARY_DIR}/Eff
|
|||||||
SET(EffectEngine_RESOURCES ${CMAKE_BINARY_DIR}/EffectEngine.qrc)
|
SET(EffectEngine_RESOURCES ${CMAKE_BINARY_DIR}/EffectEngine.qrc)
|
||||||
|
|
||||||
QT5_WRAP_CPP(EffectEngineHEADERS_MOC ${EffectEngineQT_HEADERS})
|
QT5_WRAP_CPP(EffectEngineHEADERS_MOC ${EffectEngineQT_HEADERS})
|
||||||
qt5_add_resources(EffectEngine_RESOURCES_RCC ${EffectEngine_RESOURCES} OPTIONS "-no-compress")
|
qt5_add_resources(EffectEngine_RESOURCES_RCC ${EffectEngine_RESOURCES} ) # OPTIONS "-no-compress"
|
||||||
|
|
||||||
add_library(effectengine
|
add_library(effectengine
|
||||||
${EffectEngineHEADERS}
|
${EffectEngineHEADERS}
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
#include <QRegExp>
|
#include <QRegExp>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
#include <QCryptographicHash>
|
||||||
|
#include <QFile>
|
||||||
|
|
||||||
// JsonSchema include
|
// JsonSchema include
|
||||||
#include <utils/jsonschema/JsonFactory.h>
|
#include <utils/jsonschema/JsonFactory.h>
|
||||||
@ -575,6 +577,7 @@ Hyperion::Hyperion(const Json::Value &jsonConfig, const std::string configFile)
|
|||||||
, _log(Logger::getInstance("Core"))
|
, _log(Logger::getInstance("Core"))
|
||||||
, _hwLedCount(_ledString.leds().size())
|
, _hwLedCount(_ledString.leds().size())
|
||||||
, _sourceAutoSelectEnabled(true)
|
, _sourceAutoSelectEnabled(true)
|
||||||
|
, _configHash()
|
||||||
{
|
{
|
||||||
registerPriority("Off", PriorityMuxer::LOWEST_PRIORITY);
|
registerPriority("Off", PriorityMuxer::LOWEST_PRIORITY);
|
||||||
|
|
||||||
@ -623,6 +626,9 @@ Hyperion::Hyperion(const Json::Value &jsonConfig, const std::string configFile)
|
|||||||
Debug(_log,"configured leds: %d hw leds: %d", getLedCount(), _hwLedCount);
|
Debug(_log,"configured leds: %d hw leds: %d", getLedCount(), _hwLedCount);
|
||||||
WarningIf(hwLedCount < getLedCount(), _log, "more leds configured than available. check 'ledCount' in 'device' section");
|
WarningIf(hwLedCount < getLedCount(), _log, "more leds configured than available. check 'ledCount' in 'device' section");
|
||||||
|
|
||||||
|
// initialize hash of current config
|
||||||
|
configModified();
|
||||||
|
|
||||||
// initialize the leds
|
// initialize the leds
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
@ -648,6 +654,29 @@ unsigned Hyperion::getLedCount() const
|
|||||||
return _ledString.leds().size();
|
return _ledString.leds().size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Hyperion::configModified()
|
||||||
|
{
|
||||||
|
QFile f(_configFile.c_str());
|
||||||
|
if (f.open(QFile::ReadOnly))
|
||||||
|
{
|
||||||
|
QCryptographicHash hash(QCryptographicHash::Sha1);
|
||||||
|
if (hash.addData(&f))
|
||||||
|
{
|
||||||
|
if (_configHash.size() == 0)
|
||||||
|
{
|
||||||
|
_configHash = hash.result();
|
||||||
|
qDebug(_configHash.toHex());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return _configHash != hash.result();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.close();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void Hyperion::registerPriority(const std::string name, const int priority)
|
void Hyperion::registerPriority(const std::string name, const int priority)
|
||||||
{
|
{
|
||||||
Info(_log, "Register new input source named '%s' for priority channel '%d'", name.c_str(), priority );
|
Info(_log, "Register new input source named '%s' for priority channel '%d'", name.c_str(), priority );
|
||||||
|
@ -1000,7 +1000,6 @@
|
|||||||
{
|
{
|
||||||
"type" : "object",
|
"type" : "object",
|
||||||
"title" : "WebUI - DANGER CHANGES CAN MAKE THE WEBUI UNREACHABLE!",
|
"title" : "WebUI - DANGER CHANGES CAN MAKE THE WEBUI UNREACHABLE!",
|
||||||
"required" : true,
|
|
||||||
"properties" :
|
"properties" :
|
||||||
{
|
{
|
||||||
"enable" :
|
"enable" :
|
||||||
@ -1009,21 +1008,18 @@
|
|||||||
"format": "checkbox",
|
"format": "checkbox",
|
||||||
"title" : "Activate",
|
"title" : "Activate",
|
||||||
"default" : true,
|
"default" : true,
|
||||||
"required" : true,
|
|
||||||
"propertyOrder" : 1
|
"propertyOrder" : 1
|
||||||
},
|
},
|
||||||
"document_root" :
|
"document_root" :
|
||||||
{
|
{
|
||||||
"type" : "string",
|
"type" : "string",
|
||||||
"title" : "Document Root",
|
"title" : "Document Root"
|
||||||
"required" : true
|
|
||||||
},
|
},
|
||||||
"port" :
|
"port" :
|
||||||
{
|
{
|
||||||
"type" : "integer",
|
"type" : "integer",
|
||||||
"title" : "Port",
|
"title" : "Port",
|
||||||
"default" : 8099,
|
"default" : 8099
|
||||||
"required" : true
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
|
@ -669,9 +669,9 @@ void JsonClientConnection::handleServerInfoCommand(const Json::Value &, const st
|
|||||||
ver["version"] = HYPERION_VERSION;
|
ver["version"] = HYPERION_VERSION;
|
||||||
ver["build"] = HYPERION_BUILD_ID;
|
ver["build"] = HYPERION_BUILD_ID;
|
||||||
ver["time"] = __DATE__ " " __TIME__;
|
ver["time"] = __DATE__ " " __TIME__;
|
||||||
|
ver["config_modified"] = _hyperion->configModified();
|
||||||
|
|
||||||
info["hyperion"].append(ver);
|
info["hyperion"].append(ver);
|
||||||
|
|
||||||
// send the result
|
// send the result
|
||||||
sendMessage(result);
|
sendMessage(result);
|
||||||
}
|
}
|
||||||
|
@ -27,14 +27,23 @@ set(WebConfig_SOURCES
|
|||||||
${CURRENT_SOURCE_DIR}/StaticFileServing.cpp
|
${CURRENT_SOURCE_DIR}/StaticFileServing.cpp
|
||||||
${CURRENT_SOURCE_DIR}/WebConfig.cpp
|
${CURRENT_SOURCE_DIR}/WebConfig.cpp
|
||||||
)
|
)
|
||||||
|
FILE ( GLOB_RECURSE webFiles RELATIVE ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/assets/webconfig/* )
|
||||||
|
FOREACH( f ${webFiles} )
|
||||||
|
STRING ( REPLACE "../assets/webconfig/" "" fname ${f})
|
||||||
|
SET(HYPERION_WEBCONFIG_RES "${HYPERION_WEBCONFIG_RES}\n\t\t<file alias=\"/webconfig/${fname}\">${f}</file>")
|
||||||
|
ENDFOREACH()
|
||||||
|
CONFIGURE_FILE(${CURRENT_SOURCE_DIR}/WebConfig.qrc.in ${CMAKE_BINARY_DIR}/WebConfig.qrc )
|
||||||
|
SET(WebConfig_RESOURCES ${CMAKE_BINARY_DIR}/WebConfig.qrc)
|
||||||
|
|
||||||
qt5_wrap_cpp(WebConfig_HEADERS_MOC ${WebConfig_QT_HEADERS})
|
qt5_wrap_cpp(WebConfig_HEADERS_MOC ${WebConfig_QT_HEADERS})
|
||||||
|
qt5_add_resources(WebConfig_RESOURCES_RCC ${WebConfig_RESOURCES} ) #OPTIONS "-no-compress"
|
||||||
|
|
||||||
add_library(webconfig
|
add_library(webconfig
|
||||||
${WebConfig_HEADERS}
|
${WebConfig_HEADERS}
|
||||||
${WebConfig_QT_HEADERS}
|
${WebConfig_QT_HEADERS}
|
||||||
${WebConfig_SOURCES}
|
${WebConfig_SOURCES}
|
||||||
${WebConfig_HEADERS_MOC}
|
${WebConfig_HEADERS_MOC}
|
||||||
|
${WebConfig_RESOURCES_RCC}
|
||||||
)
|
)
|
||||||
|
|
||||||
qt5_use_modules(webconfig Network)
|
qt5_use_modules(webconfig Network)
|
||||||
|
@ -7,14 +7,17 @@
|
|||||||
#include <QPair>
|
#include <QPair>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
|
#include <QResource>
|
||||||
|
|
||||||
StaticFileServing::StaticFileServing (Hyperion *hyperion, QString baseUrl, quint16 port, QObject * parent)
|
StaticFileServing::StaticFileServing (Hyperion *hyperion, QString baseUrl, quint16 port, QObject * parent)
|
||||||
: QObject (parent)
|
: QObject (parent)
|
||||||
, _hyperion(hyperion)
|
, _hyperion(hyperion)
|
||||||
, _baseUrl (baseUrl)
|
, _baseUrl (baseUrl)
|
||||||
, _cgi(hyperion, baseUrl, this)
|
, _cgi(hyperion, baseUrl, this)
|
||||||
, _log(Logger::getInstance("WEBSERVER"))
|
, _log(Logger::getInstance("WEBSERVER"))
|
||||||
{
|
{
|
||||||
|
Q_INIT_RESOURCE(WebConfig);
|
||||||
|
|
||||||
_mimeDb = new QMimeDatabase;
|
_mimeDb = new QMimeDatabase;
|
||||||
|
|
||||||
_server = new QtHttpServer (this);
|
_server = new QtHttpServer (this);
|
||||||
@ -26,6 +29,7 @@ StaticFileServing::StaticFileServing (Hyperion *hyperion, QString baseUrl, quint
|
|||||||
connect (_server, &QtHttpServer::requestNeedsReply, this, &StaticFileServing::onRequestNeedsReply);
|
connect (_server, &QtHttpServer::requestNeedsReply, this, &StaticFileServing::onRequestNeedsReply);
|
||||||
|
|
||||||
_server->start (port);
|
_server->start (port);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StaticFileServing::~StaticFileServing ()
|
StaticFileServing::~StaticFileServing ()
|
||||||
@ -75,6 +79,7 @@ void StaticFileServing::onRequestNeedsReply (QtHttpRequest * request, QtHttpRepl
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Q_INIT_RESOURCE(WebConfig);
|
||||||
|
|
||||||
QFileInfo info(_baseUrl % "/" % path);
|
QFileInfo info(_baseUrl % "/" % path);
|
||||||
if ( path == "/" || path.isEmpty() || ! info.exists() )
|
if ( path == "/" || path.isEmpty() || ! info.exists() )
|
||||||
|
@ -1,17 +1,18 @@
|
|||||||
#include "webconfig/WebConfig.h"
|
#include "webconfig/WebConfig.h"
|
||||||
#include "StaticFileServing.h"
|
#include "StaticFileServing.h"
|
||||||
|
|
||||||
|
#include <QFileInfo>
|
||||||
|
|
||||||
WebConfig::WebConfig(QObject * parent)
|
WebConfig::WebConfig(QObject * parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
|
, _hyperion(Hyperion::getInstance())
|
||||||
|
, _port(WEBCONFIG_DEFAULT_PORT)
|
||||||
, _server(nullptr)
|
, _server(nullptr)
|
||||||
{
|
{
|
||||||
_port = WEBCONFIG_DEFAULT_PORT;
|
_baseUrl = WEBCONFIG_DEFAULT_PATH;
|
||||||
_hyperion = Hyperion::getInstance();
|
|
||||||
const Json::Value &config = _hyperion->getJsonConfig();
|
const Json::Value &config = _hyperion->getJsonConfig();
|
||||||
_baseUrl = QString::fromStdString(WEBCONFIG_DEFAULT_PATH);
|
Logger* log = Logger::getInstance("WEBSERVER");
|
||||||
_port = WEBCONFIG_DEFAULT_PORT;
|
|
||||||
|
|
||||||
bool webconfigEnable = true;
|
bool webconfigEnable = true;
|
||||||
|
|
||||||
if (config.isMember("webConfig"))
|
if (config.isMember("webConfig"))
|
||||||
@ -19,11 +20,24 @@ WebConfig::WebConfig(QObject * parent)
|
|||||||
const Json::Value & webconfigConfig = config["webConfig"];
|
const Json::Value & webconfigConfig = config["webConfig"];
|
||||||
webconfigEnable = webconfigConfig.get("enable", true).asBool();
|
webconfigEnable = webconfigConfig.get("enable", true).asBool();
|
||||||
_port = webconfigConfig.get("port", WEBCONFIG_DEFAULT_PORT).asUInt();
|
_port = webconfigConfig.get("port", WEBCONFIG_DEFAULT_PORT).asUInt();
|
||||||
_baseUrl = QString::fromStdString( webconfigConfig.get("document_root", WEBCONFIG_DEFAULT_PATH).asString() );
|
_baseUrl = QString::fromStdString( webconfigConfig.get("document_root", _baseUrl.toStdString()).asString() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_baseUrl != ":/webconfig")
|
||||||
|
{
|
||||||
|
QFileInfo info(_baseUrl);
|
||||||
|
if (!info.exists() || !info.isDir())
|
||||||
|
{
|
||||||
|
Error(log, "document_root '%s' is invalid, set to default '%s'", _baseUrl.toUtf8().constData(), WEBCONFIG_DEFAULT_PATH.toUtf8().constData());
|
||||||
|
_baseUrl = WEBCONFIG_DEFAULT_PATH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug(log, "WebUI initialized, document root: %s", _baseUrl.toUtf8().constData());
|
||||||
if ( webconfigEnable )
|
if ( webconfigEnable )
|
||||||
|
{
|
||||||
start();
|
start();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
5
libsrc/webconfig/WebConfig.qrc.in
Normal file
5
libsrc/webconfig/WebConfig.qrc.in
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<RCC>
|
||||||
|
<qresource prefix="/">
|
||||||
|
${HYPERION_WEBCONFIG_RES}
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
Loading…
Reference in New Issue
Block a user