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:
brindosch
2017-10-12 11:55:03 +02:00
committed by GitHub
parent 47641012ee
commit 838008568a
42 changed files with 940 additions and 701 deletions

View File

@@ -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" )
{

View File

@@ -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;

View File

@@ -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)