mirror of
				https://github.com/hyperion-project/hyperion.ng.git
				synced 2025-03-01 10:33:28 +00:00 
			
		
		
		
	* Razor Chroma Support - Initial version
* Address clang and lgtm findings
* Razer Fixes
* Merge branch 'master' into Razer_Chroma_Support
# Conflicts:
#	assets/webconfig/i18n/en.json
#	assets/webconfig/js/content_leds.js
#	libsrc/leddevice/dev_net/ProviderRestApi.cpp
#	libsrc/leddevice/dev_net/ProviderRestApi.h
* Corrections
* Set default config for Razer
* Simplify
* Razer - Support individual LEDs and have default layout per device type
* Differentiate between HWLEDCount and LayoutLEDCount
* Revert "Differentiate between HWLEDCount and LayoutLEDCount"
This reverts commit b147b215a5.
* Correct LGTM finding
* Disable verbose mode
		
	
		
			
				
	
	
		
			321 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			321 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #ifndef PROVIDERRESTKAPI_H
 | |
| #define PROVIDERRESTKAPI_H
 | |
| 
 | |
| // Local-Hyperion includes
 | |
| #include <utils/Logger.h>
 | |
| 
 | |
| // Qt includes
 | |
| #include <QNetworkAccessManager>
 | |
| #include <QNetworkReply>
 | |
| #include <QUrlQuery>
 | |
| #include <QJsonDocument>
 | |
| 
 | |
| #include <QBasicTimer>
 | |
| #include <QTimerEvent>
 | |
| 
 | |
| //Set QNetworkReply timeout without external timer
 | |
| //https://stackoverflow.com/questions/37444539/how-to-set-qnetworkreply-timeout-without-external-timer
 | |
| 
 | |
| class ReplyTimeout : public QObject {
 | |
| 	Q_OBJECT
 | |
| public:
 | |
| 	enum HandleMethod { Abort, Close };
 | |
| 	ReplyTimeout(QNetworkReply* reply, const int timeout, HandleMethod method = Abort) :
 | |
| 		  QObject(reply), m_method(method)
 | |
| 	{
 | |
| 		Q_ASSERT(reply);
 | |
| 		if (reply && reply->isRunning()) {
 | |
| 			m_timer.start(timeout, this);
 | |
| 			connect(reply, &QNetworkReply::finished, this, &QObject::deleteLater);
 | |
| 		}
 | |
| 	}
 | |
| 	static void set(QNetworkReply* reply, const int timeout, HandleMethod method = Abort)
 | |
| 	{
 | |
| 		new ReplyTimeout(reply, timeout, method);
 | |
| 	}
 | |
| 
 | |
| protected:
 | |
| 	QBasicTimer m_timer;
 | |
| 	HandleMethod m_method;
 | |
| 	void timerEvent(QTimerEvent * ev) override {
 | |
| 		if (!m_timer.isActive() || ev->timerId() != m_timer.timerId())
 | |
| 			return;
 | |
| 		auto reply = static_cast<QNetworkReply*>(parent());
 | |
| 		if (reply->isRunning())
 | |
| 		{
 | |
| 			if (m_method == Close)
 | |
| 				reply->close();
 | |
| 			else if (m_method == Abort)
 | |
| 				reply->abort();
 | |
| 			m_timer.stop();
 | |
| 		}
 | |
| 	}
 | |
| };
 | |
| 
 | |
| ///
 | |
| /// Response object for REST-API calls and JSON-responses
 | |
| ///
 | |
| class httpResponse
 | |
| {
 | |
| public:
 | |
| 	httpResponse() = default;
 | |
| 
 | |
| 	bool error() const { return _hasError; }
 | |
| 	void setError(const bool hasError) { _hasError = hasError; }
 | |
| 
 | |
| 	QJsonDocument getBody() const { return _responseBody; }
 | |
| 	void setBody(const QJsonDocument& body) { _responseBody = body; }
 | |
| 
 | |
| 	QString getErrorReason() const { return _errorReason; }
 | |
| 	void setErrorReason(const QString& errorReason) { _errorReason = errorReason; }
 | |
| 
 | |
| 	int getHttpStatusCode() const { return _httpStatusCode; }
 | |
| 	void setHttpStatusCode(int httpStatusCode) { _httpStatusCode = httpStatusCode; }
 | |
| 
 | |
| 	QNetworkReply::NetworkError getNetworkReplyError() const { return _networkReplyError; }
 | |
| 	void setNetworkReplyError(const QNetworkReply::NetworkError networkReplyError) { _networkReplyError = networkReplyError; }
 | |
| 
 | |
| private:
 | |
| 
 | |
| 	QJsonDocument _responseBody;
 | |
| 	bool _hasError = false;
 | |
| 	QString _errorReason;
 | |
| 
 | |
| 	int _httpStatusCode = 0;
 | |
| 	QNetworkReply::NetworkError _networkReplyError = QNetworkReply::NoError;
 | |
| };
 | |
