1 #include "ganalytics.h"
2 #include "ganalytics_worker.h"
3 #include "sys.h"
4 
5 #include <QDataStream>
6 #include <QDebug>
7 #include <QLocale>
8 #include <QNetworkAccessManager>
9 #include <QNetworkReply>
10 #include <QNetworkRequest>
11 #include <QQueue>
12 #include <QSettings>
13 #include <QTimer>
14 #include <QUrlQuery>
15 #include <QUuid>
16 
GAnalytics(const QString & trackingID,const QString & clientID,const int version,QObject * parent)17 GAnalytics::GAnalytics(const QString &trackingID, const QString &clientID, const int version, QObject *parent) : QObject(parent)
18 {
19     d = new GAnalyticsWorker(this);
20     d->m_trackingID = trackingID;
21     d->m_clientID = clientID;
22     d->m_version = version;
23 }
24 
25 /**
26  * Destructor of class GAnalytics.
27  */
~GAnalytics()28 GAnalytics::~GAnalytics()
29 {
30     delete d;
31 }
32 
setLogLevel(GAnalytics::LogLevel logLevel)33 void GAnalytics::setLogLevel(GAnalytics::LogLevel logLevel)
34 {
35     d->m_logLevel = logLevel;
36 }
37 
logLevel() const38 GAnalytics::LogLevel GAnalytics::logLevel() const
39 {
40     return d->m_logLevel;
41 }
42 
43 // SETTER and GETTER
setViewportSize(const QString & viewportSize)44 void GAnalytics::setViewportSize(const QString &viewportSize)
45 {
46     d->m_viewportSize = viewportSize;
47 }
48 
viewportSize() const49 QString GAnalytics::viewportSize() const
50 {
51     return d->m_viewportSize;
52 }
53 
setLanguage(const QString & language)54 void GAnalytics::setLanguage(const QString &language)
55 {
56     d->m_language = language;
57 }
58 
language() const59 QString GAnalytics::language() const
60 {
61     return d->m_language;
62 }
63 
setAnonymizeIPs(bool anonymize)64 void GAnalytics::setAnonymizeIPs(bool anonymize)
65 {
66     d->m_anonymizeIPs = anonymize;
67 }
68 
anonymizeIPs()69 bool GAnalytics::anonymizeIPs()
70 {
71     return d->m_anonymizeIPs;
72 }
73 
setSendInterval(int milliseconds)74 void GAnalytics::setSendInterval(int milliseconds)
75 {
76     d->m_timer.setInterval(milliseconds);
77 }
78 
sendInterval() const79 int GAnalytics::sendInterval() const
80 {
81     return (d->m_timer.interval());
82 }
83 
isEnabled()84 bool GAnalytics::isEnabled()
85 {
86     return d->m_isEnabled;
87 }
88 
enable(bool state)89 void GAnalytics::enable(bool state)
90 {
91     d->enable(state);
92 }
93 
version()94 int GAnalytics::version()
95 {
96     return d->m_version;
97 }
98 
setNetworkAccessManager(QNetworkAccessManager * networkAccessManager)99 void GAnalytics::setNetworkAccessManager(QNetworkAccessManager *networkAccessManager)
100 {
101     if (d->networkManager != networkAccessManager)
102     {
103         // Delete the old network manager if it was our child
104         if (d->networkManager && d->networkManager->parent() == this)
105         {
106             d->networkManager->deleteLater();
107         }
108 
109         d->networkManager = networkAccessManager;
110     }
111 }
112 
networkAccessManager() const113 QNetworkAccessManager *GAnalytics::networkAccessManager() const
114 {
115     return d->networkManager;
116 }
117 
appendCustomValues(QUrlQuery & query,const QVariantMap & customValues)118 static void appendCustomValues(QUrlQuery &query, const QVariantMap &customValues)
119 {
120     for (QVariantMap::const_iterator iter = customValues.begin(); iter != customValues.end(); ++iter)
121     {
122         query.addQueryItem(iter.key(), iter.value().toString());
123     }
124 }
125 
126 /**
127  * Sent screen view is called when the user changed the applications view.
128  * These action of the user should be noticed and reported. Therefore
129  * a QUrlQuery is build in this method. It holts all the parameter for
130  * a http POST. The UrlQuery will be stored in a message Queue.
131  */
sendScreenView(const QString & screenName,const QVariantMap & customValues)132 void GAnalytics::sendScreenView(const QString &screenName, const QVariantMap &customValues)
133 {
134     d->logMessage(Info, QString("ScreenView: %1").arg(screenName));
135 
136     QUrlQuery query = d->buildStandardPostQuery("screenview");
137     query.addQueryItem("cd", screenName);
138     query.addQueryItem("an", d->m_appName);
139     query.addQueryItem("av", d->m_appVersion);
140     appendCustomValues(query, customValues);
141 
142     d->enqueQueryWithCurrentTime(query);
143 }
144 
145 /**
146  * This method is called whenever a button was pressed in the application.
147  * A query for a POST message will be created to report this event. The
148  * created query will be stored in a message queue.
149  */
sendEvent(const QString & category,const QString & action,const QString & label,const QVariant & value,const QVariantMap & customValues)150 void GAnalytics::sendEvent(const QString &category, const QString &action, const QString &label, const QVariant &value, const QVariantMap &customValues)
151 {
152     QUrlQuery query = d->buildStandardPostQuery("event");
153     query.addQueryItem("an", d->m_appName);
154     query.addQueryItem("av", d->m_appVersion);
155     query.addQueryItem("ec", category);
156     query.addQueryItem("ea", action);
157     if (!label.isEmpty())
158         query.addQueryItem("el", label);
159     if (value.isValid())
160         query.addQueryItem("ev", value.toString());
161 
162     appendCustomValues(query, customValues);
163 
164     d->enqueQueryWithCurrentTime(query);
165 }
166 
167 /**
168  * Method is called after an exception was raised. It builds a
169  * query for a POST message. These query will be stored in a
170  * message queue.
171  */
sendException(const QString & exceptionDescription,bool exceptionFatal,const QVariantMap & customValues)172 void GAnalytics::sendException(const QString &exceptionDescription, bool exceptionFatal, const QVariantMap &customValues)
173 {
174     QUrlQuery query = d->buildStandardPostQuery("exception");
175     query.addQueryItem("an", d->m_appName);
176     query.addQueryItem("av", d->m_appVersion);
177 
178     query.addQueryItem("exd", exceptionDescription);
179 
180     if (exceptionFatal)
181     {
182         query.addQueryItem("exf", "1");
183     }
184     else
185     {
186         query.addQueryItem("exf", "0");
187     }
188     appendCustomValues(query, customValues);
189 
190     d->enqueQueryWithCurrentTime(query);
191 }
192 
193 /**
194  * Session starts. This event will be sent by a POST message.
195  * Query is setup in this method and stored in the message
196  * queue.
197  */
startSession()198 void GAnalytics::startSession()
199 {
200     QVariantMap customValues;
201     customValues.insert("sc", "start");
202     sendEvent("Session", "Start", QString(), QVariant(), customValues);
203 }
204 
205 /**
206  * Session ends. This event will be sent by a POST message.
207  * Query is setup in this method and stored in the message
208  * queue.
209  */
endSession()210 void GAnalytics::endSession()
211 {
212     QVariantMap customValues;
213     customValues.insert("sc", "end");
214     sendEvent("Session", "End", QString(), QVariant(), customValues);
215 }
216 
217 /**
218  * Qut stream to persist class GAnalytics.
219  */
operator <<(QDataStream & outStream,const GAnalytics & analytics)220 QDataStream &operator<<(QDataStream &outStream, const GAnalytics &analytics)
221 {
222     outStream << analytics.d->persistMessageQueue();
223 
224     return outStream;
225 }
226 
227 /**
228  * In stream to read GAnalytics from file.
229  */
operator >>(QDataStream & inStream,GAnalytics & analytics)230 QDataStream &operator>>(QDataStream &inStream, GAnalytics &analytics)
231 {
232     QList<QString> dataList;
233     inStream >> dataList;
234     analytics.d->readMessagesFromFile(dataList);
235 
236     return inStream;
237 }
238