diff options
-rw-r--r-- | libraries/ganalytics/CMakeLists.txt | 17 | ||||
-rw-r--r-- | libraries/ganalytics/LICENSE.txt | 24 | ||||
-rw-r--r-- | libraries/ganalytics/README.md | 34 | ||||
-rw-r--r-- | libraries/ganalytics/include/ganalytics.h | 67 | ||||
-rw-r--r-- | libraries/ganalytics/src/ganalytics.cpp | 237 | ||||
-rw-r--r-- | libraries/ganalytics/src/ganalytics_worker.cpp | 254 | ||||
-rw-r--r-- | libraries/ganalytics/src/ganalytics_worker.h | 65 |
7 files changed, 0 insertions, 698 deletions
diff --git a/libraries/ganalytics/CMakeLists.txt b/libraries/ganalytics/CMakeLists.txt deleted file mode 100644 index 26b1b47c..00000000 --- a/libraries/ganalytics/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -project(ganalytics) - -find_package(Qt5Core) -find_package(Qt5Gui) -find_package(Qt5Network) - -set(ganalytics_SOURCES -src/ganalytics.cpp -src/ganalytics_worker.cpp -src/ganalytics_worker.h -include/ganalytics.h -) - -add_library(ganalytics STATIC ${ganalytics_SOURCES}) -qt5_use_modules(ganalytics Core Gui Network) -target_include_directories(ganalytics PUBLIC include) -target_link_libraries(ganalytics systeminfo) diff --git a/libraries/ganalytics/LICENSE.txt b/libraries/ganalytics/LICENSE.txt deleted file mode 100644 index 795497ff..00000000 --- a/libraries/ganalytics/LICENSE.txt +++ /dev/null @@ -1,24 +0,0 @@ -Copyright (c) 2014-2015, University of Applied Sciences Augsburg -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the University of Applied Sciences Augsburg nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS -BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE -OODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -UT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/libraries/ganalytics/README.md b/libraries/ganalytics/README.md deleted file mode 100644 index d7e1e33c..00000000 --- a/libraries/ganalytics/README.md +++ /dev/null @@ -1,34 +0,0 @@ -qt-google-analytics -================ - -Qt5 classes for providing google analytics usage in a Qt/QML application. - -## Building -Include ```qt-google-analytics.pri``` in your .pro file. - -## Using -Please make sure you have set your application information using ```QApplication::setApplicationName``` and ```QApplication::setApplicationVersion```. - -### In C++: -``` -GAnalytics tracker("UA-my-id"); -tracker.sendScreenView("Main Screen"); -``` - -### In QtQuick: -Register the class on the C++ side using ```qmlRegisterType<GAnalytics>("analytics", 0, 1, "Tracker");``` -``` -Tracker { - id: tracker - trackingID: "UA-my-id" -} - -[...] -tracker.sendScreenView("Main Screen") -``` - -There is also an example application in the examples folder. - -## License -Copyright (c) 2014-2016, University of Applied Sciences Augsburg. -All rights reserved. Distributed under the terms and conditions of the BSD License. See separate LICENSE.txt. diff --git a/libraries/ganalytics/include/ganalytics.h b/libraries/ganalytics/include/ganalytics.h deleted file mode 100644 index bfca6d37..00000000 --- a/libraries/ganalytics/include/ganalytics.h +++ /dev/null @@ -1,67 +0,0 @@ -#pragma once - -#include <QObject> -#include <QVariantMap> - -class QNetworkAccessManager; -class GAnalyticsWorker; - -class GAnalytics : public QObject -{ - Q_OBJECT - Q_ENUMS(LogLevel) - -public: - explicit GAnalytics(const QString &trackingID, const QString &clientID, const int version, QObject *parent = 0); - ~GAnalytics(); - -public: - enum LogLevel - { - Debug, - Info, - Error - }; - - int version(); - - void setLogLevel(LogLevel logLevel); - LogLevel logLevel() const; - - // Getter and Setters - void setViewportSize(const QString &viewportSize); - QString viewportSize() const; - - void setLanguage(const QString &language); - QString language() const; - - void setAnonymizeIPs(bool anonymize); - bool anonymizeIPs(); - - void setSendInterval(int milliseconds); - int sendInterval() const; - - void enable(bool state = true); - bool isEnabled(); - - /// Get or set the network access manager. If none is set, the class creates its own on the first request - void setNetworkAccessManager(QNetworkAccessManager *networkAccessManager); - QNetworkAccessManager *networkAccessManager() const; - -public slots: - void sendScreenView(const QString &screenName, const QVariantMap &customValues = QVariantMap()); - void sendEvent(const QString &category, const QString &action, const QString &label = QString(), const QVariant &value = QVariant(), - const QVariantMap &customValues = QVariantMap()); - void sendException(const QString &exceptionDescription, bool exceptionFatal = true, const QVariantMap &customValues = QVariantMap()); - void startSession(); - void endSession(); - -private: - GAnalyticsWorker *d; - - friend QDataStream &operator<<(QDataStream &outStream, const GAnalytics &analytics); - friend QDataStream &operator>>(QDataStream &inStream, GAnalytics &analytics); -}; - -QDataStream &operator<<(QDataStream &outStream, const GAnalytics &analytics); -QDataStream &operator>>(QDataStream &inStream, GAnalytics &analytics); diff --git a/libraries/ganalytics/src/ganalytics.cpp b/libraries/ganalytics/src/ganalytics.cpp deleted file mode 100644 index 5f2d1484..00000000 --- a/libraries/ganalytics/src/ganalytics.cpp +++ /dev/null @@ -1,237 +0,0 @@ -#include "ganalytics.h" -#include "ganalytics_worker.h" -#include "sys.h" - -#include <QDataStream> -#include <QDebug> -#include <QLocale> -#include <QNetworkAccessManager> -#include <QNetworkReply> -#include <QNetworkRequest> -#include <QQueue> -#include <QSettings> -#include <QTimer> -#include <QUrlQuery> -#include <QUuid> - -GAnalytics::GAnalytics(const QString &trackingID, const QString &clientID, const int version, QObject *parent) : QObject(parent) -{ - d = new GAnalyticsWorker(this); - d->m_trackingID = trackingID; - d->m_clientID = clientID; - d->m_version = version; -} - -/** - * Destructor of class GAnalytics. - */ -GAnalytics::~GAnalytics() -{ - delete d; -} - -void GAnalytics::setLogLevel(GAnalytics::LogLevel logLevel) -{ - d->m_logLevel = logLevel; -} - -GAnalytics::LogLevel GAnalytics::logLevel() const -{ - return d->m_logLevel; -} - -// SETTER and GETTER -void GAnalytics::setViewportSize(const QString &viewportSize) -{ - d->m_viewportSize = viewportSize; -} - -QString GAnalytics::viewportSize() const -{ - return d->m_viewportSize; -} - -void GAnalytics::setLanguage(const QString &language) -{ - d->m_language = language; -} - -QString GAnalytics::language() const -{ - return d->m_language; -} - -void GAnalytics::setAnonymizeIPs(bool anonymize) -{ - d->m_anonymizeIPs = anonymize; -} - -bool GAnalytics::anonymizeIPs() -{ - return d->m_anonymizeIPs; -} - -void GAnalytics::setSendInterval(int milliseconds) -{ - d->m_timer.setInterval(milliseconds); -} - -int GAnalytics::sendInterval() const -{ - return (d->m_timer.interval()); -} - -bool GAnalytics::isEnabled() -{ - return d->m_isEnabled; -} - -void GAnalytics::enable(bool state) -{ - d->enable(state); -} - -int GAnalytics::version() -{ - return d->m_version; -} - -void GAnalytics::setNetworkAccessManager(QNetworkAccessManager *networkAccessManager) -{ - if (d->networkManager != networkAccessManager) - { - // Delete the old network manager if it was our child - if (d->networkManager && d->networkManager->parent() == this) - { - d->networkManager->deleteLater(); - } - - d->networkManager = networkAccessManager; - } -} - -QNetworkAccessManager *GAnalytics::networkAccessManager() const -{ - return d->networkManager; -} - -static void appendCustomValues(QUrlQuery &query, const QVariantMap &customValues) -{ - for (QVariantMap::const_iterator iter = customValues.begin(); iter != customValues.end(); ++iter) - { - query.addQueryItem(iter.key(), iter.value().toString()); - } -} - -/** - * Sent screen view is called when the user changed the applications view. - * These action of the user should be noticed and reported. Therefore - * a QUrlQuery is build in this method. It holts all the parameter for - * a http POST. The UrlQuery will be stored in a message Queue. - */ -void GAnalytics::sendScreenView(const QString &screenName, const QVariantMap &customValues) -{ - d->logMessage(Info, QString("ScreenView: %1").arg(screenName)); - - QUrlQuery query = d->buildStandardPostQuery("screenview"); - query.addQueryItem("cd", screenName); - query.addQueryItem("an", d->m_appName); - query.addQueryItem("av", d->m_appVersion); - appendCustomValues(query, customValues); - - d->enqueQueryWithCurrentTime(query); -} - -/** - * This method is called whenever a button was pressed in the application. - * A query for a POST message will be created to report this event. The - * created query will be stored in a message queue. - */ -void GAnalytics::sendEvent(const QString &category, const QString &action, const QString &label, const QVariant &value, const QVariantMap &customValues) -{ - QUrlQuery query = d->buildStandardPostQuery("event"); - query.addQueryItem("an", d->m_appName); - query.addQueryItem("av", d->m_appVersion); - query.addQueryItem("ec", category); - query.addQueryItem("ea", action); - if (!label.isEmpty()) - query.addQueryItem("el", label); - if (value.isValid()) - query.addQueryItem("ev", value.toString()); - - appendCustomValues(query, customValues); - - d->enqueQueryWithCurrentTime(query); -} - -/** - * Method is called after an exception was raised. It builds a - * query for a POST message. These query will be stored in a - * message queue. - */ -void GAnalytics::sendException(const QString &exceptionDescription, bool exceptionFatal, const QVariantMap &customValues) -{ - QUrlQuery query = d->buildStandardPostQuery("exception"); - query.addQueryItem("an", d->m_appName); - query.addQueryItem("av", d->m_appVersion); - - query.addQueryItem("exd", exceptionDescription); - - if (exceptionFatal) - { - query.addQueryItem("exf", "1"); - } - else - { - query.addQueryItem("exf", "0"); - } - appendCustomValues(query, customValues); - - d->enqueQueryWithCurrentTime(query); -} - -/** - * Session starts. This event will be sent by a POST message. - * Query is setup in this method and stored in the message - * queue. - */ -void GAnalytics::startSession() -{ - QVariantMap customValues; - customValues.insert("sc", "start"); - sendEvent("Session", "Start", QString(), QVariant(), customValues); -} - -/** - * Session ends. This event will be sent by a POST message. - * Query is setup in this method and stored in the message - * queue. - */ -void GAnalytics::endSession() -{ - QVariantMap customValues; - customValues.insert("sc", "end"); - sendEvent("Session", "End", QString(), QVariant(), customValues); -} - -/** - * Qut stream to persist class GAnalytics. - */ -QDataStream &operator<<(QDataStream &outStream, const GAnalytics &analytics) -{ - outStream << analytics.d->persistMessageQueue(); - - return outStream; -} - -/** - * In stream to read GAnalytics from file. - */ -QDataStream &operator>>(QDataStream &inStream, GAnalytics &analytics) -{ - QList<QString> dataList; - inStream >> dataList; - analytics.d->readMessagesFromFile(dataList); - - return inStream; -} diff --git a/libraries/ganalytics/src/ganalytics_worker.cpp b/libraries/ganalytics/src/ganalytics_worker.cpp deleted file mode 100644 index f55a4d09..00000000 --- a/libraries/ganalytics/src/ganalytics_worker.cpp +++ /dev/null @@ -1,254 +0,0 @@ -#include "ganalytics.h" -#include "ganalytics_worker.h" -#include "sys.h" - -#include <QCoreApplication> -#include <QNetworkAccessManager> -#include <QNetworkReply> - -#include <QGuiApplication> -#include <QScreen> - -const QLatin1String GAnalyticsWorker::dateTimeFormat("yyyy,MM,dd-hh:mm::ss:zzz"); - -GAnalyticsWorker::GAnalyticsWorker(GAnalytics *parent) - : QObject(parent), q(parent), m_logLevel(GAnalytics::Error) -{ - m_appName = QCoreApplication::instance()->applicationName(); - m_appVersion = QCoreApplication::instance()->applicationVersion(); - m_request.setUrl(QUrl("https://www.google-analytics.com/collect")); - m_request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); - m_request.setHeader(QNetworkRequest::UserAgentHeader, getUserAgent()); - - m_language = QLocale::system().name().toLower().replace("_", "-"); - m_screenResolution = getScreenResolution(); - - m_timer.setInterval(m_timerInterval); - connect(&m_timer, &QTimer::timeout, this, &GAnalyticsWorker::postMessage); -} - -void GAnalyticsWorker::enable(bool state) -{ - // state change to the same is not valid. - if(m_isEnabled == state) - { - return; - } - - m_isEnabled = state; - if(m_isEnabled) - { - // enable -> start doing things :) - m_timer.start(); - } - else - { - // disable -> stop the timer - m_timer.stop(); - } -} - -void GAnalyticsWorker::logMessage(GAnalytics::LogLevel level, const QString &message) -{ - if (m_logLevel > level) - { - return; - } - - qDebug() << "[Analytics]" << message; -} - -/** - * Build the POST query. Adds all parameter to the query - * which are used in every POST. - * @param type Type of POST message. The event which is to post. - * @return query Most used parameter in a query for a POST. - */ -QUrlQuery GAnalyticsWorker::buildStandardPostQuery(const QString &type) -{ - QUrlQuery query; - query.addQueryItem("v", "1"); - query.addQueryItem("tid", m_trackingID); - query.addQueryItem("cid", m_clientID); - if (!m_userID.isEmpty()) - { - query.addQueryItem("uid", m_userID); - } - query.addQueryItem("t", type); - query.addQueryItem("ul", m_language); - query.addQueryItem("vp", m_viewportSize); - query.addQueryItem("sr", m_screenResolution); - if(m_anonymizeIPs) - { - query.addQueryItem("aip", "1"); - } - return query; -} - -/** - * Get primary screen resolution. - * @return A QString like "800x600". - */ -QString GAnalyticsWorker::getScreenResolution() -{ - QScreen *screen = QGuiApplication::primaryScreen(); - QSize size = screen->size(); - - return QString("%1x%2").arg(size.width()).arg(size.height()); -} - -/** - * Try to gain information about the system where this application - * is running. It needs to get the name and version of the operating - * system, the language and screen resolution. - * All this information will be send in POST messages. - * @return agent A QString with all the information formatted for a POST message. - */ -QString GAnalyticsWorker::getUserAgent() -{ - return QString("%1/%2").arg(m_appName).arg(m_appVersion); -} - -/** - * The message queue contains a list of QueryBuffer object. - * QueryBuffer holds a QUrlQuery object and a QDateTime object. - * These both object are freed from the buffer object and - * inserted as QString objects in a QList. - * @return dataList The list with concartinated queue data. - */ -QList<QString> GAnalyticsWorker::persistMessageQueue() -{ - QList<QString> dataList; - foreach (QueryBuffer buffer, m_messageQueue) - { - dataList << buffer.postQuery.toString(); - dataList << buffer.time.toString(dateTimeFormat); - } - return dataList; -} - -/** - * Reads persistent messages from a file. - * Gets all message data as a QList<QString>. - * Two lines in the list build a QueryBuffer object. - */ -void GAnalyticsWorker::readMessagesFromFile(const QList<QString> &dataList) -{ - QListIterator<QString> iter(dataList); - while (iter.hasNext()) - { - QString queryString = iter.next(); - QString dateString = iter.next(); - QUrlQuery query; - query.setQuery(queryString); - QDateTime dateTime = QDateTime::fromString(dateString, dateTimeFormat); - QueryBuffer buffer; - buffer.postQuery = query; - buffer.time = dateTime; - m_messageQueue.enqueue(buffer); - } -} - -/** - * Takes a QUrlQuery object and wrapp it together with - * a QTime object into a QueryBuffer struct. These struct - * will be stored in the message queue. - */ -void GAnalyticsWorker::enqueQueryWithCurrentTime(const QUrlQuery &query) -{ - QueryBuffer buffer; - buffer.postQuery = query; - buffer.time = QDateTime::currentDateTime(); - - m_messageQueue.enqueue(buffer); -} - -/** - * This function is called by a timer interval. - * The function tries to send a messages from the queue. - * If message was successfully send then this function - * will be called back to send next message. - * If message queue contains more than one message then - * the connection will kept open. - * The message POST is asyncroniously when the server - * answered a signal will be emitted. - */ -void GAnalyticsWorker::postMessage() -{ - if (m_messageQueue.isEmpty()) - { - // queue empty -> try sending later - m_timer.start(); - return; - } - else - { - // queue has messages -> stop timer and start sending - m_timer.stop(); - } - - QString connection = "close"; - if (m_messageQueue.count() > 1) - { - connection = "keep-alive"; - } - - QueryBuffer buffer = m_messageQueue.head(); - QDateTime sendTime = QDateTime::currentDateTime(); - qint64 timeDiff = buffer.time.msecsTo(sendTime); - - if (timeDiff > fourHours) - { - // too old. - m_messageQueue.dequeue(); - emit postMessage(); - return; - } - - buffer.postQuery.addQueryItem("qt", QString::number(timeDiff)); - m_request.setRawHeader("Connection", connection.toUtf8()); - m_request.setHeader(QNetworkRequest::ContentLengthHeader, buffer.postQuery.toString().length()); - - logMessage(GAnalytics::Debug, "Query string = " + buffer.postQuery.toString()); - - // Create a new network access manager if we don't have one yet - if (networkManager == NULL) - { - networkManager = new QNetworkAccessManager(this); - } - - QNetworkReply *reply = networkManager->post(m_request, buffer.postQuery.query(QUrl::EncodeUnicode).toUtf8()); - connect(reply, SIGNAL(finished()), this, SLOT(postMessageFinished())); -} - -/** - * NetworkAccsessManager has finished to POST a message. - * If POST message was successfully send then the message - * query should be removed from queue. - * SIGNAL "postMessage" will be emitted to send next message - * if there is any. - * If message couldn't be send then next try is when the - * timer emits its signal. - */ -void GAnalyticsWorker::postMessageFinished() -{ - QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender()); - - int httpStausCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - if (httpStausCode < 200 || httpStausCode > 299) - { - logMessage(GAnalytics::Error, QString("Error posting message: %s").arg(reply->errorString())); - - // An error ocurred. Try sending later. - m_timer.start(); - return; - } - else - { - logMessage(GAnalytics::Debug, "Message sent"); - } - - m_messageQueue.dequeue(); - postMessage(); - reply->deleteLater(); -} diff --git a/libraries/ganalytics/src/ganalytics_worker.h b/libraries/ganalytics/src/ganalytics_worker.h deleted file mode 100644 index 559e0eb6..00000000 --- a/libraries/ganalytics/src/ganalytics_worker.h +++ /dev/null @@ -1,65 +0,0 @@ -#pragma once - -#include <QUrlQuery> -#include <QDateTime> -#include <QTimer> -#include <QNetworkRequest> -#include <QQueue> - -struct QueryBuffer -{ - QUrlQuery postQuery; - QDateTime time; -}; - -class GAnalyticsWorker : public QObject -{ - Q_OBJECT - -public: - explicit GAnalyticsWorker(GAnalytics *parent = 0); - - GAnalytics *q; - - QNetworkAccessManager *networkManager = nullptr; - - QQueue<QueryBuffer> m_messageQueue; - QTimer m_timer; - QNetworkRequest m_request; - GAnalytics::LogLevel m_logLevel; - - QString m_trackingID; - QString m_clientID; - QString m_userID; - QString m_appName; - QString m_appVersion; - QString m_language; - QString m_screenResolution; - QString m_viewportSize; - - bool m_anonymizeIPs = false; - bool m_isEnabled = false; - int m_timerInterval = 30000; - int m_version = 0; - - const static int fourHours = 4 * 60 * 60 * 1000; - const static QLatin1String dateTimeFormat; - -public: - void logMessage(GAnalytics::LogLevel level, const QString &message); - - QUrlQuery buildStandardPostQuery(const QString &type); - QString getScreenResolution(); - QString getUserAgent(); - QList<QString> persistMessageQueue(); - void readMessagesFromFile(const QList<QString> &dataList); - - void enqueQueryWithCurrentTime(const QUrlQuery &query); - void setIsSending(bool doSend); - void enable(bool state); - -public slots: - void postMessage(); - void postMessageFinished(); -}; - |