diff --git a/README.md b/README.md
index 15f227c..e12fa6f 100644
--- a/README.md
+++ b/README.md
@@ -23,6 +23,7 @@ We have libraries for the following languages:
* [Ruby](#ruby)
* [Rust](#rust)
* [Haskell](#haskell)
+ * [Qt5] (#qt5)
Alternatively, you can use Botan API via [plain HTTP calls](#http).
@@ -203,6 +204,19 @@ data AnyMessage = AnyMessage
} deriving (Show, Generic, ToJSON)
```
+
+## Qt5 example
+
+```qt5
+ QVariantMap params;
+ params["int_metric"] = 1234;
+ params["double_metric"] = 12.34;
+ params["string_metric"] = "1234";
+ params["bool_metric"] = true;
+ //call asynchronously "track" request
+ QBotanioTrackApi::newInstance()->track("SOME_PRIVATE_KEY", 1234, "TEST_EVENT", params);
+```
+
## HTTP API
### Track message
The base url is: https://api.botan.io/track
diff --git a/qt/example/track/main.cpp b/qt/example/track/main.cpp
new file mode 100644
index 0000000..7185878
--- /dev/null
+++ b/qt/example/track/main.cpp
@@ -0,0 +1,39 @@
+#include
+#include
+
+//QBotanioAPI
+#include
+
+//Insert here your "botan.io" application key
+static const QString BOTANIO_APP_KEY = QStringLiteral("SOME_PRIVATE_KEY");
+static const int UNIQUE_SET_ID = 1234;//e.g. telegram user id
+static const QString EVENT_NAME = QStringLiteral("TEST_EVENT");
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication a(argc, argv);
+
+ //create a new "Botanio track API" instance on the heap
+ QBotanioTrackApi* pBotaino = QBotanioTrackApi::newInstance();
+
+ //prints result after "track" request is finished
+ QObject::connect(pBotaino,&QBotanioTrackApi::signalFinished,[](bool bResult, const QString& sResultDetails){
+ Q_UNUSED(bResult);qDebug()<<"result" << sResultDetails;
+ });
+
+ //close application after "track" request is finished
+ QObject::connect(pBotaino,&QBotanioTrackApi::signalFinished,&a,&QCoreApplication::quit);
+
+ //some metrics
+ QVariantMap params;
+ params["int_metric"] = 1234;
+ params["double_metric"] = 12.34;
+ params["string_metric"] = "1234";
+ params["bool_metric"] = true;
+ //call asynchronously "track" request
+ pBotaino->track(BOTANIO_APP_KEY, UNIQUE_SET_ID, EVENT_NAME, params);
+ //client don't neede to delete the pBotaino instance, because it is self destructed after HTTP request is finished
+ //delete pBotaino;
+
+ return a.exec();
+}
diff --git a/qt/example/track/qtbotaniotrack.pro b/qt/example/track/qtbotaniotrack.pro
new file mode 100644
index 0000000..99ac2bf
--- /dev/null
+++ b/qt/example/track/qtbotaniotrack.pro
@@ -0,0 +1,41 @@
+QT += core network
+QT -= gui
+CONFIG += c++11
+TARGET = qtbotaniotrack
+CONFIG += console
+CONFIG -= app_bundle
+TEMPLATE = app
+
+SOURCES += main.cpp
+
+INCLUDEPATH += ./../../qbotanio
+
+QMAKE_CLEAN += Makefile
+QMAKE_CLEAN += Makefile.$${TARGET}
+QMAKE_CLEAN += Makefile.$${TARGET}.Release
+QMAKE_CLEAN += Makefile.$${TARGET}.Debug
+QMAKE_CLEAN += Makefile.Release
+QMAKE_CLEAN += Makefile.Debug
+
+CONFIG(release, debug|release) {
+ DESTDIR = ./Release
+ MOC_DIR += $${DESTDIR}/.moc
+ OBJECTS_DIR += $${DESTDIR}/.obj
+ UI_DIR += $${DESTDIR}/.ui
+ RCC_DIR += $${DESTDIR}/.rcc
+ LIBS += -L../../qbotanio/Release -lqbotanio
+}
+else{
+ DESTDIR = ./Debug
+ MOC_DIR += $${DESTDIR}/.moc
+ OBJECTS_DIR += $${DESTDIR}/.obj
+ UI_DIR += $${DESTDIR}/.ui
+ RCC_DIR += $${DESTDIR}/.rcc
+ TARGET = $$join(TARGET,,,d)
+ LIBS += -L../../qbotanio/Debug -lqbotaniod
+}
+unix{
+ QMAKE_CXXFLAGS +=-std=c++11
+ target.path = /usr/bin
+ INSTALLS += target
+}
\ No newline at end of file
diff --git a/qt/example/urlshortener/main.cpp b/qt/example/urlshortener/main.cpp
new file mode 100644
index 0000000..1ea803d
--- /dev/null
+++ b/qt/example/urlshortener/main.cpp
@@ -0,0 +1,32 @@
+#include
+#include
+
+//QBotanioAPI
+#include
+
+//Insert here your "botan.io" application key
+static const QString BOTANIO_APP_KEY = QStringLiteral("YOUR_PRIVATE_KEY");
+static const int UNIQUE_SET_ID = 1234;//Telegram user id
+static const QString URL = QStringLiteral("https://github.com/botanio/sdk");
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication a(argc, argv);
+
+ //create a new "Botanio URL Shortener API" instance on the heap
+ QBotanioUrlShortenerAPI* pBotaino = QBotanioUrlShortenerAPI::newInstance();
+
+ //prints result after "shorten URL" request is finished
+ QObject::connect(pBotaino,&QBotanioUrlShortenerAPI::signalFinished,[](bool bResult, const QString& sShortenURL,const QString& sResultDetails){
+ qDebug()<<"result" << (bResult? sShortenURL : sResultDetails);
+ });
+
+ //close application after "shorten URL" request is finished
+ QObject::connect(pBotaino,&QBotanioUrlShortenerAPI::signalFinished,&a,&QCoreApplication::quit);
+
+ //call asynchronously "shortenURL" request
+ pBotaino->shortenUrlAsynch(BOTANIO_APP_KEY, UNIQUE_SET_ID, URL);
+ //client don't need to delete the pBotaino instance, because it is self destructed after HTTP request is finished
+ //delete pBotaino;
+ return a.exec();
+}
diff --git a/qt/example/urlshortener/qtbotaniourlshortener.pro b/qt/example/urlshortener/qtbotaniourlshortener.pro
new file mode 100644
index 0000000..b341f54
--- /dev/null
+++ b/qt/example/urlshortener/qtbotaniourlshortener.pro
@@ -0,0 +1,41 @@
+QT += core network
+QT -= gui
+CONFIG += c++11
+TARGET = qtbotaniourlshortener
+CONFIG += console
+CONFIG -= app_bundle
+TEMPLATE = app
+
+SOURCES += main.cpp
+
+INCLUDEPATH += ./../../qbotanio
+
+QMAKE_CLEAN += Makefile
+QMAKE_CLEAN += Makefile.$${TARGET}
+QMAKE_CLEAN += Makefile.$${TARGET}.Release
+QMAKE_CLEAN += Makefile.$${TARGET}.Debug
+QMAKE_CLEAN += Makefile.Release
+QMAKE_CLEAN += Makefile.Debug
+
+CONFIG(release, debug|release) {
+ DESTDIR = ./Release
+ MOC_DIR += $${DESTDIR}/.moc
+ OBJECTS_DIR += $${DESTDIR}/.obj
+ UI_DIR += $${DESTDIR}/.ui
+ RCC_DIR += $${DESTDIR}/.rcc
+ LIBS += -L../../qbotanio/Release -lqbotanio
+}
+else{
+ DESTDIR = ./Debug
+ MOC_DIR += $${DESTDIR}/.moc
+ OBJECTS_DIR += $${DESTDIR}/.obj
+ UI_DIR += $${DESTDIR}/.ui
+ RCC_DIR += $${DESTDIR}/.rcc
+ TARGET = $$join(TARGET,,,d)
+ LIBS += -L../../qbotanio/Debug -lqbotaniod
+}
+unix{
+ QMAKE_CXXFLAGS +=-std=c++11
+ target.path = /usr/bin
+ INSTALLS += target
+}
\ No newline at end of file
diff --git a/qt/qbotanio/private/qbotaniotrackapi_p.cpp b/qt/qbotanio/private/qbotaniotrackapi_p.cpp
new file mode 100644
index 0000000..ba49280
--- /dev/null
+++ b/qt/qbotanio/private/qbotaniotrackapi_p.cpp
@@ -0,0 +1,139 @@
+#include "stdafx.h"
+
+//Botanio API base URL
+static const QString BOTANIO_BASE_URL = QStringLiteral("https://api.botan.io/track");
+//Botanio base URL fragments names
+static const QString BOTANIO_BASE_TOKEN_FRAGMENT_NAME = QStringLiteral("token");
+static const QString BOTANIO_BASE_UID_FRAGMENT_NAME = QStringLiteral("uid");
+static const QString BOTANIO_BASE_NAME_FRAGMENT_NAME = QStringLiteral("name");
+
+//------------------------------------------------------------------------------------
+//@author max walter @date 09.12.2016
+QBotanioTrackApiPrivate::QBotanioTrackApiPrivate(QObject *parent)
+: QObject(parent)
+{
+ m_TimeoutTimer.setSingleShot(true);
+
+ connect(&m_TimeoutTimer , &QTimer::timeout, [this](){
+ if(m_pReply && m_pReply->isRunning()){
+ m_pReply->close();
+ }
+ });
+}
+//------------------------------------------------------------------------------------
+//@author max walter @date 06.12.2016
+QBotanioTrackApiPrivate::~QBotanioTrackApiPrivate()
+{
+
+}
+//------------------------------------------------------------------------------------
+//@author max walter @date 06.12.2016
+bool QBotanioTrackApiPrivate::track(const QString& sApiKey, int UID, const QString& sEventName, const QJsonDocument& params, int timeoutMs)
+{
+ bool bResult = false;
+ if (!m_pReply)
+ {
+ //setup URL
+ QString sFullUrl = QString("%1?%2=%3&%4=%5&%6=%7")
+ .arg(BOTANIO_BASE_URL)
+ .arg(BOTANIO_BASE_TOKEN_FRAGMENT_NAME)
+ .arg(sApiKey)
+ .arg(BOTANIO_BASE_UID_FRAGMENT_NAME)
+ .arg(QString::number(UID))
+ .arg(BOTANIO_BASE_NAME_FRAGMENT_NAME)
+ .arg(sEventName);
+
+ //pack JSON params
+ QByteArray ba = params.toJson();
+ QNetworkRequest request(sFullUrl);
+ request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant(QStringLiteral("application/json")));
+ request.setHeader(QNetworkRequest::ContentLengthHeader, QVariant(ba.size()));
+
+ //POST request
+ m_pReply = m_NAM.post(request, ba);
+ if (m_pReply)
+ {
+ connect(m_pReply, SIGNAL(finished()), this, SLOT(slotRequestFinished()));
+ bResult = true;
+ //timeout
+ if(timeoutMs > 0)
+ m_TimeoutTimer.start(timeoutMs);
+ }
+ }
+ return bResult;
+}
+//------------------------------------------------------------------------------------
+//@author max walter @date 06.12.2016
+bool QBotanioTrackApiPrivate::track(const QString &sApiKey, int UID, const QString &sEventName, int timeoutMs)
+{
+ return track(sApiKey, UID, sEventName,QJsonDocument(),timeoutMs);
+}
+//------------------------------------------------------------------------------------
+//@author max walter @date 06.12.2016
+bool QBotanioTrackApiPrivate::track(const QString &sApiKey, int UID, const QString &sEventName, const QVariantMap ¶ms, int timeoutMs)
+{
+ return track(sApiKey, UID, sEventName,QJsonDocument(QJsonObject::fromVariantMap(params)),timeoutMs);
+}
+
+//------------------------------------------------------------------------------------
+//@author max walter @date 06.12.2016
+bool QBotanioTrackApiPrivate::parseResult(QByteArray jsonResult, QString& sResult)
+{
+ bool bResult = false;
+ QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonResult);
+ if (!jsonDoc.isNull() && jsonDoc.isObject())
+ {
+ QJsonObject obj = jsonDoc.object();
+ if (obj.contains("status") )
+ {
+ //Status available?
+ QString sStatus = obj.value("status").toString();
+ if(sStatus == QStringLiteral("accepted"))
+ {
+ sResult = sStatus;
+ bResult = true;
+ }
+ else
+ if(sStatus == QStringLiteral("failed") || sStatus == QStringLiteral("bad request")){
+ sResult = sStatus;
+ bResult = false;
+ }
+
+ //Info availabvle?
+ if(obj.contains("info"))
+ sResult.append(QStringLiteral(" %1").arg(obj.value("info").toString()));
+ }
+ else
+ sResult = tr("Invalid json structure");
+ }
+ else
+ sResult = tr("Invalid json document");
+
+ return bResult;
+}
+//------------------------------------------------------------------------------------
+//@author max walter @date 06.12.2016
+void QBotanioTrackApiPrivate::slotRequestFinished()
+{
+ //stop timeout timer
+ m_TimeoutTimer.stop();
+ if (m_pReply)
+ {
+ bool bResult = false;
+ QNetworkReply::NetworkError error = m_pReply->error();
+ QString sResultDetails;
+ if (error == QNetworkReply::NoError)
+ {
+ QByteArray baResult = m_pReply->readAll();
+ bResult = parseResult(baResult, sResultDetails);
+ }
+ else
+ sResultDetails = tr("http request failed! %1").arg(m_pReply->errorString());
+
+ m_pReply->deleteLater();
+ m_pReply = nullptr;
+ //inform client
+ emit signalFinished(bResult, sResultDetails);
+ deleteLater();
+ }
+}
diff --git a/qt/qbotanio/private/qbotaniotrackapi_p.h b/qt/qbotanio/private/qbotaniotrackapi_p.h
new file mode 100644
index 0000000..da8329c
--- /dev/null
+++ b/qt/qbotanio/private/qbotaniotrackapi_p.h
@@ -0,0 +1,42 @@
+#ifndef QBOTANIOTRACKAPIPRIVATE_H
+#define QBOTANIOTRACKAPIPRIVATE_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+class QBotanioTrackApiPrivate : public QObject
+{
+ Q_OBJECT
+public:
+ QBotanioTrackApiPrivate(QObject *parent);
+ ~QBotanioTrackApiPrivate();
+public://method
+ //track event
+ bool track(const QString& sApiKey, int UID, const QString& sEventName,int timeoutMs = 30000);
+ //track event with params as varaint map
+ bool track(const QString& sApiKey, int UID, const QString& sEventName,const QVariantMap& params,int timeoutMs = 30000);
+ //track event with params as json document
+ bool track(const QString& sApiKey, int UID, const QString& sEventName,const QJsonDocument& params,int timeoutMs = 30000);
+signals:
+ //Informs clients about request is finished
+ void signalFinished(bool bResult, const QString& sResultDetails);
+protected:
+ bool parseResult(QByteArray jsonResult, QString &sResult);
+protected slots:
+ void slotRequestFinished();
+private:
+ //Network access manager
+ QNetworkAccessManager m_NAM;
+ //reply for current request
+ QPointer m_pReply = nullptr;
+ //timeout timer
+ QTimer m_TimeoutTimer;
+
+};
+#endif // QBOTANIOTRACKAPIPRIVATE_H
diff --git a/qt/qbotanio/private/qbotaniourlshortenerapi_p.cpp b/qt/qbotanio/private/qbotaniourlshortenerapi_p.cpp
new file mode 100644
index 0000000..057c54e
--- /dev/null
+++ b/qt/qbotanio/private/qbotaniourlshortenerapi_p.cpp
@@ -0,0 +1,109 @@
+#include "stdafx.h"
+
+//Botanuio URL-Shortener service URL
+static const QString BOTANIO_URL_SHORTENER_SERVICE_URL = QStringLiteral("https://api.botan.io/s/");
+//Botanio URL-Shortener URL fragments names
+static const QString BOTANIO_URL_SHORTENER_TOKEN_FRAGMENT_NAME = QStringLiteral("token");
+static const QString BOTANIO_URL_SHORTENER_URL_FRAGMENT_NAME = QStringLiteral("url");
+static const QString BOTANIO_URL_SHORTENER_USERID_FRAGMENT_NAME = QStringLiteral("user_ids");
+
+//------------------------------------------------------------------------------------
+//@author max walter @date 06.12.2016
+QBotanioUrlShortenerAPIPrivate::QBotanioUrlShortenerAPIPrivate(QObject *parent)
+ : QObject(parent)
+{
+ m_TimeoutTimer.setSingleShot(true);
+
+ connect(&m_TimeoutTimer , &QTimer::timeout, [this](){
+ if(m_pReply && m_pReply->isRunning()){
+ m_pReply->close();
+ }
+ });
+
+}
+//------------------------------------------------------------------------------------
+//@author max walter @date 06.12.2016
+QBotanioUrlShortenerAPIPrivate::~QBotanioUrlShortenerAPIPrivate()
+{
+
+}
+//------------------------------------------------------------------------------------
+//@author max walter @date 06.12.2016
+bool QBotanioUrlShortenerAPIPrivate::shortenUrlAsynch(const QString& sApiKey, int UID, const QString& sUrl, int timeoutMs)
+{
+ bool bResult = false;
+ if (!m_pReply)
+ {
+ //setup URL
+ QString sFullUrl = QString("%1?%2=%3&%4=%5&%6=%7")
+ .arg(BOTANIO_URL_SHORTENER_SERVICE_URL)
+ .arg(BOTANIO_URL_SHORTENER_TOKEN_FRAGMENT_NAME)
+ .arg(sApiKey)
+ .arg(BOTANIO_URL_SHORTENER_URL_FRAGMENT_NAME)
+ .arg(sUrl)
+ .arg(BOTANIO_URL_SHORTENER_USERID_FRAGMENT_NAME)
+ .arg(QString::number(UID));
+
+ //stack request together
+ QNetworkRequest request(sFullUrl);
+ //POST request
+ m_pReply = m_NAM.get(request);
+ if (m_pReply)
+ {
+ connect(m_pReply, SIGNAL(finished()), this, SLOT(slotRequestFinished()));
+ bResult = true;
+ //timeout
+ if(timeoutMs > 0)
+ m_TimeoutTimer.start(timeoutMs);
+ }
+ }
+ return bResult;
+}
+//------------------------------------------------------------------------------------
+//@author max walter @date 06.12.2016
+QString QBotanioUrlShortenerAPIPrivate::shortenUrl(const QString &sApiKey, int UID, const QString &sUrlToBeShorten, bool &bResult, QString &sResultDetails, int timeoutMs)
+{
+ QString sResultUrl = sUrlToBeShorten;
+ bResult = shortenUrlAsynch(sApiKey, UID, sUrlToBeShorten, timeoutMs);
+ if(bResult)
+ {
+ //Lokal "event loop" instance
+ QEventLoop loop;
+ QObject::connect(this, &QBotanioUrlShortenerAPIPrivate::signalFinished, &loop, &QEventLoop::quit);
+ connect(this, &QBotanioUrlShortenerAPIPrivate::signalFinished,[this,&sResultUrl,&sResultDetails,&bResult](bool result, const QString& sShortenURL,const QString& sResult){
+ bResult = result;
+ if(bResult)
+ sResultUrl = sShortenURL;
+ sResultDetails = sResult;
+ });
+ loop.exec();
+ }
+ return sResultUrl;
+}
+//------------------------------------------------------------------------------------
+//@author max walter @date 06.12.2016
+void QBotanioUrlShortenerAPIPrivate::slotRequestFinished()
+{
+ //stop timeout timer
+ m_TimeoutTimer.stop();
+ if (m_pReply)
+ {
+ QString sShortenURL;
+ QString sResultDetails;
+ bool bResult = false;
+ QNetworkReply::NetworkError error = m_pReply->error();
+ if (error == QNetworkReply::NoError)
+ {
+ sShortenURL = m_pReply->readAll();
+ bResult = true;
+ }
+ else
+ sResultDetails = tr("http request failed! %1").arg(m_pReply->errorString());
+
+ m_pReply->deleteLater();
+ m_pReply = nullptr;
+ //inform client
+ emit signalFinished(bResult, sShortenURL, sResultDetails);
+ deleteLater();
+ }
+}
diff --git a/qt/qbotanio/private/qbotaniourlshortenerapi_p.h b/qt/qbotanio/private/qbotaniourlshortenerapi_p.h
new file mode 100644
index 0000000..4827c6e
--- /dev/null
+++ b/qt/qbotanio/private/qbotaniourlshortenerapi_p.h
@@ -0,0 +1,36 @@
+#ifndef QBOTANIOURLSHORTENERAPIPRIVATE_H
+#define QBOTANIOURLSHORTENERAPIPRIVATE_H
+
+#include
+#include
+#include
+#include
+#include
+
+class QBotanioUrlShortenerAPIPrivate : public QObject
+{
+ Q_OBJECT
+public:
+ QBotanioUrlShortenerAPIPrivate(QObject *parent = 0);
+ ~QBotanioUrlShortenerAPIPrivate();
+public:
+ //get shorten URL synchronously
+ QString shortenUrl(const QString& sApiKey, int UID, const QString& sUrltobeShorten, bool& bResult, QString& sResultDetails, int timeoutMs = 30000);
+ //get shorten URL asynchronously
+ bool shortenUrlAsynch(const QString& sApiKey, int UID, const QString& sUrl,int timeoutMs = 30000);
+signals:
+ //Informs clients about request is finished
+ void signalFinished(bool bResult, const QString& sShortenURL,const QString& sResultDetails);
+protected slots:
+ void slotRequestFinished();
+private:
+ //Network access manager
+ QNetworkAccessManager m_NAM;
+ //reply for current request
+ QPointer m_pReply = nullptr;
+ //timeout timer
+ QTimer m_TimeoutTimer;
+};
+
+
+#endif // QBOTANIOURLSHORTENERAPIPRIVATE_H
diff --git a/qt/qbotanio/qbotanio.pri b/qt/qbotanio/qbotanio.pri
new file mode 100644
index 0000000..8792faa
--- /dev/null
+++ b/qt/qbotanio/qbotanio.pri
@@ -0,0 +1,11 @@
+SOURCES += $$PWD/qbotaniotrackapi.cpp \
+ $$PWD/qbotaniourlshortenerapi.cpp \
+ $$PWD/private/qbotaniotrackapi_p.cpp \
+ $$PWD/private/qbotaniourlshortenerapi_p.cpp
+
+HEADERS += $$PWD/qbotanio_global.h \
+ $$PWD/stdafx.h \
+ $$PWD/qbotaniotrackapi.h \
+ $$PWD/qbotaniourlshortenerapi.h \
+ $$PWD/private/qbotaniotrackapi_p.h \
+ $$PWD/private/qbotaniourlshortenerapi_p.h
diff --git a/qt/qbotanio/qbotanio.pro b/qt/qbotanio/qbotanio.pro
new file mode 100644
index 0000000..60daeca
--- /dev/null
+++ b/qt/qbotanio/qbotanio.pro
@@ -0,0 +1,53 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2016-12-09T13:57:33
+#
+#-------------------------------------------------
+
+QT += network
+QT -= gui
+TARGET = qbotanio
+TEMPLATE = lib
+
+DEFINES += QBOTANIO_LIBRARY
+PRECOMPILED_HEADER = stdafx.h
+
+
+QMAKE_CLEAN += Makefile
+QMAKE_CLEAN += Makefile.$${TARGET}
+QMAKE_CLEAN += Makefile.$${TARGET}.Release
+QMAKE_CLEAN += Makefile.$${TARGET}.Debug
+QMAKE_CLEAN += Makefile.Release
+QMAKE_CLEAN += Makefile.Debug
+
+CONFIG(release, debug|release) {
+ DESTDIR = ./Release
+ MOC_DIR += $${DESTDIR}/.moc
+ OBJECTS_DIR += $${DESTDIR}/.obj
+ UI_DIR += $${DESTDIR}/.ui
+ RCC_DIR += $${DESTDIR}/.rcc
+}
+else{
+ DESTDIR = ./Debug
+ MOC_DIR += $${DESTDIR}/.moc
+ OBJECTS_DIR += $${DESTDIR}/.obj
+ UI_DIR += $${DESTDIR}/.ui
+ RCC_DIR += $${DESTDIR}/.rcc
+ TARGET = $$join(TARGET,,,d)
+ DEFINES += _DEBUG
+}
+
+win32{
+ QMAKE_CLEAN += $$DESTDIR/$${TARGET}.lib
+ QMAKE_CLEAN += $$DESTDIR/$${TARGET}.dll
+ QMAKE_CLEAN += $$DESTDIR/$${TARGET}.pdb
+}
+unix{
+ QMAKE_CLEAN += $$DESTDIR/lib$${TARGET}.so*
+ QMAKE_CXXFLAGS += -std=c++11
+
+ target.path = /usr/lib
+ INSTALLS += target
+}
+
+include(qbotanio.pri)
diff --git a/qt/qbotanio/qbotanio_global.h b/qt/qbotanio/qbotanio_global.h
new file mode 100644
index 0000000..a24a077
--- /dev/null
+++ b/qt/qbotanio/qbotanio_global.h
@@ -0,0 +1,16 @@
+#ifndef QBOTANIO_GLOBAL_H
+#define QBOTANIO_GLOBAL_H
+
+#include
+
+/**
+ * @author Maximilian Walter
+ * @since 2016-12-03 15:00
+ */
+#if defined(QBOTANIO_LIBRARY)
+# define QBOTANIOSHARED_EXPORT Q_DECL_EXPORT
+#else
+# define QBOTANIOSHARED_EXPORT Q_DECL_IMPORT
+#endif
+
+#endif // QBOTANIO_GLOBAL_H
diff --git a/qt/qbotanio/qbotaniotrackapi.cpp b/qt/qbotanio/qbotaniotrackapi.cpp
new file mode 100644
index 0000000..8f05384
--- /dev/null
+++ b/qt/qbotanio/qbotaniotrackapi.cpp
@@ -0,0 +1,46 @@
+#include "stdafx.h"
+
+//------------------------------------------------------------------------------------
+//------------------------------------------------------------------------------------
+//------------------------------------------------------------------------------------
+//------------------------------------------------------------------------------------
+//------------------------------------------------------------------------------------
+//------------------------------------------------------------------------------------
+//------------------------------------------------------------------------------------
+//@author max walter @date 05.12.2016
+QBotanioTrackApi *QBotanioTrackApi::newInstance()
+{
+ return new QBotanioTrackApi();
+}
+//------------------------------------------------------------------------------------
+//@author max walter @date 05.12.2016
+QBotanioTrackApi::QBotanioTrackApi()
+ : QObject(nullptr), d(new QBotanioTrackApiPrivate(this))
+{
+ connect(d.data(), SIGNAL(signalFinished(bool, const QString&)),
+ this, SIGNAL(signalFinished(bool, const QString&)));
+}
+//------------------------------------------------------------------------------------
+//@author max walter @date 05.12.2016
+QBotanioTrackApi::~QBotanioTrackApi()
+{
+
+}
+//------------------------------------------------------------------------------------
+//@author max walter @date 05.12.2016
+bool QBotanioTrackApi::track(const QString& sApiKey, int UID, const QString& sEventName, const QJsonDocument& params, int timeoutMs)
+{
+ return d->track(sApiKey, UID, sEventName, params, timeoutMs);
+}
+//------------------------------------------------------------------------------------
+//@author max walter @date 06.12.2016
+bool QBotanioTrackApi::track(const QString &sApiKey, int UID, const QString &sEventName, int timeoutMs)
+{
+ return d->track(sApiKey, UID, sEventName,timeoutMs);
+}
+//------------------------------------------------------------------------------------
+//@author max walter @date 05.12.2016
+bool QBotanioTrackApi::track(const QString &sApiKey, int UID, const QString &sEventName, const QVariantMap ¶ms, int timeoutMs)
+{
+ return d->track(sApiKey, UID, sEventName,params,timeoutMs);
+}
diff --git a/qt/qbotanio/qbotaniotrackapi.h b/qt/qbotanio/qbotaniotrackapi.h
new file mode 100644
index 0000000..2bd581b
--- /dev/null
+++ b/qt/qbotanio/qbotaniotrackapi.h
@@ -0,0 +1,37 @@
+#ifndef QBOTANIOAPI_H
+#define QBOTANIOAPI_H
+#include "qbotanio_global.h"
+
+#include
+
+/**
+ * Simple asynchronous "track" client implementation with Qt5.5 for Botan.io https://botan.io
+
+ * @author Maximilian Walter
+ * @since 2016-12-03 15:00
+ */
+class QBotanioTrackApiPrivate;
+class QBOTANIOSHARED_EXPORT QBotanioTrackApi : public QObject
+{
+ Q_OBJECT
+public:
+ static QBotanioTrackApi * newInstance();
+public://method
+ //track event
+ bool track(const QString& sApiKey, int UID, const QString& sEventName,int timeoutMs = 30000);
+ //track event with params as varaint map
+ bool track(const QString& sApiKey, int UID, const QString& sEventName,const QVariantMap& params,int timeoutMs = 30000);
+ //track event with params as json document
+ bool track(const QString& sApiKey, int UID, const QString& sEventName,const QJsonDocument& params,int timeoutMs = 30000);
+signals:
+ //Informs clients about request is finished
+ void signalFinished(bool bResult, const QString& sResultDetails);
+private :
+ //shouldn't be called from clients. Use static QBotanioTrackApi * newInstance();
+ QBotanioTrackApi();
+ ~QBotanioTrackApi();
+ //PIMPL
+ const QScopedPointer d;
+};
+
+#endif // QBOTANIOAPI_H
diff --git a/qt/qbotanio/qbotaniourlshortenerapi.cpp b/qt/qbotanio/qbotaniourlshortenerapi.cpp
new file mode 100644
index 0000000..87859f7
--- /dev/null
+++ b/qt/qbotanio/qbotaniourlshortenerapi.cpp
@@ -0,0 +1,36 @@
+#include "stdafx.h"
+
+//------------------------------------------------------------------------------------
+//@author max walter @date 06.12.2016
+QBotanioUrlShortenerAPI *QBotanioUrlShortenerAPI::newInstance()
+{
+ return new QBotanioUrlShortenerAPI();
+}
+//------------------------------------------------------------------------------------
+//@author max walter @date 06.12.2016
+QBotanioUrlShortenerAPI::QBotanioUrlShortenerAPI()
+ : QObject(nullptr), d(new QBotanioUrlShortenerAPIPrivate(this))
+{
+
+ connect(d.data(), SIGNAL(signalFinished(bool, const QString&,const QString&)),
+ this, SIGNAL(signalFinished(bool, const QString&,const QString&)));
+}
+//------------------------------------------------------------------------------------
+//@author max walter @date 06.12.2016
+QBotanioUrlShortenerAPI::~QBotanioUrlShortenerAPI()
+{
+
+}
+
+//------------------------------------------------------------------------------------
+//@author max walter @date 06.12.2016
+QString QBotanioUrlShortenerAPI::shortenUrl(const QString &sApiKey, int UID, const QString &sUrlToBeShorten, bool &bResult, QString &sResultDetails, int timeoutMs)
+{
+ return d->shortenUrl(sApiKey, UID, sUrlToBeShorten, bResult, sResultDetails, timeoutMs);
+}
+//------------------------------------------------------------------------------------
+//@author max walter @date 06.12.2016
+bool QBotanioUrlShortenerAPI::shortenUrlAsynch(const QString& sApiKey, int UID, const QString& sUrl, int timeoutMs)
+{
+ return d->shortenUrlAsynch(sApiKey, UID, sUrl, timeoutMs);
+}
diff --git a/qt/qbotanio/qbotaniourlshortenerapi.h b/qt/qbotanio/qbotaniourlshortenerapi.h
new file mode 100644
index 0000000..d99bcd9
--- /dev/null
+++ b/qt/qbotanio/qbotaniourlshortenerapi.h
@@ -0,0 +1,34 @@
+#ifndef QBOTANIOURLSHORTENERAPI_H
+#define QBOTANIOURLSHORTENERAPI_H
+#include "qbotanio_global.h"
+
+#include
+/**
+ * Simple (a)synchronous "shorten URL" client implementation with Qt5.5 for Botan.io https://botan.io
+ *
+ * @author Maximilian Walter
+ * @since 2016-12-03 15:00
+ */
+class QBotanioUrlShortenerAPIPrivate;
+class QBOTANIOSHARED_EXPORT QBotanioUrlShortenerAPI : public QObject
+{
+ Q_OBJECT
+public:
+ static QBotanioUrlShortenerAPI * newInstance();
+public:
+ //get shorten URL synchronously
+ QString shortenUrl(const QString& sApiKey, int UID, const QString& sUrlToBeShorten, bool& bResult, QString& sResultDetails, int timeoutMs = 30000);
+ //get shorten URL asynchronously
+ bool shortenUrlAsynch(const QString& sApiKey, int UID, const QString& sUrl,int timeoutMs = 30000);
+signals:
+ //Informs clients about request is finished
+ void signalFinished(bool bResult, const QString& sShortenURL,const QString& sResultDetails);
+private:
+ //shouldn't be called from clients. Use static QBotanioUrlShortenerAPI * newInstance();
+ QBotanioUrlShortenerAPI();
+ ~QBotanioUrlShortenerAPI();
+ //PIMPL
+ const QScopedPointer d;
+};
+
+#endif // QBOTANIOURLSHORTENERAPI_H
diff --git a/qt/qbotanio/stdafx.h b/qt/qbotanio/stdafx.h
new file mode 100644
index 0000000..227a368
--- /dev/null
+++ b/qt/qbotanio/stdafx.h
@@ -0,0 +1,13 @@
+#ifndef STDAFX_H
+#define STDAFX_H
+//qt
+#include
+#include
+
+//Own
+#include "qbotaniotrackapi.h"
+#include "private/qbotaniotrackapi_p.h"
+#include "qbotaniourlshortenerapi.h"
+#include "private/qbotaniourlshortenerapi_p.h"
+
+#endif // STDAFX_H
diff --git a/qt/track_example.pro b/qt/track_example.pro
new file mode 100644
index 0000000..6f88562
--- /dev/null
+++ b/qt/track_example.pro
@@ -0,0 +1,12 @@
+TEMPLATE = subdirs
+SUBDIRS += botanioapi \
+ example
+
+#pro files
+example.file = example/track/qtbotaniotrack.pro
+botanioapi.file = qbotanio/qbotanio.pro
+
+#dependencies
+example.depends = botanioapi
+
+QMAKE_CLEAN += Makefile
\ No newline at end of file
diff --git a/qt/urlshortener_example.pro b/qt/urlshortener_example.pro
new file mode 100644
index 0000000..c2555cb
--- /dev/null
+++ b/qt/urlshortener_example.pro
@@ -0,0 +1,12 @@
+TEMPLATE = subdirs
+SUBDIRS += botanioapi \
+ example
+
+#pro files
+example.file = example/urlshortener/qtbotaniourlshortener.pro
+botanioapi.file = qbotanio/qbotanio.pro
+
+#dependencies
+example.depends = botanioapi
+
+QMAKE_CLEAN += Makefile
\ No newline at end of file