mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2025-03-01 10:33:28 +00:00
refactoring of webui and event based websocket layer (#219)
* make hyperion websocket api event based * implement new websocket handling for generalconf * migrate all webui stuff to new event based websocket api some cleanup ... now all html templates are in content refactoring of web stuff * add hyperionport to global start impl. removing advanced key * separate dashboard serverinfo is updated every 3 seconds automatily add input selection cleanup and remove not needed stuff * prepare infrastructure for server sided file execution * webui minor fixes * fix compile
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
|
||||
// hyperion util includes
|
||||
#include <utils/jsonschema/JsonSchemaChecker.h>
|
||||
#include <utils/FileUtils.h>
|
||||
|
||||
// effect engine includes
|
||||
#include <effectengine/EffectEngine.h>
|
||||
@@ -181,7 +182,7 @@ int EffectEngine::runEffectScript(const std::string &script, const Json::Value &
|
||||
_activeEffects.push_back(effect);
|
||||
|
||||
// start the effect
|
||||
_hyperion->registerPriority("EFFECT: "+script, priority);
|
||||
_hyperion->registerPriority("EFFECT: "+FileUtils::getBaseName(script), priority);
|
||||
effect->start();
|
||||
|
||||
return 0;
|
||||
|
@@ -684,6 +684,30 @@
|
||||
"maximum" : 1.0,
|
||||
"default" : 0.05
|
||||
},
|
||||
"unknownFrameCnt" :
|
||||
{
|
||||
"type" : "number",
|
||||
"minimum" : 0,
|
||||
"advanced" : true
|
||||
},
|
||||
"borderFrameCnt" :
|
||||
{
|
||||
"type" : "number",
|
||||
"minimum" : 0,
|
||||
"advanced" : true
|
||||
},
|
||||
"maxInconsistentCnt" :
|
||||
{
|
||||
"type" : "number",
|
||||
"minimum" : 0,
|
||||
"advanced" : true
|
||||
},
|
||||
"blurRemoveCnt" :
|
||||
{
|
||||
"type" : "number",
|
||||
"minimum" : 0,
|
||||
"advanced" : true
|
||||
},
|
||||
"mode" :
|
||||
{
|
||||
"type" : "string",
|
||||
|
@@ -852,21 +852,22 @@ void JsonClientConnection::handleSourceSelectCommand(const Json::Value & message
|
||||
void JsonClientConnection::handleConfigCommand(const Json::Value & message, const std::string &command, const int tan)
|
||||
{
|
||||
std::string subcommand = message.get("subcommand","").asString();
|
||||
std::string full_command = command + "-" + subcommand;
|
||||
if (subcommand == "getschema")
|
||||
{
|
||||
handleSchemaGetCommand(message, command, tan);
|
||||
handleSchemaGetCommand(message, full_command, tan);
|
||||
}
|
||||
else if (subcommand == "getconfig")
|
||||
{
|
||||
handleConfigGetCommand(message, command, tan);
|
||||
handleConfigGetCommand(message, full_command, tan);
|
||||
}
|
||||
else if (subcommand == "setconfig")
|
||||
{
|
||||
handleConfigSetCommand(message, command, tan);
|
||||
handleConfigSetCommand(message, full_command, tan);
|
||||
}
|
||||
else
|
||||
{
|
||||
sendErrorReply("unknown or missing subcommand", command, tan);
|
||||
sendErrorReply("unknown or missing subcommand", full_command, tan);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -19,6 +19,8 @@ add_library(hyperion-utils
|
||||
${CURRENT_SOURCE_DIR}/ColorRgbw.cpp
|
||||
${CURRENT_HEADER_DIR}/Image.h
|
||||
${CURRENT_HEADER_DIR}/Sleep.h
|
||||
${CURRENT_HEADER_DIR}/FileUtils.h
|
||||
${CURRENT_SOURCE_DIR}/FileUtils.cpp
|
||||
|
||||
${CURRENT_HEADER_DIR}/Logger.h
|
||||
${CURRENT_SOURCE_DIR}/Logger.cpp
|
||||
|
35
libsrc/utils/FileUtils.cpp
Normal file
35
libsrc/utils/FileUtils.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
#include <utils/FileUtils.h>
|
||||
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <QFileInfo>
|
||||
|
||||
namespace FileUtils {
|
||||
|
||||
std::string getBaseName( std::string sourceFile)
|
||||
{
|
||||
QFileInfo fi( sourceFile.c_str() );
|
||||
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;
|
||||
}
|
||||
|
||||
};
|
@@ -1,4 +1,5 @@
|
||||
#include "utils/Logger.h"
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/FileUtils.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
@@ -7,11 +8,6 @@
|
||||
#include <QFileInfo>
|
||||
#include <QString>
|
||||
|
||||
std::string getBaseName( std::string sourceFile)
|
||||
{
|
||||
QFileInfo fi( sourceFile.c_str() );
|
||||
return fi.fileName().toStdString();
|
||||
}
|
||||
|
||||
static const char * LogLevelStrings[] = { "", "DEBUG", "INFO", "WARNING", "ERROR" };
|
||||
static const int LogLevelSysLog[] = { LOG_DEBUG, LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERR };
|
||||
@@ -134,7 +130,7 @@ void Logger::Message(LogLevel level, const char* sourceFile, const char* func, u
|
||||
std::string function(func);
|
||||
if ( level == Logger::DEBUG )
|
||||
{
|
||||
location = "<" + getBaseName(sourceFile) + ":" + QString::number(line).toStdString()+":"+ function + "()> ";
|
||||
location = "<" + FileUtils::getBaseName(sourceFile) + ":" + QString::number(line).toStdString()+":"+ function + "()> ";
|
||||
}
|
||||
|
||||
std::cout
|
||||
|
@@ -1,5 +1,6 @@
|
||||
#include "HyperionConfig.h"
|
||||
#include "utils/Profiler.h"
|
||||
#include <utils/Profiler.h>
|
||||
#include <utils/FileUtils.h>
|
||||
|
||||
#include <QFileInfo>
|
||||
#include <QString>
|
||||
@@ -15,21 +16,11 @@ static unsigned int blockCounter = 0;
|
||||
static std::map<std::string,StopWatchItem> GlobalProfilerMap;
|
||||
Logger* Profiler::_logger = nullptr;
|
||||
|
||||
|
||||
|
||||
std::string profiler_getBaseName( std::string sourceFile)
|
||||
{
|
||||
QFileInfo fi( sourceFile.c_str() );
|
||||
return fi.fileName().toStdString();
|
||||
}
|
||||
|
||||
double getClockDelta(clock_t start)
|
||||
{
|
||||
return ((double)(clock() - start) / CLOCKS_PER_SEC) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Profiler::Profiler(const char* sourceFile, const char* func, unsigned int line) :
|
||||
_file(sourceFile),
|
||||
_func(func),
|
||||
@@ -71,7 +62,7 @@ void Profiler::TimerStart(const std::string timerName, const char* sourceFile, c
|
||||
else
|
||||
{
|
||||
_logger->Message(Logger::DEBUG, sourceFile, func, line, "ERROR timer '%s' started in multiple locations. First occurence %s:%d:%s()",
|
||||
timerName.c_str(), profiler_getBaseName(ret.first->second.sourceFile).c_str(), ret.first->second.line, ret.first->second.func );
|
||||
timerName.c_str(), FileUtils::getBaseName(ret.first->second.sourceFile).c_str(), ret.first->second.line, ret.first->second.func );
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -88,7 +79,7 @@ void Profiler::TimerGetTime(const std::string timerName, const char* sourceFile,
|
||||
if (ret != GlobalProfilerMap.end())
|
||||
{
|
||||
_logger->Message(Logger::DEBUG, sourceFile, func, line, "timer '%s' started at %s:%d:%s() took %f s execution time until here", timerName.c_str(),
|
||||
profiler_getBaseName(ret->second.sourceFile).c_str(), ret->second.line, ret->second.func, getClockDelta(ret->second.startTime) );
|
||||
FileUtils::getBaseName(ret->second.sourceFile).c_str(), ret->second.line, ret->second.func, getClockDelta(ret->second.startTime) );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -108,7 +108,7 @@ void QJsonSchemaChecker::validate(const QJsonValue & value, const QJsonObject &s
|
||||
; // nothing to do. value is present so always oke
|
||||
else if (attribute == "id")
|
||||
; // references have already been collected
|
||||
else if (attribute == "title" || attribute == "description" || attribute == "default" || attribute == "format")
|
||||
else if (attribute == "title" || attribute == "description" || attribute == "default" || attribute == "format" || attribute == "advanced")
|
||||
; // nothing to do.
|
||||
else
|
||||
{
|
||||
|
@@ -5,11 +5,13 @@
|
||||
|
||||
#include "CgiHandler.h"
|
||||
#include "QtHttpHeader.h"
|
||||
#include <utils/FileUtils.h>
|
||||
|
||||
CgiHandler::CgiHandler (Hyperion * hyperion, QObject * parent)
|
||||
CgiHandler::CgiHandler (Hyperion * hyperion, QString baseUrl, QObject * parent)
|
||||
: QObject(parent)
|
||||
, _hyperion(hyperion)
|
||||
, _hyperionConfig(_hyperion->getJsonConfig())
|
||||
, _baseUrl(baseUrl)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -26,6 +28,7 @@ void CgiHandler::exec(const QStringList & args, QtHttpRequest * request, QtHttpR
|
||||
|
||||
cmd_cfg_jsonserver(args,reply);
|
||||
cmd_cfg_hyperion(args,reply);
|
||||
cmd_runscript(args,reply);
|
||||
throw 1;
|
||||
}
|
||||
catch(int e)
|
||||
@@ -71,3 +74,34 @@ void CgiHandler::cmd_cfg_hyperion(const QStringList & args, QtHttpReply * reply)
|
||||
throw 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CgiHandler::cmd_runscript(const QStringList & args, QtHttpReply * reply)
|
||||
{
|
||||
if ( args.at(0) == "run" )
|
||||
{
|
||||
QStringList scriptFilePathList(args);
|
||||
scriptFilePathList.removeAt(0);
|
||||
|
||||
QString scriptFilePath = scriptFilePathList.join('/');
|
||||
// relative path not allowed
|
||||
if (scriptFilePath.indexOf("..") >=0)
|
||||
{
|
||||
throw 1;
|
||||
}
|
||||
|
||||
scriptFilePath = _baseUrl+"/server_scripts/"+scriptFilePath;
|
||||
QString interpreter = "";
|
||||
if (scriptFilePath.endsWith(".sh")) interpreter = "sh";
|
||||
if (scriptFilePath.endsWith(".py")) interpreter = "python";
|
||||
|
||||
if (QFile::exists(scriptFilePath) && !interpreter.isEmpty())
|
||||
{
|
||||
QByteArray data = FileUtils::command_exec(QString(interpreter + " " + scriptFilePath).toUtf8().constData()).c_str();
|
||||
|
||||
reply->addHeader ("Content-Type", "text/plain");
|
||||
reply->appendRawData (data);
|
||||
throw 0;
|
||||
}
|
||||
throw 1;
|
||||
}
|
||||
}
|
||||
|
@@ -15,7 +15,7 @@ class CgiHandler : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CgiHandler (Hyperion * hyperion, QObject * parent = NULL);
|
||||
CgiHandler (Hyperion * hyperion, QString baseUrl, QObject * parent = NULL);
|
||||
virtual ~CgiHandler (void);
|
||||
|
||||
void exec(const QStringList & args,QtHttpRequest * request, QtHttpReply * reply);
|
||||
@@ -23,11 +23,13 @@ public:
|
||||
// cgi commands
|
||||
void cmd_cfg_jsonserver(const QStringList & args, QtHttpReply * reply);
|
||||
void cmd_cfg_hyperion (const QStringList & args, QtHttpReply * reply);
|
||||
void cmd_runscript (const QStringList & args, QtHttpReply * reply);
|
||||
|
||||
private:
|
||||
Hyperion* _hyperion;
|
||||
QtHttpReply * _reply;
|
||||
const Json::Value &_hyperionConfig;
|
||||
const QString _baseUrl;
|
||||
};
|
||||
|
||||
#endif // CGIHANDLER_H
|
||||
|
@@ -12,7 +12,7 @@ StaticFileServing::StaticFileServing (Hyperion *hyperion, QString baseUrl, quint
|
||||
: QObject (parent)
|
||||
, _hyperion(hyperion)
|
||||
, _baseUrl (baseUrl)
|
||||
, _cgi(hyperion, this)
|
||||
, _cgi(hyperion, baseUrl, this)
|
||||
, _log(Logger::getInstance("WEBSERVER"))
|
||||
{
|
||||
_mimeDb = new QMimeDatabase;
|
||||
@@ -71,7 +71,7 @@ void StaticFileServing::onRequestNeedsReply (QtHttpRequest * request, QtHttpRepl
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
printErrorToReply (reply, "cgi script failed (" % path % ")");
|
||||
printErrorToReply (reply, "script failed (" % path % ")");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@@ -33,7 +33,7 @@ private:
|
||||
QtHttpServer * _server;
|
||||
QMimeDatabase * _mimeDb;
|
||||
CgiHandler _cgi;
|
||||
Logger * _log;
|
||||
Logger * _log;
|
||||
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user