Completely remove Google Analytics library
This commit is contained in:
parent
af76cf59b6
commit
f25a9bc103
@ -78,9 +78,6 @@ set(Launcher_PASTE_EE_API_KEY "utLvciUouSURFzfjPxLBf5W4ISsUX4pwBDF7N1AfZ" CACHE
|
||||
# Imgur API Client ID
|
||||
set(Launcher_IMGUR_CLIENT_ID "5b97b0713fba4a3" CACHE STRING "Client ID you can get from Imgur when you register an application")
|
||||
|
||||
# Google analytics ID
|
||||
set(Launcher_ANALYTICS_ID "" CACHE STRING "ID you can get from Google analytics")
|
||||
|
||||
# MSA Client ID
|
||||
set(Launcher_MSA_CLIENT_ID "17b47edd-c884-4997-926d-9e7f9a6b4647" CACHE STRING "Client ID you can get from Microsoft Identity Platform when you register an application")
|
||||
|
||||
@ -250,7 +247,6 @@ set(NBT_NAME Launcher_nbt++)
|
||||
set(NBT_DEST_DIR ${LIBRARY_DEST_DIR})
|
||||
add_subdirectory(libraries/libnbtplusplus)
|
||||
|
||||
add_subdirectory(libraries/ganalytics) # google analytics library
|
||||
add_subdirectory(libraries/systeminfo) # system information library
|
||||
add_subdirectory(libraries/hoedown) # markdown parser
|
||||
add_subdirectory(libraries/launcher) # java based launcher part for Minecraft
|
||||
@ -260,7 +256,7 @@ add_subdirectory(libraries/quazip) # zip manipulation library
|
||||
add_subdirectory(libraries/rainbow) # Qt extension for colors
|
||||
add_subdirectory(libraries/iconfix) # fork of Qt's QIcon loader
|
||||
add_subdirectory(libraries/LocalPeer) # fork of a library from Qt solutions
|
||||
add_subdirectory(libraries/classparser) # google analytics library
|
||||
add_subdirectory(libraries/classparser) # class parser library
|
||||
add_subdirectory(libraries/optional-bare)
|
||||
add_subdirectory(libraries/tomlc99) # toml parser
|
||||
add_subdirectory(libraries/katabasis) # An OAuth2 library that tried to do too much
|
||||
|
@ -24,7 +24,6 @@ Config::Config()
|
||||
|
||||
BUILD_PLATFORM = "@Launcher_BUILD_PLATFORM@";
|
||||
UPDATER_BASE = "@Launcher_UPDATER_BASE@";
|
||||
ANALYTICS_ID = "@Launcher_ANALYTICS_ID@";
|
||||
NOTIFICATION_URL = "@Launcher_NOTIFICATION_URL@";
|
||||
FULL_VERSION_STR = "@Launcher_VERSION_MAJOR@.@Launcher_VERSION_MINOR@.@Launcher_VERSION_BUILD@";
|
||||
|
||||
|
@ -46,9 +46,6 @@ public:
|
||||
QString USER_AGENT_UNCACHED;
|
||||
|
||||
|
||||
/// Google analytics ID
|
||||
QString ANALYTICS_ID;
|
||||
|
||||
/// URL for notifications
|
||||
QString NOTIFICATION_URL;
|
||||
|
||||
@ -79,7 +76,7 @@ public:
|
||||
* Client ID you can get from Imgur when you register an application
|
||||
*/
|
||||
QString IMGUR_CLIENT_ID;
|
||||
|
||||
|
||||
/**
|
||||
* Client ID you can get from Microsoft Identity Platform when you register an application
|
||||
*/
|
||||
@ -115,3 +112,4 @@ public:
|
||||
};
|
||||
|
||||
extern const Config BuildConfig;
|
||||
|
||||
|
@ -26,7 +26,6 @@
|
||||
#include "ui/setupwizard/SetupWizard.h"
|
||||
#include "ui/setupwizard/LanguageWizardPage.h"
|
||||
#include "ui/setupwizard/JavaWizardPage.h"
|
||||
#include "ui/setupwizard/AnalyticsWizardPage.h"
|
||||
|
||||
#include "ui/dialogs/CustomMessageBox.h"
|
||||
|
||||
@ -73,7 +72,6 @@
|
||||
#include <DesktopServices.h>
|
||||
#include <LocalPeer.h>
|
||||
|
||||
#include <ganalytics.h>
|
||||
#include <sys.h>
|
||||
|
||||
|
||||
@ -719,14 +717,6 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
|
||||
// paste.ee API key
|
||||
m_settings->registerSetting("PasteEEAPIKey", "multimc");
|
||||
|
||||
if(!BuildConfig.ANALYTICS_ID.isEmpty())
|
||||
{
|
||||
// Analytics
|
||||
m_settings->registerSetting("Analytics", true);
|
||||
m_settings->registerSetting("AnalyticsSeen", 0);
|
||||
m_settings->registerSetting("AnalyticsClientID", QString());
|
||||
}
|
||||
|
||||
// Init page provider
|
||||
{
|
||||
m_globalSettingsProvider = std::make_shared<GenericPageProvider>(tr("Settings"));
|
||||
@ -908,46 +898,6 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
|
||||
qDebug() << "<> Application theme set.";
|
||||
}
|
||||
|
||||
// Initialize analytics
|
||||
[this]()
|
||||
{
|
||||
const int analyticsVersion = 2;
|
||||
if(BuildConfig.ANALYTICS_ID.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto analyticsSetting = m_settings->getSetting("Analytics");
|
||||
connect(analyticsSetting.get(), &Setting::SettingChanged, this, &Application::analyticsSettingChanged);
|
||||
QString clientID = m_settings->get("AnalyticsClientID").toString();
|
||||
if(clientID.isEmpty())
|
||||
{
|
||||
clientID = QUuid::createUuid().toString();
|
||||
clientID.remove(QLatin1Char('{'));
|
||||
clientID.remove(QLatin1Char('}'));
|
||||
m_settings->set("AnalyticsClientID", clientID);
|
||||
}
|
||||
m_analytics = new GAnalytics(BuildConfig.ANALYTICS_ID, clientID, analyticsVersion, this);
|
||||
m_analytics->setLogLevel(GAnalytics::Debug);
|
||||
m_analytics->setAnonymizeIPs(true);
|
||||
// FIXME: the ganalytics library has no idea about our fancy shared pointers...
|
||||
m_analytics->setNetworkAccessManager(network().get());
|
||||
|
||||
if(m_settings->get("AnalyticsSeen").toInt() < m_analytics->version())
|
||||
{
|
||||
qDebug() << "Analytics info not seen by user yet (or old version).";
|
||||
return;
|
||||
}
|
||||
if(!m_settings->get("Analytics").toBool())
|
||||
{
|
||||
qDebug() << "Analytics disabled by user.";
|
||||
return;
|
||||
}
|
||||
|
||||
m_analytics->enable();
|
||||
qDebug() << "<> Initialized analytics with tid" << BuildConfig.ANALYTICS_ID;
|
||||
}();
|
||||
|
||||
if(createSetupWizard())
|
||||
{
|
||||
return;
|
||||
@ -974,29 +924,13 @@ bool Application::createSetupWizard()
|
||||
}
|
||||
return false;
|
||||
}();
|
||||
bool analyticsRequired = [&]()
|
||||
{
|
||||
if(BuildConfig.ANALYTICS_ID.isEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!settings()->get("Analytics").toBool())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (settings()->get("AnalyticsSeen").toInt() < analytics()->version())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}();
|
||||
bool languageRequired = [&]()
|
||||
{
|
||||
if (settings()->get("Language").toString().isEmpty())
|
||||
return true;
|
||||
return false;
|
||||
}();
|
||||
bool wizardRequired = javaRequired || analyticsRequired || languageRequired;
|
||||
bool wizardRequired = javaRequired || languageRequired;
|
||||
|
||||
if(wizardRequired)
|
||||
{
|
||||
@ -1009,10 +943,6 @@ bool Application::createSetupWizard()
|
||||
{
|
||||
m_setupWizard->addPage(new JavaWizardPage(m_setupWizard));
|
||||
}
|
||||
if(analyticsRequired)
|
||||
{
|
||||
m_setupWizard->addPage(new AnalyticsWizardPage(m_setupWizard));
|
||||
}
|
||||
connect(m_setupWizard, &QDialog::finished, this, &Application::setupWizardFinished);
|
||||
m_setupWizard->show();
|
||||
return true;
|
||||
@ -1169,22 +1099,6 @@ void Application::messageReceived(const QByteArray& message)
|
||||
}
|
||||
}
|
||||
|
||||
void Application::analyticsSettingChanged(const Setting&, QVariant value)
|
||||
{
|
||||
if(!m_analytics)
|
||||
return;
|
||||
bool enabled = value.toBool();
|
||||
if(enabled)
|
||||
{
|
||||
qDebug() << "Analytics enabled by user.";
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "Analytics disabled by user.";
|
||||
}
|
||||
m_analytics->enable(enabled);
|
||||
}
|
||||
|
||||
std::shared_ptr<TranslationsModel> Application::translations()
|
||||
{
|
||||
return m_translations;
|
||||
@ -1454,60 +1368,6 @@ MainWindow* Application::showMainWindow(bool minimized)
|
||||
connect(m_mainWindow, &MainWindow::isClosing, this, &Application::on_windowClose);
|
||||
m_openWindows++;
|
||||
}
|
||||
// FIXME: move this somewhere else...
|
||||
if(m_analytics)
|
||||
{
|
||||
auto windowSize = m_mainWindow->size();
|
||||
auto sizeString = QString("%1x%2").arg(windowSize.width()).arg(windowSize.height());
|
||||
qDebug() << "Viewport size" << sizeString;
|
||||
m_analytics->setViewportSize(sizeString);
|
||||
/*
|
||||
* cm1 = java min heap [MB]
|
||||
* cm2 = java max heap [MB]
|
||||
* cm3 = system RAM [MB]
|
||||
*
|
||||
* cd1 = java version
|
||||
* cd2 = java architecture
|
||||
* cd3 = system architecture
|
||||
* cd4 = CPU architecture
|
||||
*/
|
||||
QVariantMap customValues;
|
||||
int min = m_settings->get("MinMemAlloc").toInt();
|
||||
int max = m_settings->get("MaxMemAlloc").toInt();
|
||||
if(min < max)
|
||||
{
|
||||
customValues["cm1"] = min;
|
||||
customValues["cm2"] = max;
|
||||
}
|
||||
else
|
||||
{
|
||||
customValues["cm1"] = max;
|
||||
customValues["cm2"] = min;
|
||||
}
|
||||
|
||||
constexpr uint64_t Mega = 1024ull * 1024ull;
|
||||
int ramSize = int(Sys::getSystemRam() / Mega);
|
||||
qDebug() << "RAM size is" << ramSize << "MB";
|
||||
customValues["cm3"] = ramSize;
|
||||
|
||||
customValues["cd1"] = m_settings->get("JavaVersion");
|
||||
customValues["cd2"] = m_settings->get("JavaArchitecture");
|
||||
customValues["cd3"] = Sys::isSystem64bit() ? "64":"32";
|
||||
customValues["cd4"] = Sys::isCPU64bit() ? "64":"32";
|
||||
auto kernelInfo = Sys::getKernelInfo();
|
||||
customValues["cd5"] = kernelInfo.kernelName;
|
||||
customValues["cd6"] = kernelInfo.kernelVersion;
|
||||
auto distInfo = Sys::getDistributionInfo();
|
||||
if(!distInfo.distributionName.isEmpty())
|
||||
{
|
||||
customValues["cd7"] = distInfo.distributionName;
|
||||
}
|
||||
if(!distInfo.distributionVersion.isEmpty())
|
||||
{
|
||||
customValues["cd8"] = distInfo.distributionVersion;
|
||||
}
|
||||
m_analytics->sendScreenView("Main Window", customValues);
|
||||
}
|
||||
return m_mainWindow;
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,6 @@ class BaseDetachedToolFactory;
|
||||
class TranslationsModel;
|
||||
class ITheme;
|
||||
class MCEditTool;
|
||||
class GAnalytics;
|
||||
|
||||
namespace Meta {
|
||||
class Index;
|
||||
@ -60,10 +59,6 @@ public:
|
||||
Application(int &argc, char **argv);
|
||||
virtual ~Application();
|
||||
|
||||
GAnalytics *analytics() const {
|
||||
return m_analytics;
|
||||
}
|
||||
|
||||
std::shared_ptr<SettingsObject> settings() const {
|
||||
return m_settings;
|
||||
}
|
||||
@ -161,7 +156,6 @@ private slots:
|
||||
void messageReceived(const QByteArray & message);
|
||||
void controllerSucceeded();
|
||||
void controllerFailed(const QString & error);
|
||||
void analyticsSettingChanged(const Setting &setting, QVariant value);
|
||||
void setupWizardFinished(int status);
|
||||
|
||||
private:
|
||||
@ -226,7 +220,6 @@ private:
|
||||
// peer launcher instance connector - used to implement single instance launcher and signalling
|
||||
LocalPeer * m_peerInstance = nullptr;
|
||||
|
||||
GAnalytics * m_analytics = nullptr;
|
||||
SetupWizard * m_setupWizard = nullptr;
|
||||
public:
|
||||
QString m_instanceIdToLaunch;
|
||||
@ -236,3 +229,4 @@ public:
|
||||
QUrl m_zipToImport;
|
||||
std::unique_ptr<QFile> logFile;
|
||||
};
|
||||
|
||||
|
@ -627,8 +627,6 @@ SET(LAUNCHER_SOURCES
|
||||
# GUI - setup wizard
|
||||
ui/setupwizard/SetupWizard.h
|
||||
ui/setupwizard/SetupWizard.cpp
|
||||
ui/setupwizard/AnalyticsWizardPage.cpp
|
||||
ui/setupwizard/AnalyticsWizardPage.h
|
||||
ui/setupwizard/BaseWizardPage.h
|
||||
ui/setupwizard/JavaWizardPage.cpp
|
||||
ui/setupwizard/JavaWizardPage.h
|
||||
@ -932,7 +930,6 @@ target_link_libraries(Launcher_logic
|
||||
hoedown
|
||||
Launcher_rainbow
|
||||
LocalPeer
|
||||
ganalytics
|
||||
)
|
||||
|
||||
target_link_libraries(Launcher_logic)
|
||||
|
@ -73,11 +73,6 @@ LauncherPage::LauncherPage(QWidget *parent) : QWidget(parent), ui(new Ui::Launch
|
||||
{
|
||||
ui->updateSettingsBox->setHidden(true);
|
||||
}
|
||||
// Analytics
|
||||
if(BuildConfig.ANALYTICS_ID.isEmpty())
|
||||
{
|
||||
ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->analyticsTab));
|
||||
}
|
||||
connect(ui->fontSizeBox, SIGNAL(valueChanged(int)), SLOT(refreshFontPreview()));
|
||||
connect(ui->consoleFont, SIGNAL(currentFontChanged(QFont)), SLOT(refreshFontPreview()));
|
||||
|
||||
@ -321,12 +316,6 @@ void LauncherPage::applySettings()
|
||||
s->set("InstSortMode", "Name");
|
||||
break;
|
||||
}
|
||||
|
||||
// Analytics
|
||||
if(!BuildConfig.ANALYTICS_ID.isEmpty())
|
||||
{
|
||||
s->set("Analytics", ui->analyticsCheck->isChecked());
|
||||
}
|
||||
}
|
||||
void LauncherPage::loadSettings()
|
||||
{
|
||||
@ -422,12 +411,6 @@ void LauncherPage::loadSettings()
|
||||
{
|
||||
ui->sortByNameBtn->setChecked(true);
|
||||
}
|
||||
|
||||
// Analytics
|
||||
if(!BuildConfig.ANALYTICS_ID.isEmpty())
|
||||
{
|
||||
ui->analyticsCheck->setChecked(s->get("Analytics").toBool());
|
||||
}
|
||||
}
|
||||
|
||||
void LauncherPage::refreshFontPreview()
|
||||
|
@ -485,69 +485,6 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="analyticsTab">
|
||||
<attribute name="title">
|
||||
<string>Analytics</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_8">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="consoleSettingsBox_2">
|
||||
<property name="title">
|
||||
<string>Analytics Settings</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="analyticsCheck">
|
||||
<property name="text">
|
||||
<string>Send anonymous usage statistics?</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string><html><head/>
|
||||
<body>
|
||||
<p>The launcher sends anonymous usage statistics on every start of the application.</p><p>The following data is collected:</p>
|
||||
<ul>
|
||||
<li>Launcher version.</li>
|
||||
<li>Operating system name, version and architecture.</li>
|
||||
<li>CPU architecture (kernel architecture on linux).</li>
|
||||
<li>Size of system memory.</li>
|
||||
<li>Java version, architecture and memory settings.</li>
|
||||
</ul>
|
||||
</body></html></string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
@ -1,63 +0,0 @@
|
||||
#include "AnalyticsWizardPage.h"
|
||||
#include <Application.h>
|
||||
|
||||
#include <QVBoxLayout>
|
||||
#include <QTextBrowser>
|
||||
#include <QCheckBox>
|
||||
|
||||
#include <ganalytics.h>
|
||||
#include <BuildConfig.h>
|
||||
|
||||
AnalyticsWizardPage::AnalyticsWizardPage(QWidget *parent)
|
||||
: BaseWizardPage(parent)
|
||||
{
|
||||
setObjectName(QStringLiteral("analyticsPage"));
|
||||
verticalLayout_3 = new QVBoxLayout(this);
|
||||
verticalLayout_3->setObjectName(QStringLiteral("verticalLayout_3"));
|
||||
textBrowser = new QTextBrowser(this);
|
||||
textBrowser->setObjectName(QStringLiteral("textBrowser"));
|
||||
textBrowser->setAcceptRichText(false);
|
||||
textBrowser->setOpenExternalLinks(true);
|
||||
verticalLayout_3->addWidget(textBrowser);
|
||||
|
||||
checkBox = new QCheckBox(this);
|
||||
checkBox->setObjectName(QStringLiteral("checkBox"));
|
||||
checkBox->setChecked(true);
|
||||
verticalLayout_3->addWidget(checkBox);
|
||||
retranslate();
|
||||
}
|
||||
|
||||
AnalyticsWizardPage::~AnalyticsWizardPage()
|
||||
{
|
||||
}
|
||||
|
||||
bool AnalyticsWizardPage::validatePage()
|
||||
{
|
||||
auto settings = APPLICATION->settings();
|
||||
auto analytics = APPLICATION->analytics();
|
||||
auto status = checkBox->isChecked();
|
||||
settings->set("AnalyticsSeen", analytics->version());
|
||||
settings->set("Analytics", status);
|
||||
return true;
|
||||
}
|
||||
|
||||
void AnalyticsWizardPage::retranslate()
|
||||
{
|
||||
setTitle(tr("Analytics"));
|
||||
setSubTitle(tr("We track some anonymous statistics about users."));
|
||||
textBrowser->setHtml(tr(
|
||||
"<html><body>"
|
||||
"<p>The launcher sends anonymous usage statistics on every start of the application. This helps us decide what platforms and issues to focus on.</p>"
|
||||
"<p>The data is processed by Google Analytics, see their <a href=\"https://support.google.com/analytics/answer/6004245?hl=en\">article on the "
|
||||
"matter</a>.</p>"
|
||||
"<p>The following data is collected:</p>"
|
||||
"<ul><li>A random unique ID of the installation.<br />It is stored in the application settings file.</li>"
|
||||
"<li>Anonymized (partial) IP address.</li>"
|
||||
"<li>Launcher version.</li>"
|
||||
"<li>Operating system name, version and architecture.</li>"
|
||||
"<li>CPU architecture (kernel architecture on linux).</li>"
|
||||
"<li>Size of system memory.</li>"
|
||||
"<li>Java version, architecture and memory settings.</li></ul>"
|
||||
"<p>If we change the tracked information, you will see this page again.</p></body></html>"));
|
||||
checkBox->setText(tr("Enable Analytics"));
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "BaseWizardPage.h"
|
||||
|
||||
class QVBoxLayout;
|
||||
class QTextBrowser;
|
||||
class QCheckBox;
|
||||
|
||||
class AnalyticsWizardPage : public BaseWizardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AnalyticsWizardPage(QWidget *parent = Q_NULLPTR);
|
||||
virtual ~AnalyticsWizardPage();
|
||||
|
||||
bool validatePage() override;
|
||||
|
||||
protected:
|
||||
void retranslate() override;
|
||||
|
||||
private:
|
||||
QVBoxLayout *verticalLayout_3 = nullptr;
|
||||
QTextBrowser *textBrowser = nullptr;
|
||||
QCheckBox *checkBox = nullptr;
|
||||
};
|
@ -2,12 +2,10 @@
|
||||
|
||||
#include "LanguageWizardPage.h"
|
||||
#include "JavaWizardPage.h"
|
||||
#include "AnalyticsWizardPage.h"
|
||||
|
||||
#include "translations/TranslationsModel.h"
|
||||
#include <Application.h>
|
||||
#include <FileSystem.h>
|
||||
#include <ganalytics.h>
|
||||
|
||||
#include <QAbstractButton>
|
||||
#include <BuildConfig.h>
|
||||
|
@ -9,13 +9,6 @@ This library has served as a base for some (much more full-featured and advanced
|
||||
|
||||
Copyright belongs to Petr Mrázek, unless explicitly stated otherwise in the source files. Available under the Apache 2.0 license.
|
||||
|
||||
## ganalytics
|
||||
A Google Analytics library for Qt.
|
||||
|
||||
BSD licensed, derived from [qt-google-analytics](https://github.com/HSAnet/qt-google-analytics).
|
||||
|
||||
Modifications include better handling of IP anonymization (can be enabled) and general improvements of the API (application handles persistence and ID generation instead of the library).
|
||||
|
||||
## hoedown
|
||||
Hoedown is a revived fork of Sundown, the Markdown parser based on the original code of the Upskirt library by Natacha Porté.
|
||||
|
||||
|
@ -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})
|
||||
target_link_libraries(ganalytics Qt5::Core Qt5::Gui Qt5::Network)
|
||||
target_include_directories(ganalytics PUBLIC include)
|
||||
target_link_libraries(ganalytics systeminfo)
|
@ -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.
|
@ -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.
|
@ -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);
|
@ -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;
|
||||
}
|
@ -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: %1").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();
|
||||
}
|
@ -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();
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user