mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2025-03-01 10:33:28 +00:00
JsonUtils & improvements (#476)
* add JsonUtils * update * repair * update * ident * Schema correct msg other adjusts * fix effDel, ExceptionLog, cleanup * fix travis qt5.2 * not so funny * use Qthread interrupt instead abort bool * update services
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
|
||||
#include <utils/jsonschema/QJsonFactory.h>
|
||||
#include <utils/Components.h>
|
||||
#include <utils/JsonUtils.h>
|
||||
|
||||
#include <hyperion/Hyperion.h>
|
||||
#include <hyperion/PriorityMuxer.h>
|
||||
@@ -33,7 +34,9 @@
|
||||
|
||||
#include "hyperiond.h"
|
||||
|
||||
HyperionDaemon::HyperionDaemon(QString configFile, QObject *parent)
|
||||
#include <QDebug>
|
||||
|
||||
HyperionDaemon::HyperionDaemon(QString configFile, const QString rootPath, QObject *parent)
|
||||
: QObject(parent)
|
||||
, _log(Logger::getInstance("MAIN"))
|
||||
, _kodiVideoChecker(nullptr)
|
||||
@@ -73,7 +76,7 @@ HyperionDaemon::HyperionDaemon(QString configFile, QObject *parent)
|
||||
WarningIf(_qconfig.contains("logger"), Logger::getInstance("LOGGER"), "Logger settings overridden by command line argument");
|
||||
}
|
||||
|
||||
_hyperion = Hyperion::initInstance(_qconfig, configFile);
|
||||
_hyperion = Hyperion::initInstance(_qconfig, configFile, rootPath);
|
||||
|
||||
Info(_log, "Hyperion initialized");
|
||||
}
|
||||
@@ -145,11 +148,12 @@ void HyperionDaemon::loadConfig(const QString & configFile)
|
||||
Q_INIT_RESOURCE(resource);
|
||||
|
||||
// read the json schema from the resource
|
||||
|
||||
QString schemaFile = ":/hyperion-schema";
|
||||
QJsonObject schemaJson;
|
||||
try
|
||||
{
|
||||
//QJsonObject obj;
|
||||
//JsonUtils::readSchema(schemaFile, obj, _log);
|
||||
schemaJson = QJsonFactory::readSchema(schemaFile);
|
||||
}
|
||||
catch(const std::runtime_error& error)
|
||||
@@ -160,25 +164,31 @@ void HyperionDaemon::loadConfig(const QString & configFile)
|
||||
QJsonSchemaChecker schemaChecker;
|
||||
schemaChecker.setSchema(schemaJson);
|
||||
|
||||
_qconfig = QJsonFactory::readConfig(configFile);
|
||||
if(!JsonUtils::readFile(configFile, _qconfig, _log))
|
||||
throw std::runtime_error("Failed to load config!");
|
||||
|
||||
// validate config with schema and correct it if required
|
||||
QPair<bool, bool> validate = schemaChecker.validate(_qconfig);
|
||||
|
||||
if (!validate.first && validate.second)
|
||||
// errors in schema syntax, abort
|
||||
if (!validate.second)
|
||||
{
|
||||
Warning(_log,"Errors have been found in the configuration file. Automatic correction is applied");
|
||||
foreach (auto & schemaError, schemaChecker.getMessages())
|
||||
Error(_log, "Schema Syntax Error: %s", QSTRING_CSTR(schemaError));
|
||||
|
||||
throw std::runtime_error("ERROR: Hyperion schema has errors!");
|
||||
}
|
||||
// errors in configuration, correct it!
|
||||
if (!validate.first)
|
||||
{
|
||||
Warning(_log,"Errors have been found in the configuration file. Automatic correction has been applied");
|
||||
_qconfig = schemaChecker.getAutoCorrectedConfig(_qconfig);
|
||||
|
||||
if (!QJsonFactory::writeJson(configFile, _qconfig))
|
||||
throw std::runtime_error("ERROR: can not save configuration file, aborting ");
|
||||
}
|
||||
else if (validate.first && !validate.second) //Error in Schema
|
||||
{
|
||||
QStringList schemaErrors = schemaChecker.getMessages();
|
||||
foreach (auto & schemaError, schemaErrors)
|
||||
std::cout << schemaError.toStdString() << std::endl;
|
||||
foreach (auto & schemaError, schemaChecker.getMessages())
|
||||
Warning(_log, "Config Fix: %s", QSTRING_CSTR(schemaError));
|
||||
|
||||
throw std::runtime_error("ERROR: Json validation failed");
|
||||
if (!JsonUtils::write(configFile, _qconfig, _log))
|
||||
throw std::runtime_error("ERROR: Can't save configuration file, aborting");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -409,7 +419,7 @@ void HyperionDaemon::createSystemFrameGrabber()
|
||||
#else
|
||||
QString type = grabberConfig["type"].toString("auto");
|
||||
#endif
|
||||
|
||||
|
||||
// auto eval of type
|
||||
if ( type == "auto" )
|
||||
{
|
||||
|
@@ -58,7 +58,7 @@ class HyperionDaemon : public QObject
|
||||
friend SysTray;
|
||||
|
||||
public:
|
||||
HyperionDaemon(QString configFile, QObject *parent=nullptr);
|
||||
HyperionDaemon(QString configFile, QString rootPath, QObject *parent=nullptr);
|
||||
~HyperionDaemon();
|
||||
|
||||
void loadConfig(const QString & configFile);
|
||||
@@ -95,11 +95,11 @@ private:
|
||||
X11Wrapper* _x11Grabber;
|
||||
#endif
|
||||
AmlogicWrapper* _amlGrabber;
|
||||
FramebufferWrapper* _fbGrabber;
|
||||
FramebufferWrapper* _fbGrabber;
|
||||
OsxWrapper* _osxGrabber;
|
||||
Hyperion* _hyperion;
|
||||
Stats* _stats;
|
||||
|
||||
|
||||
unsigned _grabber_width;
|
||||
unsigned _grabber_height;
|
||||
unsigned _grabber_frequency;
|
||||
|
@@ -92,7 +92,7 @@ QCoreApplication* createApplication(int &argc, char *argv[])
|
||||
// if x11, then test if xserver is available
|
||||
#ifdef ENABLE_X11
|
||||
Display* dpy = XOpenDisplay(NULL);
|
||||
if (dpy != NULL)
|
||||
if (dpy != NULL)
|
||||
{
|
||||
XCloseDisplay(dpy);
|
||||
isGuiApp = true;
|
||||
@@ -140,6 +140,7 @@ int main(int argc, char** argv)
|
||||
parser.addHelpOption();
|
||||
|
||||
BooleanOption & versionOption = parser.add<BooleanOption>(0x0, "version", "Show version information");
|
||||
Option & rootPathOption = parser.add<Option> (0x0, "rootPath", "Overwrite root path for all hyperion user files, defaults to home directory of current user");
|
||||
IntOption & parentOption = parser.add<IntOption> ('p', "parent", "pid of parent hyperiond"); // 2^22 is the max for Linux
|
||||
BooleanOption & silentOption = parser.add<BooleanOption>('s', "silent", "do not print any outputs");
|
||||
BooleanOption & verboseOption = parser.add<BooleanOption>('v', "verbose", "Increase verbosity");
|
||||
@@ -207,7 +208,7 @@ int main(int argc, char** argv)
|
||||
{
|
||||
QFile::remove(destFileName);
|
||||
}
|
||||
|
||||
|
||||
std::cout << "Extract: " << filename.toStdString() << " ... ";
|
||||
if (QFile::copy(QString(":/effects/")+filename, destFileName))
|
||||
{
|
||||
@@ -227,21 +228,48 @@ int main(int argc, char** argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
// handle default config file
|
||||
if (configFiles.size() == 0)
|
||||
// handle rootPath for user data, default path is home directory + /.hyperion
|
||||
QString rootPath = QDir::homePath() + "/.hyperion";
|
||||
if (parser.isSet(rootPathOption))
|
||||
{
|
||||
QString hyperiond_path = QDir::homePath();
|
||||
QString hyperiond_config = hyperiond_path+"/.hyperion.config.json";
|
||||
QFileInfo hyperiond_pathinfo(hyperiond_path);
|
||||
|
||||
if ( ! hyperiond_pathinfo.isWritable() && ! QFile::exists(hyperiond_config) )
|
||||
QDir rDir(rootPathOption.value(parser));
|
||||
if(!rDir.mkpath(rootPathOption.value(parser)))
|
||||
{
|
||||
QFileInfo hyperiond_fileinfo(argv[0]);
|
||||
hyperiond_config = hyperiond_fileinfo.absolutePath()+"/hyperion.config.json";
|
||||
Error(log, "Can't create root path '%s', falling back to home directory", QSTRING_CSTR(rDir.absolutePath()));
|
||||
}
|
||||
else
|
||||
{
|
||||
rootPath = rDir.absolutePath();
|
||||
}
|
||||
}
|
||||
// create /.hyperion folder for default path, check if the directory is read/writeable
|
||||
// Note: No further checks inside Hyperion. FileUtils::writeFile() will resolve permission errors and others that occur during runtime
|
||||
QDir mDir(rootPath);
|
||||
QFileInfo mFi(rootPath);
|
||||
if(!mDir.mkpath(rootPath) || !mFi.isWritable() || !mDir.isReadable())
|
||||
{
|
||||
throw std::runtime_error("The specified root path can't be created or isn't read/writeable. Please setup the permissions correctly!");
|
||||
}
|
||||
|
||||
configFiles.append(hyperiond_config);
|
||||
Info(log, "No config file given. Standard config file used: %s", QSTRING_CSTR(configFiles[0]));
|
||||
// determine name of config file, defaults to hyperion_main.json
|
||||
// create config folder
|
||||
QString cPath(rootPath+"/config");
|
||||
QDir().mkpath(rootPath+"/config");
|
||||
if (configFiles.size() > 0)
|
||||
{
|
||||
// use argument config file
|
||||
// check if file has a path and ends with .json
|
||||
if(configFiles[0].contains("/"))
|
||||
throw std::runtime_error("Don't provide a path to config file, just a config name is allowed!");
|
||||
if(!configFiles[0].endsWith(".json"))
|
||||
configFiles[0].append(".json");
|
||||
|
||||
configFiles.prepend(cPath+"/"+configFiles[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// use default config file
|
||||
configFiles.append(cPath+"/hyperion_main.json");
|
||||
}
|
||||
|
||||
bool exportDefaultConfig = false;
|
||||
@@ -257,7 +285,7 @@ int main(int argc, char** argv)
|
||||
{
|
||||
exportDefaultConfig = true;
|
||||
exportConfigFileTarget = configFiles[0];
|
||||
Warning(log, "Your configuration file does not exist. hyperion writes default config");
|
||||
Warning(log, "Create new config file (%s)",QSTRING_CSTR(configFiles[0]));
|
||||
}
|
||||
|
||||
if (exportDefaultConfig)
|
||||
@@ -277,11 +305,6 @@ int main(int argc, char** argv)
|
||||
}
|
||||
}
|
||||
|
||||
if (configFiles.size() > 1)
|
||||
{
|
||||
Warning(log, "You provided more than one config file. Hyperion will use only the first one");
|
||||
}
|
||||
|
||||
int parentPid = parser.value(parentOption).toInt();
|
||||
if (parentPid > 0 )
|
||||
{
|
||||
@@ -295,7 +318,7 @@ int main(int argc, char** argv)
|
||||
HyperionDaemon* hyperiond = nullptr;
|
||||
try
|
||||
{
|
||||
hyperiond = new HyperionDaemon(configFiles[0], qApp);
|
||||
hyperiond = new HyperionDaemon(configFiles[0], rootPath, qApp);
|
||||
hyperiond->run();
|
||||
}
|
||||
catch (std::exception& e)
|
||||
|
Reference in New Issue
Block a user