From e2ca9bcaa518abded5696a3e7e13ecf12abb823e Mon Sep 17 00:00:00 2001 From: brindosch Date: Mon, 29 May 2017 15:59:11 +0200 Subject: [PATCH] Stats Testing time! Also new: Effects dirs are now created automatically --- include/hyperion/Hyperion.h | 2 + include/utils/Stats.h | 34 ++++++ libsrc/effectengine/EffectEngine.cpp | 13 ++- libsrc/utils/CMakeLists.txt | 2 + libsrc/utils/Stats.cpp | 155 +++++++++++++++++++++++++++ src/hyperiond/hyperiond.cpp | 6 ++ src/hyperiond/hyperiond.h | 2 + 7 files changed, 213 insertions(+), 1 deletion(-) create mode 100644 include/utils/Stats.h create mode 100644 libsrc/utils/Stats.cpp diff --git a/include/hyperion/Hyperion.h b/include/hyperion/Hyperion.h index 82cad3f1..94154f80 100644 --- a/include/hyperion/Hyperion.h +++ b/include/hyperion/Hyperion.h @@ -178,6 +178,8 @@ public: int getLedMappingType() { return _ledMAppingType; }; int getConfigVersionId() { return _configVersionId; }; + + QJsonObject getConfig() { return _qjsonConfig; }; int getLatchTime() const; diff --git a/include/utils/Stats.h b/include/utils/Stats.h new file mode 100644 index 00000000..193c8986 --- /dev/null +++ b/include/utils/Stats.h @@ -0,0 +1,34 @@ +// qt includes +#include +#include +#include +#include +#include +#include +#include +#include + +// hyperion includes +#include + +class Stats : public QObject +{ + Q_OBJECT + +public: + Stats(); + ~Stats(); + +private: + Logger* _log; + QString _hash = ""; + QNetworkAccessManager _mgr; + + bool trigger(bool set = false); + +private slots: + void sendHTTP(bool put = false); + void resolveReply(QNetworkReply *reply); + + +}; diff --git a/libsrc/effectengine/EffectEngine.cpp b/libsrc/effectengine/EffectEngine.cpp index a84dd9fa..7f575a7e 100644 --- a/libsrc/effectengine/EffectEngine.cpp +++ b/libsrc/effectengine/EffectEngine.cpp @@ -282,7 +282,18 @@ void EffectEngine::readEffects() foreach (const QString & path, efxPathList ) { QDir directory(path); - if (directory.exists()) + if (!directory.exists()) + { + if(directory.mkpath(path)) + { + Warning(_log, "New Effect path \"%s\" created successfull",path.toUtf8().constData() ); + } + else + { + Warning(_log, "Failed to create Effect path \"%s\", please check permissions",path.toUtf8().constData() ); + } + } + if (directory.exists(path)) { int efxCount = 0; QStringList filenames = directory.entryList(QStringList() << "*.json", QDir::Files, QDir::Name | QDir::IgnoreCase); diff --git a/libsrc/utils/CMakeLists.txt b/libsrc/utils/CMakeLists.txt index 72ce2ecd..d1a4b365 100644 --- a/libsrc/utils/CMakeLists.txt +++ b/libsrc/utils/CMakeLists.txt @@ -5,6 +5,7 @@ SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/utils) SET(Utils_QT_HEADERS ${CURRENT_HEADER_DIR}/Logger.h + ${CURRENT_HEADER_DIR}/Stats.h ) SET(Utils_HEADERS @@ -44,6 +45,7 @@ SET(Utils_SOURCES ${CURRENT_SOURCE_DIR}/RgbTransform.cpp ${CURRENT_SOURCE_DIR}/RgbToRgbw.cpp ${CURRENT_SOURCE_DIR}/SysInfo.cpp + ${CURRENT_SOURCE_DIR}/Stats.cpp ${CURRENT_SOURCE_DIR}/jsonschema/QJsonSchemaChecker.cpp ) diff --git a/libsrc/utils/Stats.cpp b/libsrc/utils/Stats.cpp new file mode 100644 index 00000000..356cd44a --- /dev/null +++ b/libsrc/utils/Stats.cpp @@ -0,0 +1,155 @@ +#include +#include +#include +#include +#include + +// qt includes +#include +#include +#include +#include +#include +#include +#include +#include + +Stats::Stats() + : QObject() + , _log(Logger::getInstance("STATS")) +{ + // generate hash + QString hash; + foreach(QNetworkInterface interface, QNetworkInterface::allInterfaces()) + { + if (!(interface.flags() & QNetworkInterface::IsLoopBack)) + { + _hash = QString(QCryptographicHash::hash(interface.hardwareAddress().toLocal8Bit(),QCryptographicHash::Sha1).toHex()); + break; + } + } + + // stop reporting if not found + if(_hash.isEmpty()) + { + Warning(_log, "No interface found, abort"); + return; + } + + connect(&_mgr, SIGNAL(finished(QNetworkReply*)), this, SLOT(resolveReply(QNetworkReply*))); + + // 7 days interval + QTimer *timer = new QTimer(this); + connect(timer, SIGNAL(timeout()), this, SLOT(sendHTTP())); + timer->start(604800000); + + // check instant execution required + if(trigger()) + { + QTimer::singleShot(0, this, [=]() { + sendHTTP(); + }); + } +} + +Stats::~Stats() +{ + +} + +void Stats::sendHTTP(bool put) +{ + QJsonObject config = Hyperion::getInstance()->getConfig(); + SysInfo::HyperionSysInfo data = SysInfo::get(); + + QJsonObject system; + system["kType" ] = data.kernelType; + //system["kernelVersion" ] = data.kernelVersion; + system["arch" ] = data.architecture; + system["pType" ] = data.productType; + system["pVersion" ] = data.productVersion; + system["pName" ] = data.prettyName; + system["version" ] = QString(HYPERION_VERSION); + system["device" ] = LedDevice::activeDevice(); + system["id" ] = _hash; + system["ledCount" ] = QString::number(Hyperion::getInstance()->getLedCount()); + system["comp_sm" ] = config["smoothing"].toObject().take("enable"); + system["comp_bb" ] = config["blackborderdetector"].toObject().take("enable"); + system["comp_fw" ] = config["forwarder"].toObject().take("enable"); + system["comp_udpl" ] = config["udpListener"].toObject().take("enable"); + system["comp_bobl" ] = config["boblightServer"].toObject().take("enable"); + system["comp_pc" ] = config["framegrabber"].toObject().take("enable"); + system["comp_uc" ] = config["grabberV4L2"].toArray().at(0).toObject().take("enable"); + + QJsonDocument doc(system); + QByteArray ba = doc.toJson(); + + QNetworkRequest req; + req.setRawHeader("Content-Type", "application/json"); + req.setRawHeader("Authorization", "Basic SHlwZXJpb25YbDQ5MlZrcXA6ZDQxZDhjZDk4ZjAwYjIw"); + + if(put) + { + req.setUrl(QUrl("https://api.hyperion-project.org/api/stats/"+_hash)); + _mgr.put(req,ba); + } + else + { + req.setUrl(QUrl("https://api.hyperion-project.org/api/stats")); + _mgr.post(req,ba); + } +} + +void Stats::resolveReply(QNetworkReply *reply) +{ + if (reply->error() == QNetworkReply::NoError) + { + // update file timestamp + trigger(true); + // already created, update entry + if(reply->readAll().startsWith("null")) + { + //bool put = true; + QTimer::singleShot(0, this, [=]() { + sendHTTP(true); + }); + } + } +} + +bool Stats::trigger(bool set) +{ + QString path = QDir::homePath()+"/.hyperion/misc/"; + QDir dir; + QFile file(path + "ts"); + + if(set && file.open(QIODevice::ReadWrite) ) + { + QTextStream stream( &file ); + stream << "DO NOT DELETE" << endl; + file.close(); + } + else + { + if(!dir.exists(path)) + { + dir.mkpath(path); + } + if (!file.exists()) + { + if(file.open(QIODevice::ReadWrite)) + { + file.close(); + return true; + } + return true; + } + + QFileInfo info(file); + QDateTime newDate = QDateTime::currentDateTime(); + QDateTime oldDate = info.lastModified(); + int diff = oldDate.daysTo(newDate); + return diff >= 7 ? true : false; + } + return false; +} diff --git a/src/hyperiond/hyperiond.cpp b/src/hyperiond/hyperiond.cpp index 172f7c9b..981de254 100644 --- a/src/hyperiond/hyperiond.cpp +++ b/src/hyperiond/hyperiond.cpp @@ -50,6 +50,7 @@ HyperionDaemon::HyperionDaemon(QString configFile, QObject *parent) , _fbGrabber(nullptr) , _osxGrabber(nullptr) , _hyperion(nullptr) + , _stats(nullptr) { loadConfig(configFile, CURRENT_CONFIG_VERSION ); @@ -99,6 +100,7 @@ void HyperionDaemon::freeObjects() delete _protoServer; delete _boblightServer; delete _udpListener; + delete _stats; _v4l2Grabbers.clear(); _amlGrabber = nullptr; @@ -110,6 +112,7 @@ void HyperionDaemon::freeObjects() _protoServer = nullptr; _boblightServer = nullptr; _udpListener = nullptr; + _stats = nullptr; } void HyperionDaemon::run() @@ -302,6 +305,9 @@ void HyperionDaemon::startNetworkServices() { KODIVideoChecker* kodiVideoChecker = KODIVideoChecker::getInstance(); + // Create Stats + _stats = new Stats(); + // Create Json server if configuration is present unsigned int jsonPort = 19444; if (_qconfig.contains("jsonServer")) diff --git a/src/hyperiond/hyperiond.h b/src/hyperiond/hyperiond.h index a1f3acd7..762af51d 100644 --- a/src/hyperiond/hyperiond.h +++ b/src/hyperiond/hyperiond.h @@ -45,6 +45,7 @@ #include #include #include +#include #include class HyperionDaemon : public QObject @@ -92,6 +93,7 @@ private: FramebufferWrapper* _fbGrabber; OsxWrapper* _osxGrabber; Hyperion* _hyperion; + Stats* _stats; unsigned _grabber_width; unsigned _grabber_height;