mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
implement hyperion restart via webui (#242)
* first try * implement hyperion restart. core function is good, but needs a beeter structuring- something for next refactoring session ;-) * several fixes (including osx) merge with upstream some refactoring * add some eye candy to webui
This commit is contained in:
parent
a04f34eab7
commit
eeb9b0f7da
@ -8,7 +8,7 @@
|
||||
<hr>
|
||||
<div class="col-lg-12">
|
||||
<div id='editor_container'></div>
|
||||
<button id='btn_submit'>Submit (console.log)</button>
|
||||
<button id='btn_submit' class="btn btn-danger">Submit - currently will destroy your config!</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -61,3 +61,7 @@ table.borderless td,table.borderless th{border: none !important;}
|
||||
top: 0;
|
||||
z-index:99999;
|
||||
}
|
||||
|
||||
#page-content {
|
||||
padding-bottom:50px;
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 6.8 KiB |
Binary file not shown.
After Width: | Height: | Size: 6.9 KiB |
Binary file not shown.
After Width: | Height: | Size: 4.6 KiB |
Binary file not shown.
After Width: | Height: | Size: 6.8 KiB |
Binary file not shown.
After Width: | Height: | Size: 4.5 KiB |
Binary file not shown.
After Width: | Height: | Size: 6.2 KiB |
7
assets/webconfig/css/jquery-ui/jquery-ui.min.css
vendored
Normal file
7
assets/webconfig/css/jquery-ui/jquery-ui.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
5
assets/webconfig/css/jquery-ui/jquery-ui.structure.min.css
vendored
Normal file
5
assets/webconfig/css/jquery-ui/jquery-ui.structure.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
5
assets/webconfig/css/jquery-ui/jquery-ui.theme.min.css
vendored
Normal file
5
assets/webconfig/css/jquery-ui/jquery-ui.theme.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -36,6 +36,11 @@
|
||||
<script src="js/lib/jquery-lang.js" charset="utf-8" type="text/javascript"></script>
|
||||
<script src="js/lib/js.cookie.js"></script>
|
||||
|
||||
<!-- jquery ui -->
|
||||
<link href="css/jquery-ui/jquery-ui.min.css" rel="stylesheet">
|
||||
<link href="css/jquery-ui/jquery-ui.structure.min.css" rel="stylesheet">
|
||||
<link href="css/jquery-ui/jquery-ui.theme.min.css" rel="stylesheet">
|
||||
|
||||
<script type="text/javascript">
|
||||
// Create language switcher instance
|
||||
var lang = new Lang();
|
||||
@ -195,7 +200,7 @@
|
||||
</ul>
|
||||
<!-- /.navbar-top-left -->
|
||||
|
||||
<div class="navbar-default sidebar" role="navigation">
|
||||
<div id="main-nav" class="navbar-default sidebar" role="navigation">
|
||||
<div class="sidebar-nav navbar-collapse">
|
||||
<ul class="nav" id="side-menu">
|
||||
<li> <a class="active" id="load_dashboard"><i class="fa fa-dashboard fa-fw"></i><span lang="en" data-lang-token="main_menu_dashboard_token">Dashboard</span></a> </li>
|
||||
@ -225,10 +230,10 @@
|
||||
|
||||
<!-- Page Content -->
|
||||
<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 id="hyperion_reload_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>
|
||||
<button id="btn_hyperion_reload" class="btn btn-danger">Restart Hyperion</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -264,6 +269,7 @@
|
||||
<!-- Custom Theme JavaScript -->
|
||||
<script src="/js/lib/sb-admin-2.js"></script>
|
||||
|
||||
<script src="/js/lib/jquery-ui.min.js"></script>
|
||||
<script src="/js/content_index.js"></script>
|
||||
</body>
|
||||
|
||||
|
@ -50,19 +50,19 @@ $(hyperion).one("cmd-config-getschema", function(event) {
|
||||
schema: {
|
||||
title:'',
|
||||
properties: {
|
||||
/*blackborderdetector,
|
||||
blackborderdetector,
|
||||
color,
|
||||
effects,
|
||||
forwarder,
|
||||
initialEffect,
|
||||
kodiVideoChecker,
|
||||
smoothing,*/
|
||||
logger//,
|
||||
/*jsonServer,
|
||||
smoothing,
|
||||
logger,
|
||||
jsonServer,
|
||||
protoServer,
|
||||
boblightServer,
|
||||
udpListener,
|
||||
webConfig*/
|
||||
webConfig
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -74,10 +74,10 @@ $(hyperion).one("cmd-config-getschema", function(event) {
|
||||
$('#editor_container h3').first().remove();
|
||||
|
||||
//Called everytime a Input Field is changed = No need for save button
|
||||
general_conf_editor.off().on('change',function() {
|
||||
console.log(JSON.stringify(general_conf_editor.getValue()));
|
||||
requestWriteConfig(general_conf_editor.getValue());
|
||||
});
|
||||
// general_conf_editor.off().on('change',function() {
|
||||
// console.log(JSON.stringify(general_conf_editor.getValue()));
|
||||
// requestWriteConfig(general_conf_editor.getValue());
|
||||
// });
|
||||
|
||||
//Alternative Function with submit button to get Values
|
||||
$('btn_submit').off().on('click',function() {
|
||||
|
@ -1,4 +1,6 @@
|
||||
$(document).ready( function() {
|
||||
$("#main-nav").hide();
|
||||
$("#page-content").hide();
|
||||
$("#loading_overlay").addClass("overlay");
|
||||
loadContentTo("#container_connection_lost","connection_lost");
|
||||
initWebSocket();
|
||||
@ -22,9 +24,9 @@ $(document).ready( function() {
|
||||
cleanCurrentVersion = currentVersion.replace(/\./g, '');
|
||||
|
||||
if (parsedServerInfoJSON.info.hyperion[0].config_modified)
|
||||
$("#hyperion_restart_notify").fadeIn("fast");
|
||||
$("#hyperion_reload_notify").fadeIn("fast");
|
||||
else
|
||||
$("#hyperion_restart_notify").fadeOut("fast");
|
||||
$("#hyperion_reload_notify").fadeOut("fast");
|
||||
|
||||
// get active led device
|
||||
var leddevice = parsedServerInfoJSON.info.ledDevices.active;
|
||||
@ -59,6 +61,9 @@ $(document).ready( function() {
|
||||
}
|
||||
});
|
||||
$("#loading_overlay").removeClass("overlay");
|
||||
$("#main-nav").show('slide', {direction: 'left'}, 1000);
|
||||
$("#page-content").show('slide', {direction: 'down'}, 2000);
|
||||
|
||||
}); // end cmd-serverinfo
|
||||
|
||||
$(hyperion).one("cmd-config-getschema", function(event) {
|
||||
@ -75,6 +80,13 @@ $(document).ready( function() {
|
||||
requestServerInfo();
|
||||
});
|
||||
|
||||
$("#btn_hyperion_reload").on("click", function(){
|
||||
$(hyperion).off();
|
||||
requestServerConfigReload();
|
||||
watchdog = 1;
|
||||
$("#wrapper").fadeOut("slow");
|
||||
cron();
|
||||
});
|
||||
});
|
||||
|
||||
$(function(){
|
||||
|
1
assets/webconfig/js/content_kodi.js
Normal file
1
assets/webconfig/js/content_kodi.js
Normal file
@ -0,0 +1 @@
|
||||
|
@ -1,6 +1,21 @@
|
||||
|
||||
var ledsCustomCfgInitialized = false;
|
||||
|
||||
function get_hue_lights(){
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: 'http://'+$("#ip").val()+'/api/'+$("#user").val()+'/lights',
|
||||
processData: false,
|
||||
contentType: 'application/json',
|
||||
success: function(r) {
|
||||
for(var lightid in r){
|
||||
//console.log(r[lightid].name);
|
||||
$('#hue_lights').append('ID: '+lightid+' Name: '+r[lightid].name+'<br />');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
$(document).ready(function() {
|
||||
// ------------------------------------------------------------------
|
||||
@ -157,7 +172,7 @@ $(document).ready(function() {
|
||||
if (isCurrentDevice)
|
||||
{
|
||||
specificOptions_val = grabber_conf_editor.getEditor("root.specificOptions").getValue()
|
||||
for(var key in grabber_conf_editor.getEditor("root.specificOptions").getValue()){
|
||||
for(var key in specificOptions_val){
|
||||
values_specific[key] = (key in parsedConfJSON.device) ? parsedConfJSON.device[key] : specificOptions_val[key];
|
||||
};
|
||||
|
||||
|
@ -155,6 +155,10 @@ function requestServerConfig() {
|
||||
websocket.send('{"command":"config", "tan":'+wsTan+',"subcommand":"getconfig"}');
|
||||
}
|
||||
|
||||
function requestServerConfigReload() {
|
||||
websocket.send('{"command":"config", "tan":'+wsTan+',"subcommand":"reload"}');
|
||||
}
|
||||
|
||||
function requestLedColorsStart() {
|
||||
ledStreamActive=true;
|
||||
websocket.send('{"command":"ledcolors", "tan":'+wsTan+',"subcommand":"ledstream-start"}');
|
||||
@ -197,18 +201,3 @@ function requestWriteConfig(config, create, overwrite)
|
||||
var overwrite = (typeof overwrite !== 'undefined') ? overwrite : false;
|
||||
websocket.send('{"command":"config","subcommand":"setconfig", "tan":'+wsTan+', "config":'+JSON.stringify(config)+',"create":'+create+', "overwrite":'+overwrite+'}');
|
||||
}
|
||||
|
||||
function get_hue_lights(){
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: 'http://'+$("#ip").val()+'/api/'+$("#user").val()+'/lights',
|
||||
processData: false,
|
||||
contentType: 'application/json',
|
||||
success: function(r) {
|
||||
for(var lightid in r){
|
||||
//console.log(r[lightid].name);
|
||||
$('#hue_lights').append('ID: '+lightid+' Name: '+r[lightid].name+'<br />');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
BIN
assets/webconfig/js/lib/jquery-ui-1.12.1.zip
Normal file
BIN
assets/webconfig/js/lib/jquery-ui-1.12.1.zip
Normal file
Binary file not shown.
13
assets/webconfig/js/lib/jquery-ui.min.js
vendored
Normal file
13
assets/webconfig/js/lib/jquery-ui.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -7,7 +7,7 @@ function bindNavToContent(containerId, fileName, loadNow)
|
||||
});
|
||||
if (loadNow)
|
||||
{
|
||||
$("#page-content").load("/content/"+fileName+".html");
|
||||
$(containerId).trigger("click");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,6 @@
|
||||
namespace FileUtils {
|
||||
|
||||
std::string getBaseName( std::string sourceFile);
|
||||
std::string command_exec(const char* cmd);
|
||||
|
||||
|
||||
};
|
||||
|
8
include/utils/Process.h
Normal file
8
include/utils/Process.h
Normal file
@ -0,0 +1,8 @@
|
||||
#include <string>
|
||||
|
||||
namespace Process {
|
||||
|
||||
void restartHyperion(bool asNewProcess=false);
|
||||
std::string command_exec(const char* cmd);
|
||||
|
||||
};
|
@ -657,24 +657,26 @@ unsigned Hyperion::getLedCount() const
|
||||
|
||||
bool Hyperion::configModified()
|
||||
{
|
||||
bool isModified = false;
|
||||
QFile f(_configFile.c_str());
|
||||
if (f.open(QFile::ReadOnly))
|
||||
{
|
||||
QCryptographicHash hash(QCryptographicHash::Sha1);
|
||||
if (hash.addData(&f))
|
||||
if (hash.addData(&f))
|
||||
{
|
||||
if (_configHash.size() == 0)
|
||||
{
|
||||
if (_configHash.size() == 0)
|
||||
{
|
||||
_configHash = hash.result();
|
||||
qDebug(_configHash.toHex());
|
||||
return false;
|
||||
}
|
||||
return _configHash != hash.result();
|
||||
_configHash = hash.result();
|
||||
}
|
||||
else
|
||||
{
|
||||
isModified = _configHash != hash.result();
|
||||
}
|
||||
}
|
||||
}
|
||||
f.close();
|
||||
|
||||
return false;
|
||||
return isModified;
|
||||
}
|
||||
|
||||
void Hyperion::registerPriority(const std::string name, const int priority)
|
||||
|
@ -1057,7 +1057,15 @@
|
||||
{
|
||||
"paths" :
|
||||
{
|
||||
"type" : "array"
|
||||
"type" : "array",
|
||||
"title" : "List of folders to additional effects",
|
||||
"propertyOrder" : 1
|
||||
},
|
||||
"disable" :
|
||||
{
|
||||
"type" : "array",
|
||||
"title" : "List of disabled effects",
|
||||
"propertyOrder" : 2
|
||||
}
|
||||
},
|
||||
"additionalProperties" : false
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <stdexcept>
|
||||
#include <cassert>
|
||||
#include <iomanip>
|
||||
#include <unistd.h>
|
||||
|
||||
// stl includes
|
||||
#include <iostream>
|
||||
@ -15,6 +16,7 @@
|
||||
#include <QHostInfo>
|
||||
#include <QString>
|
||||
#include <QFile>
|
||||
#include <QCoreApplication>
|
||||
|
||||
// hyperion util includes
|
||||
#include <hyperion/ImageProcessorFactory.h>
|
||||
@ -27,6 +29,7 @@
|
||||
#include <leddevice/LedDevice.h>
|
||||
#include <HyperionConfig.h>
|
||||
#include <utils/jsonschema/JsonFactory.h>
|
||||
#include <utils/Process.h>
|
||||
|
||||
// project includes
|
||||
#include "JsonClientConnection.h"
|
||||
@ -883,6 +886,12 @@ void JsonClientConnection::handleConfigCommand(const Json::Value & message, cons
|
||||
{
|
||||
handleConfigSetCommand(message, full_command, tan);
|
||||
}
|
||||
else if (subcommand == "reload")
|
||||
{
|
||||
// restart hyperion, this code must be put in some own class ...
|
||||
Process::restartHyperion();
|
||||
sendErrorReply("failed to restart hyperion", full_command, tan);
|
||||
}
|
||||
else
|
||||
{
|
||||
sendErrorReply("unknown or missing subcommand", full_command, tan);
|
||||
|
@ -10,7 +10,7 @@
|
||||
"subcommand": {
|
||||
"type" : "string",
|
||||
"required" : true,
|
||||
"enum" : ["getconfig","setconfig","getschema"]
|
||||
"enum" : ["getconfig","setconfig","getschema","reload"]
|
||||
},
|
||||
"tan" : {
|
||||
"type" : "integer"
|
||||
|
@ -54,6 +54,9 @@
|
||||
"type" : "array",
|
||||
"propertyOrder" : 9,
|
||||
"default" : [1.0,1.0,1.0],
|
||||
"maxItems" : 3,
|
||||
"minItems" : 3,
|
||||
"format" : "table",
|
||||
"items" : {
|
||||
"type" : "number",
|
||||
"minimum" : 0.0,
|
||||
|
@ -21,6 +21,8 @@ add_library(hyperion-utils
|
||||
${CURRENT_HEADER_DIR}/Sleep.h
|
||||
${CURRENT_HEADER_DIR}/FileUtils.h
|
||||
${CURRENT_SOURCE_DIR}/FileUtils.cpp
|
||||
${CURRENT_HEADER_DIR}/Process.h
|
||||
${CURRENT_SOURCE_DIR}/Process.cpp
|
||||
|
||||
${CURRENT_HEADER_DIR}/Logger.h
|
||||
${CURRENT_SOURCE_DIR}/Logger.cpp
|
||||
|
@ -1,10 +1,5 @@
|
||||
#include <utils/FileUtils.h>
|
||||
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <QFileInfo>
|
||||
|
||||
namespace FileUtils {
|
||||
@ -15,21 +10,5 @@ std::string getBaseName( std::string sourceFile)
|
||||
return fi.fileName().toStdString();
|
||||
}
|
||||
|
||||
std::string command_exec(const char* cmd)
|
||||
{
|
||||
char buffer[128];
|
||||
std::string result = "";
|
||||
std::shared_ptr<FILE> pipe(popen(cmd, "r"), pclose);
|
||||
if (pipe)
|
||||
{
|
||||
while (!feof(pipe.get()))
|
||||
{
|
||||
if (fgets(buffer, 128, pipe.get()) != NULL)
|
||||
result += buffer;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
};
|
57
libsrc/utils/Process.cpp
Normal file
57
libsrc/utils/Process.cpp
Normal file
@ -0,0 +1,57 @@
|
||||
#include <utils/Process.h>
|
||||
#include <utils/Logger.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QStringList>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace Process {
|
||||
|
||||
void restartHyperion(bool asNewProcess)
|
||||
{
|
||||
Logger* log = Logger::getInstance("Process");
|
||||
std::cout << std::endl
|
||||
<< " *******************************************" << std::endl
|
||||
<< " * hyperion will restart now *" << std::endl
|
||||
<< " *******************************************" << std::endl << std::endl;
|
||||
|
||||
|
||||
QStringList qargs = QCoreApplication::arguments();
|
||||
int size = qargs.size();
|
||||
char *args[size+1];
|
||||
args[size] = nullptr;
|
||||
for(int i=0; i<size; i++)
|
||||
{
|
||||
int str_size = qargs[i].toLocal8Bit().size();
|
||||
args[i] = new char[str_size+1];
|
||||
strncpy(args[i], qargs[i].toLocal8Bit().constData(),str_size );
|
||||
args[i][str_size] = '\0';
|
||||
}
|
||||
|
||||
execv(args[0],args);
|
||||
Error(log, "error while restarting hyperion");
|
||||
}
|
||||
|
||||
std::string command_exec(const char* cmd)
|
||||
{
|
||||
char buffer[128];
|
||||
std::string result = "";
|
||||
std::shared_ptr<FILE> pipe(popen(cmd, "r"), pclose);
|
||||
if (pipe)
|
||||
{
|
||||
while (!feof(pipe.get()))
|
||||
{
|
||||
if (fgets(buffer, 128, pipe.get()) != NULL)
|
||||
result += buffer;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
};
|
@ -6,6 +6,7 @@
|
||||
#include "CgiHandler.h"
|
||||
#include "QtHttpHeader.h"
|
||||
#include <utils/FileUtils.h>
|
||||
#include <utils/Process.h>
|
||||
|
||||
CgiHandler::CgiHandler (Hyperion * hyperion, QString baseUrl, QObject * parent)
|
||||
: QObject(parent)
|
||||
@ -96,7 +97,7 @@ void CgiHandler::cmd_runscript(const QStringList & args, QtHttpReply * reply)
|
||||
|
||||
if (QFile::exists(scriptFilePath) && !interpreter.isEmpty())
|
||||
{
|
||||
QByteArray data = FileUtils::command_exec(QString(interpreter + " " + scriptFilePath).toUtf8().constData()).c_str();
|
||||
QByteArray data = Process::command_exec(QString(interpreter + " " + scriptFilePath).toUtf8().constData()).c_str();
|
||||
|
||||
reply->addHeader ("Content-Type", "text/plain");
|
||||
reply->appendRawData (data);
|
||||
|
@ -6,12 +6,12 @@
|
||||
WebConfig::WebConfig(QObject * parent)
|
||||
: QObject(parent)
|
||||
, _hyperion(Hyperion::getInstance())
|
||||
, _port(WEBCONFIG_DEFAULT_PORT)
|
||||
, _server(nullptr)
|
||||
{
|
||||
_baseUrl = WEBCONFIG_DEFAULT_PATH;
|
||||
const Json::Value &config = _hyperion->getJsonConfig();
|
||||
Logger* log = Logger::getInstance("WEBSERVER");
|
||||
_port = WEBCONFIG_DEFAULT_PORT;
|
||||
_baseUrl = WEBCONFIG_DEFAULT_PATH;
|
||||
const Json::Value &config = _hyperion->getJsonConfig();
|
||||
|
||||
bool webconfigEnable = true;
|
||||
|
||||
@ -19,7 +19,7 @@ WebConfig::WebConfig(QObject * parent)
|
||||
{
|
||||
const Json::Value & webconfigConfig = config["webConfig"];
|
||||
webconfigEnable = webconfigConfig.get("enable", true).asBool();
|
||||
_port = webconfigConfig.get("port", WEBCONFIG_DEFAULT_PORT).asUInt();
|
||||
_port = webconfigConfig.get("port", _port).asUInt();
|
||||
_baseUrl = QString::fromStdString( webconfigConfig.get("document_root", _baseUrl.toStdString()).asString() );
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user