2017-10-12 11:55:03 +02:00
//project include
# include <utils/JsonUtils.h>
// util includes
# include <utils/jsonschema/QJsonSchemaChecker.h>
//qt includes
# include <QRegularExpression>
# include <QJsonObject>
# include <QJsonParseError>
namespace JsonUtils {
bool readFile ( const QString & path , QJsonObject & obj , Logger * log , bool ignError )
{
QString data ;
if ( ! FileUtils : : readFile ( path , data , log , ignError ) )
return false ;
if ( ! parse ( path , data , obj , log ) )
return false ;
return true ;
}
bool readSchema ( const QString & path , QJsonObject & obj , Logger * log )
{
QJsonObject schema ;
if ( ! readFile ( path , schema , log ) )
return false ;
if ( ! resolveRefs ( schema , obj , log ) )
return false ;
return true ;
}
bool parse ( const QString & path , const QString & data , QJsonObject & obj , Logger * log )
2018-12-27 23:11:32 +01:00
{
QJsonDocument doc ;
if ( ! parse ( path , data , doc , log ) )
return false ;
obj = doc . object ( ) ;
return true ;
}
bool parse ( const QString & path , const QString & data , QJsonArray & arr , Logger * log )
{
QJsonDocument doc ;
if ( ! parse ( path , data , doc , log ) )
return false ;
arr = doc . array ( ) ;
return true ;
}
bool parse ( const QString & path , const QString & data , QJsonDocument & doc , Logger * log )
2017-10-12 11:55:03 +02:00
{
//remove Comments in data
QString cleanData = data ;
QJsonParseError error ;
2018-12-27 23:11:32 +01:00
doc = QJsonDocument : : fromJson ( cleanData . toUtf8 ( ) , & error ) ;
2017-10-12 11:55:03 +02:00
if ( error . error ! = QJsonParseError : : NoError )
{
// report to the user the failure and their locations in the document.
int errorLine ( 0 ) , errorColumn ( 0 ) ;
for ( int i = 0 , count = qMin ( error . offset , cleanData . size ( ) ) ; i < count ; + + i )
{
+ + errorColumn ;
if ( data . at ( i ) = = ' \n ' )
{
errorColumn = 0 ;
+ + errorLine ;
}
}
mDNS Support (#1452)
* Allow build, if no grabbers are enabled
* Align available functions to right Qt version
* Update to next development version
* Align available functions to right Qt version
* fix workflows (apt/nightly)
* Disable QNetworkConfigurationManager deprecation warnings
* Initial go on Smart Pointers
* Add Deallocation
* Correct QT_WARNING_DISABLE_DEPRECATED (available since 5.9)
* Cluster Build Variables
* Hyperion Light
* Address build warnings
* Hyperion Light - UI
* Update Protobuf to latest master
* Removed compiler warnings
* Added restart ability to systray
* Correct Protobuf
* Ignore 'no-return' warning on protobuf build
* hyperion-remote: Fix auto discovery of hyperion server
* Fix Qt version override
* Update changelog
* Remove Grabber Components, if no Grabber exists
* Standalone Grabber - Fix fps default
* Remote Control - Have Source Selction accrosswhole screen
* Enable Blackborder detection only, if relevant input sources available
* Enable Blackborder detection only, if relevant input sources available
* Remote UI - rearrange containers
* Checkout
* Fix compilation on windows
* Re-added qmdnsengine template cmake
* chrono added for linux
* Removed existing AVAHI/Bonjour, allow to enable/disable mDNS
* hyperiond macos typo fix
* Fix macOS Bundle build
* Fix macOS bundle info details
* Correct CMake files
* Removed existing AVAHI/Bonjour (2)
* Share hyperion's services via mDNS
* Add mDNS Browser and mDNS for LED-Devices
* Support mDNS discovery for standalone grabbers
* Remove ZLib Dependency & Cleanup
* mDNS - hanle 2.local2 an ".local." domains equally
* Hue - Link discovery to bridge class, workaround port 443 for mDNS discovery
* Fix save button state when switching between devices
* Removed sessions (of other hyperions)
* mDNS Publisher - Simplify service naming
* mDNS refactoring & Forwarder discovery
* mDNS Updates to use device service name
* Consistency of standalone grabbers with mDNS Service Registry
* Merge branch 'hyperion-project:master' into mDNS
* Start JSON and WebServers only after Instance 0 is available
* Remove bespoke qDebug Output again
* MDNS updates and refactor Forwarder
* Minor updates
* Upgrade to CMake 3.1
* typo
* macOS fix
* Correct merge
* - Remove dynamic linker flag from standalone dispmanX Grabber
- Added ability to use system qmdns libs
* Cec handler library will load at runtime
* typo fix
* protobuf changes
* mDNS changes for Windows/macOS
* test window build qmdnsengine
* absolute path to protobuf cmake dir
* Rework Hue Wizard supporting mDNS
* LED-Devices - Retry support + Refactoring (excl. Hue)
* LED-Devices - Refactoring/Retry support Hue + additional alignments
* Address LGTM findings
* Fix CI-Build, revert test changes
* Build Windows in Release mode to avoid python problem
* Correct that WebServerObject is available earlier
* Ensure that instance name in logs for one instance are presented
* Update content LEDs
* Rework mDNS Address lookup
* Fix LED UI
* Fix for non mDNS Services (ignore default port)
* Disbale device when now input is available
* Revert back some updates, ensure last color is updated when switched on
* Handle reopening case and changed IP, port for API-calls
* Add UPD-DDP Device
* WLED support for DDP
* Fix printout
* LEDDevice - Allow more retries, udapte defaults
* LED-Net Devices - Select Custom device, if configured
Co-authored-by: Paulchen Panther <16664240+Paulchen-Panther@users.noreply.github.com>
Co-authored-by: Paulchen Panther <Paulchen-Panter@protonmail.com>
2022-05-01 19:42:47 +02:00
Error ( log , " Failed to parse json data from %s: Error: %s at Line: %i, Column: %i, Data: '%s' " , QSTRING_CSTR ( path ) , QSTRING_CSTR ( error . errorString ( ) ) , errorLine , errorColumn , QSTRING_CSTR ( data ) ) ;
2017-10-12 11:55:03 +02:00
return false ;
}
return true ;
}
bool validate ( const QString & file , const QJsonObject & json , const QString & schemaPath , Logger * log )
{
// get the schema data
QJsonObject schema ;
if ( ! readFile ( schemaPath , schema , log ) )
return false ;
2018-12-27 23:11:32 +01:00
if ( ! validate ( file , json , schema , log ) )
return false ;
return true ;
}
bool validate ( const QString & file , const QJsonObject & json , const QJsonObject & schema , Logger * log )
{
2017-10-12 11:55:03 +02:00
QJsonSchemaChecker schemaChecker ;
schemaChecker . setSchema ( schema ) ;
if ( ! schemaChecker . validate ( json ) . first )
{
const QStringList & errors = schemaChecker . getMessages ( ) ;
for ( auto & error : errors )
{
Error ( log , " While validating schema against json data of '%s':%s " , QSTRING_CSTR ( file ) , QSTRING_CSTR ( error ) ) ;
}
return false ;
}
return true ;
}
bool write ( const QString & filename , const QJsonObject & json , Logger * log )
{
QJsonDocument doc ;
doc . setObject ( json ) ;
QByteArray data = doc . toJson ( QJsonDocument : : Indented ) ;
if ( ! FileUtils : : writeFile ( filename , data , log ) )
return false ;
return true ;
}
bool resolveRefs ( const QJsonObject & schema , QJsonObject & obj , Logger * log )
{
for ( QJsonObject : : const_iterator i = schema . begin ( ) ; i ! = schema . end ( ) ; + + i )
{
QString attribute = i . key ( ) ;
const QJsonValue & attributeValue = * i ;
if ( attribute = = " $ref " & & attributeValue . isString ( ) )
{
if ( ! readSchema ( " :/ " + attributeValue . toString ( ) , obj , log ) )
{
Error ( log , " Error while getting schema ref: %s " , QSTRING_CSTR ( QString ( " :/ " + attributeValue . toString ( ) ) ) ) ;
return false ;
}
}
else if ( attributeValue . isObject ( ) )
obj . insert ( attribute , resolveRefs ( attributeValue . toObject ( ) , obj , log ) ) ;
else
{
obj . insert ( attribute , attributeValue ) ;
}
}
return true ;
}
} ;