| 
 | |
| ///
 | |
| /// Wrapper class supporting REST-API calls with JSON requests and responses
 | |
| ///
 | |
| /// Usage sample:
 | |
| /// @code
 | |
| ///
 | |
| /// ProviderRestApi* _restApi = new ProviderRestApi(hostname, port );
 | |
| ///
 | |
| /// _restApi->setBasePath( QString("/api/%1/").arg(token) );
 | |
| /// _restApi->setPath( QString("%1/%2").arg( "groups" ).arg( groupId ) );
 | |
| ///
 | |
| /// httpResponse response = _restApi->get();
 | |
| /// if ( !response.error() )
 | |
| ///		response.getBody();
 | |
| ///
 | |
| /// delete _restApi;
 | |
| ///
 | |
| ///@endcode
 | |
| ///
 | |
| class ProviderRestApi
 | |
| {
 | |
| public:
 | |
| 
 | |
| 	///
 | |
| 	/// @brief Constructor of the REST-API wrapper
 | |
| 	///
 | |
| 	ProviderRestApi();
 | |
| 
 | |
| 	///
 | |
| 	/// @brief Constructor of the REST-API wrapper
 | |
| 	///
 | |
| 	/// @param[in] host
 | |
| 	/// @param[in] port
 | |
| 	///
 | |
| 	explicit ProviderRestApi(const QString& host, int port);
 | |
| 
 | |
| 	///
 | |
| 	/// @brief Constructor of the REST-API wrapper
 | |
| 	///
 | |
| 	/// @param[in] host
 | |
| 	/// @param[in] port
 | |
| 	/// @param[in] API base-path
 | |
| 	///
 | |
| 	explicit ProviderRestApi(const QString& host, int port, const QString& basePath);
 | |
| 
 | |
| 	///
 | |
| 	/// @brief Destructor of the REST-API wrapper
 | |
| 	///
 | |
| 	virtual ~ProviderRestApi();
 | |
| 
 | |
| 	///
 | |
| 	/// @brief Set an API's host
 | |
| 	///
 | |
| 	/// @param[in] host
 | |
| 	///
 | |
| 	void setHost(const QString& host) { _apiUrl.setHost(host); }
 | |
| 
 | |
| 	///
 | |
| 	/// @brief Set an API's port
 | |
| 	///
 | |
| 	/// @param[in] port
 | |
| 	///
 | |
| 	void setPort(const int port) { _apiUrl.setPort(port); }
 | |
| 
 | |
| 	///
 | |
| 	/// @brief Set an API's url
 | |
| 	///
 | |
| 	/// @param[in] url, e.g. "http://locahost:60351/chromalink/"
 | |
| 	///
 | |
| 	void setUrl(const QUrl& url);
 | |
| 
 | |
| 	///
 | |
| 	/// @brief Get the URL as defined using scheme, host, port, API-basepath, path, query, fragment
 | |
| 	///
 | |
| 	/// @return url
 | |
| 	///
 | |
| 	QUrl getUrl() const;
 | |
| 
 | |
| 	///
 | |
| 	/// @brief Set an API's base path (the stable path element before addressing resources)
 | |
| 	///
 | |
| 	/// @param[in] basePath, e.g. "/api/v1/" or "/json"
 | |
| 	///
 | |
| 	void setBasePath(const QString& basePath);
 | |
| 
 | |
| 	///
 | |
| 	/// @brief Set an API's path to address resources
 | |
| 	///
 | |
| 	/// @param[in] path, e.g. "/lights/1/state/"
 | |
| 	///
 | |
| 	void setPath(const QString& path);
 | |
| 
 | |
| 	///
 | |
| 	/// @brief Append an API's path element to path set before
 | |
| 	///
 | |
| 	/// @param[in] path
 | |
| 	///
 | |
| 	void appendPath(const QString& appendPath);
 | |
| 
 | |
| 	///
 | |
| 	/// @brief Set an API's fragment
 | |
| 	///
 | |
| 	/// @param[in] fragment, e.g. "question3"
 | |
| 	///
 | |
| 	void setFragment(const QString& fragment);
 | |
| 
 | |
| 	///
 | |
| 	/// @brief Set an API's query string
 | |
| 	///
 | |
| 	/// @param[in] query, e.g. "&A=128&FX=0"
 | |
| 	///
 | |
| 	void setQuery(const QUrlQuery& query);
 | |
| 
 | |
| 	///
 | |
| 	/// @brief Execute GET request
 | |
| 	///
 | |
| 	/// @return Response The body of the response in JSON
 | |
| 	///
 | |
| 	httpResponse get();
 | |
| 
 | |
| 	///
 | |
| 	/// @brief Execute GET request
 | |
| 	///
 | |
| 	/// @param[in] url GET request for URL
 | |
| 	/// @return Response The body of the response in JSON
 | |
| 	///
 | |
| 	httpResponse get(const QUrl& url);
 | |
| 
 | |
| 	/// @brief Execute PUT request
 | |
| 	///
 | |
| 	/// @param[in] body The body of the request in JSON
 | |
| 	/// @return Response The body of the response in JSON
 | |
| 	///
 | |
| 	httpResponse put(const QJsonObject& body);
 | |
| 
 | |
| 	///
 | |
| 	/// @brief Execute PUT request
 | |
| 	///
 | |
| 	/// @param[in] body The body of the request in JSON
 | |
| 	/// @return Response The body of the response in JSON
 | |
| 	///
 | |
| 	httpResponse put(const QString& body = "");
 | |
| 
 | |
| 	///
 | |
| 	/// @brief Execute PUT request
 | |
| 	///
 | |
| 	/// @param[in] URL for PUT request
 | |
| 	/// @param[in] body The body of the request in JSON
 | |
| 	/// @return Response The body of the response in JSON
 | |
| 	///
 | |
| 	httpResponse put(const QUrl &url, const QByteArray& body);
 | |
| 
 | |
| 	///
 | |
| 	/// @brief Execute POST request
 | |
| 	///
 | |
| 	/// @param[in] body The body of the request in JSON
 | |
| 	/// @return Response The body of the response in JSON
 | |
| 	///
 | |
| 	httpResponse post(const QString& body = "");
 | |
| 
 | |
| 	/// @brief Execute POST request
 | |
| 	///
 | |
| 	/// @param[in] body The body of the request in JSON
 | |
| 	/// @return Response The body of the response in JSON
 | |
| 	///
 | |
| 	httpResponse post(const QJsonObject& body);
 | |
| 
 | |
| 	///
 | |
| 	/// @brief Execute POST request
 | |
| 	///
 | |
| 	/// @param[in] URL for POST request
 | |
| 	/// @param[in] body The body of the request in JSON
 | |
| 	/// @return Response The body of the response in JSON
 | |
| 	///
 | |
| 	httpResponse post(const QUrl &url, const QByteArray& body);
 | |
| 
 | |
| 	///
 | |
| 	/// @brief Execute DELETE request
 | |
| 	///
 | |
| 	/// @param[in] URL (Resource) for DELETE request
 | |
| 	/// @return Response The body of the response in JSON
 | |
| 	///
 | |
| 	httpResponse deleteResource(const QUrl& url);
 | |
| 
 | |
| 	///
 | |
| 	/// @brief Handle responses for REST requests
 | |
| 	///
 | |
| 	/// @param[in] reply Network reply
 | |
| 	/// @return Response The body of the response in JSON
 | |
| 	///
 | |
| 	httpResponse getResponse(QNetworkReply* const& reply);
 | |
| 
 | |
| 	///
 | |
| 	/// Adds a header field.
 | |
| 	///
 | |
| 	/// @param[in] The type of the header field.
 | |
| 	/// @param[in] The value of the header field.
 | |
| 	/// If the header field exists, the value will be combined as comma separated string.
 | |
| 
 | |
| 	void setHeader(QNetworkRequest::KnownHeaders header, const QVariant& value);
 | |
| 
 | |
| 	///
 | |
| 	/// Remove all header fields.
 | |
| 	///
 | |
| 	void removeAllHeaders() { _networkRequestHeaders = QNetworkRequest(); }
 | |
| 
 | |
| private:
 | |
| 
 | |
| 	///
 | |
| 	/// @brief Append an API's path element to path given as param
 | |
| 	///
 | |
| 	/// @param[in/out] path to be updated
 | |
| 	/// @param[in] path, element to be appended
 | |
| 	///
 | |
| 	static void appendPath (QString &path, const QString &appendPath) ;
 | |
| 
 | |
| 	Logger* _log;
 | |
| 
 | |
| 	// QNetworkAccessManager object for sending REST-requests.
 | |
| 	QNetworkAccessManager* _networkManager;
 | |
| 
 | |
| 	QUrl _apiUrl;
 | |
| 
 | |
| 	QString _basePath;
 | |
| 	QString _path;
 | |
| 
 | |
| 	QString _fragment;
 | |
| 	QUrlQuery _query;
 | |
| 
 | |
| 	QNetworkRequest _networkRequestHeaders;
 | |
| };
 | |
| 
 | |
| #endif // PROVIDERRESTKAPI_H
 |