Commit 618e1108 authored by Volker Krause's avatar Volker Krause

Implement survey targeting in the provider class

parent 8eb1ead7
......@@ -12,7 +12,7 @@ Framework for collecting feedback from application users. This currently consist
## Surveys
* Distribute surveys and offer users to participate in them.
* Survey targeting based on telemetry data [TODO].
* Survey targeting based on telemetry data.
* Allow the user to configure how often they want to participate in surveys.
## Components
......
......@@ -27,4 +27,5 @@ if(Qt5Core_FOUND)
target_link_libraries(UserFeedbackCommon LINK_PRIVATE Qt5::Core)
else()
target_link_libraries(UserFeedbackCommon LINK_PRIVATE ${QT_QTCORE_LIBS})
set_target_properties(UserFeedbackCommon PROPERTIES POSITION_INDEPENDENT_CODE ON)
endif()
......@@ -30,9 +30,9 @@ SurveyTargetExpression::SurveyTargetExpression(const QString& source, const QVar
, m_source(source)
, m_sourceElement(elem)
{
if (index.type() == QMetaType::Int)
if (index.type() == QVariant::Int)
m_type = ListElement;
else if (index.type() == QMetaType::QString)
else if (index.type() == QVariant::String)
m_type = MapElement;
else
m_type = ScalarElement;
......
......@@ -20,6 +20,10 @@
using namespace UserFeedback;
SurveyTargetExpressionDataProvider::~SurveyTargetExpressionDataProvider()
{
}
SurveyTargetExpressionEvaluator::SurveyTargetExpressionEvaluator()
: m_provider(nullptr)
{
......@@ -29,7 +33,7 @@ SurveyTargetExpressionEvaluator::~SurveyTargetExpressionEvaluator()
{
}
void SurveyTargetExpressionEvaluator::setDataProvider(SurveyTargetExpressionDataProvider* provider)
void SurveyTargetExpressionEvaluator::setDataProvider(const SurveyTargetExpressionDataProvider* provider)
{
m_provider = provider;
}
......
......@@ -30,6 +30,7 @@ class SurveyTargetExpression;
class SurveyTargetExpressionDataProvider
{
public:
virtual ~SurveyTargetExpressionDataProvider();
virtual QVariant sourceData(const QString &sourceName) const = 0;
};
......@@ -39,7 +40,7 @@ public:
SurveyTargetExpressionEvaluator();
~SurveyTargetExpressionEvaluator();
void setDataProvider(SurveyTargetExpressionDataProvider *provider);
void setDataProvider(const SurveyTargetExpressionDataProvider *provider);
bool evaluate(SurveyTargetExpression *expression);
......@@ -47,7 +48,7 @@ private:
QVariant value(SurveyTargetExpression *expression);
QVariant value(const QString &source);
SurveyTargetExpressionDataProvider *m_provider;
const SurveyTargetExpressionDataProvider *m_provider;
QHash<QString, QVariant> m_dataCache;
};
......
......@@ -24,6 +24,7 @@ if(Qt5Core_FOUND)
else()
target_link_libraries(UserFeedbackCore PUBLIC ${QT_QTCORE_LIBRARIES} PRIVATE ${QT_QTGUI_LIBRARIES} ${QT_QTNETWORK_LIBRARIES})
endif()
target_link_libraries(UserFeedbackCore PRIVATE UserFeedbackCommon)
target_include_directories(UserFeedbackCore PUBLIC "$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/src;${CMAKE_CURRENT_BINARY_DIR};>")
install(TARGETS UserFeedbackCore EXPORT UserFeedbackTargets ${INSTALL_TARGETS_DEFAULT_ARGS})
......
......@@ -25,6 +25,9 @@
#include "surveyinfo.h"
#include "usagetimesource.h"
#include <common/surveytargetexpressionparser.h>
#include <common/surveytargetexpressionevaluator.h>
#include <QCoreApplication>
#include <QDebug>
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
......@@ -264,15 +267,37 @@ void ProviderPrivate::submitFinished()
scheduleNextSubmission();
}
QVariant ProviderPrivate::sourceData(const QString& sourceName) const
{
foreach (auto src, dataSources) {
if (src->name() == sourceName)
return src->data();
}
return QVariant();
}
bool ProviderPrivate::selectSurvey(const SurveyInfo &survey) const
{
qCDebug(Log) << "got survey:" << survey.url();
qCDebug(Log) << "got survey:" << survey.url() << survey.target();
if (!survey.isValid() || completedSurveys.contains(QString::number(survey.id())))
return false;
if (lastSurveyTime.addDays(surveyInterval) > QDateTime::currentDateTime())
return false;
if (!survey.target().isEmpty()) {
SurveyTargetExpressionParser parser;
if (!parser.parse(survey.target())) {
qCDebug(Log) << "failed to parse target expression";
return false;
}
SurveyTargetExpressionEvaluator eval;
eval.setDataProvider(this);
if (!eval.evaluate(parser.expression()))
return false;
}
emit q->surveyAvailable(survey);
return true;
}
......
......@@ -20,6 +20,8 @@
#include "provider.h"
#include <common/surveytargetexpressionevaluator.h>
#include <QDateTime>
#include <QStringList>
#include <QTime>
......@@ -31,7 +33,7 @@ class QNetworkAccessManager;
QT_END_NAMESPACE
namespace UserFeedback {
class ProviderPrivate
class ProviderPrivate : public SurveyTargetExpressionDataProvider
{
public:
ProviderPrivate(Provider *qq);
......@@ -55,6 +57,8 @@ public:
void scheduleEncouragement();
void emitShowEncouragementMessage();
QVariant sourceData(const QString &sourceName) const override;
Provider *q;
QString productId;
......
......@@ -32,6 +32,7 @@ public:
int id;
QUrl url;
QString target;
};
SurveyInfoData::SurveyInfoData()
......@@ -75,12 +76,23 @@ void SurveyInfo::setUrl(const QUrl& url)
d->url = url;
}
QString SurveyInfo::target() const
{
return d->target;
}
void SurveyInfo::setTarget(const QString &target)
{
d->target = target;
}
SurveyInfo SurveyInfo::fromJson(const QJsonObject& obj)
{
SurveyInfo s;
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
s.setId(obj.value(QStringLiteral("id")).toInt());
s.setUrl(QUrl(obj.value(QStringLiteral("url")).toString()));
s.setId(obj.value(QLatin1String("id")).toInt());
s.setUrl(QUrl(obj.value(QLatin1String("url")).toString()));
s.setTarget(obj.value(QLatin1String("target")).toString());
#endif
return s;
}
......@@ -54,9 +54,13 @@ public:
/*! The URL to the survey website. */
QUrl url() const;
/*! The survey targeting expression. */
QString target() const;
///@cond internal
void setId(int id);
void setUrl(const QUrl &url);
void setTarget(const QString &target);
static SurveyInfo fromJson(const QJsonObject &obj);
///@endcond
private:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment