mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 16:55:07 +02:00
Merge pull request #3101 from Atlante45/add_interface_to_log_user_activity
Add interface to log user activity
This commit is contained in:
commit
5d789ec108
8 changed files with 226 additions and 2 deletions
|
@ -60,6 +60,7 @@
|
|||
#include <ParticlesScriptingInterface.h>
|
||||
#include <PerfStat.h>
|
||||
#include <ResourceCache.h>
|
||||
#include <UserActivityLogger.h>
|
||||
#include <UUID.h>
|
||||
#include <OctreeSceneStats.h>
|
||||
#include <LocalVoxelsList.h>
|
||||
|
@ -268,6 +269,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
|||
|
||||
// set the account manager's root URL and trigger a login request if we don't have the access token
|
||||
accountManager.setAuthURL(DEFAULT_NODE_AUTH_URL);
|
||||
UserActivityLogger::getInstance().launch(applicationVersion());
|
||||
|
||||
// once the event loop has started, check and signal for an access token
|
||||
QMetaObject::invokeMethod(&accountManager, "checkAndSignalForAccessToken", Qt::QueuedConnection);
|
||||
|
@ -396,7 +398,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
|||
}
|
||||
|
||||
Application::~Application() {
|
||||
|
||||
int DELAY_TIME = 1000;
|
||||
UserActivityLogger::getInstance().close(DELAY_TIME);
|
||||
|
||||
qInstallMessageHandler(NULL);
|
||||
|
||||
// make sure we don't call the idle timer any more
|
||||
|
@ -3577,6 +3581,7 @@ ScriptEngine* Application::loadScript(const QString& scriptName, bool loadScript
|
|||
|
||||
_scriptEnginesHash.insertMulti(scriptURLString, scriptEngine);
|
||||
_runningScriptsWidget->setRunningScripts(getRunningScripts());
|
||||
UserActivityLogger::getInstance().loadedScript(scriptURLString);
|
||||
}
|
||||
|
||||
// setup the packet senders and jurisdiction listeners of the script engine's scripting interfaces so
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <QOpenGLFramebufferObject>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <UserActivityLogger.h>
|
||||
|
||||
#include "Application.h"
|
||||
|
||||
|
@ -61,6 +62,9 @@ void OculusManager::connect() {
|
|||
|
||||
_ovrHmd = ovrHmd_Create(0);
|
||||
if (_ovrHmd) {
|
||||
if (!_isConnected) {
|
||||
UserActivityLogger::getInstance().connectedDevice("hmd", "oculus");
|
||||
}
|
||||
_isConnected = true;
|
||||
|
||||
ovrHmd_GetDesc(_ovrHmd, &_ovrHmdDesc);
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include "Application.h"
|
||||
#include "SixenseManager.h"
|
||||
#include "UserActivityLogger.h"
|
||||
|
||||
#ifdef HAVE_SIXENSE
|
||||
const int CALIBRATION_STATE_IDLE = 0;
|
||||
|
@ -39,6 +40,7 @@ SixenseManager::SixenseManager() {
|
|||
|
||||
sixenseInit();
|
||||
#endif
|
||||
_hydrasConnected = false;
|
||||
_triggerPressed[0] = false;
|
||||
_bumperPressed[0] = false;
|
||||
_oldX[0] = -1;
|
||||
|
@ -70,7 +72,11 @@ void SixenseManager::setFilter(bool filter) {
|
|||
void SixenseManager::update(float deltaTime) {
|
||||
#ifdef HAVE_SIXENSE
|
||||
if (sixenseGetNumActiveControllers() == 0) {
|
||||
_hydrasConnected = false;
|
||||
return;
|
||||
} else if (!_hydrasConnected) {
|
||||
_hydrasConnected = true;
|
||||
UserActivityLogger::getInstance().connectedDevice("spatial_controller", "hydra");
|
||||
}
|
||||
MyAvatar* avatar = Application::getInstance()->getAvatar();
|
||||
Hand* hand = avatar->getHand();
|
||||
|
|
|
@ -71,6 +71,7 @@ private:
|
|||
float _lastDistance;
|
||||
|
||||
#endif
|
||||
bool _hydrasConnected;
|
||||
quint64 _lastMovement;
|
||||
glm::vec3 _amountMoved;
|
||||
|
||||
|
|
|
@ -12,8 +12,9 @@
|
|||
|
||||
#include "Application.h"
|
||||
#include "Menu.h"
|
||||
#include "PreferencesDialog.h"
|
||||
#include "ModelsBrowser.h"
|
||||
#include "PreferencesDialog.h"
|
||||
#include "UserActivityLogger.h"
|
||||
|
||||
const int SCROLL_PANEL_BOTTOM_MARGIN = 30;
|
||||
const int OK_BUTTON_RIGHT_MARGIN = 30;
|
||||
|
@ -176,6 +177,7 @@ void PreferencesDialog::savePreferences() {
|
|||
QString displayNameStr(ui.displayNameEdit->text());
|
||||
if (displayNameStr != _displayNameString) {
|
||||
myAvatar->setDisplayName(displayNameStr);
|
||||
UserActivityLogger::getInstance().changedDisplayName(displayNameStr);
|
||||
shouldDispatchIdentityPacket = true;
|
||||
}
|
||||
|
||||
|
@ -183,6 +185,7 @@ void PreferencesDialog::savePreferences() {
|
|||
if (faceModelURL.toString() != _faceURLString) {
|
||||
// change the faceModelURL in the profile, it will also update this user's BlendFace
|
||||
myAvatar->setFaceModelURL(faceModelURL);
|
||||
UserActivityLogger::getInstance().changedModel("head", faceModelURL.toString());
|
||||
shouldDispatchIdentityPacket = true;
|
||||
}
|
||||
|
||||
|
@ -190,6 +193,7 @@ void PreferencesDialog::savePreferences() {
|
|||
if (skeletonModelURL.toString() != _skeletonURLString) {
|
||||
// change the skeletonModelURL in the profile, it will also update this user's Body
|
||||
myAvatar->setSkeletonModelURL(skeletonModelURL);
|
||||
UserActivityLogger::getInstance().changedModel("skeleton", skeletonModelURL.toString());
|
||||
shouldDispatchIdentityPacket = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "NodeList.h"
|
||||
#include "PacketHeaders.h"
|
||||
#include "UserActivityLogger.h"
|
||||
|
||||
#include "DomainHandler.h"
|
||||
|
||||
|
@ -83,6 +84,7 @@ void DomainHandler::setHostname(const QString& hostname) {
|
|||
qDebug("Looking up DS hostname %s.", _hostname.toLocal8Bit().constData());
|
||||
QHostInfo::lookupHost(_hostname, this, SLOT(completedHostnameLookup(const QHostInfo&)));
|
||||
|
||||
UserActivityLogger::getInstance().changedDomain(_hostname);
|
||||
emit hostnameChanged(_hostname);
|
||||
}
|
||||
}
|
||||
|
|
155
libraries/networking/src/UserActivityLogger.cpp
Normal file
155
libraries/networking/src/UserActivityLogger.cpp
Normal file
|
@ -0,0 +1,155 @@
|
|||
//
|
||||
// UserActivityLogger.cpp
|
||||
//
|
||||
//
|
||||
// Created by Clement on 5/21/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "UserActivityLogger.h"
|
||||
|
||||
#include <QEventLoop>
|
||||
#include <QJsonDocument>
|
||||
#include <QHttpMultiPart>
|
||||
#include <QTimer>
|
||||
|
||||
static const QString USER_ACTIVITY_URL = "/api/v1/user_activities";
|
||||
|
||||
UserActivityLogger& UserActivityLogger::getInstance() {
|
||||
static UserActivityLogger sharedInstance;
|
||||
return sharedInstance;
|
||||
}
|
||||
|
||||
UserActivityLogger::UserActivityLogger() {
|
||||
}
|
||||
|
||||
void UserActivityLogger::logAction(QString action, QJsonObject details, JSONCallbackParameters params) {
|
||||
AccountManager& accountManager = AccountManager::getInstance();
|
||||
QHttpMultiPart* multipart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
|
||||
|
||||
// Adding the action name
|
||||
QHttpPart actionPart;
|
||||
actionPart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"action_name\"");
|
||||
actionPart.setBody(QByteArray().append(action));
|
||||
multipart->append(actionPart);
|
||||
|
||||
// If there are action details, add them to the multipart
|
||||
if (!details.isEmpty()) {
|
||||
QHttpPart detailsPart;
|
||||
detailsPart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data;"
|
||||
" name=\"action_details\"");
|
||||
detailsPart.setBody(QJsonDocument(details).toJson(QJsonDocument::Compact));
|
||||
multipart->append(detailsPart);
|
||||
}
|
||||
qDebug() << "Logging activity" << action;
|
||||
|
||||
// if no callbacks specified, call our owns
|
||||
if (params.isEmpty()) {
|
||||
params.jsonCallbackReceiver = this;
|
||||
params.jsonCallbackMethod = "requestFinished";
|
||||
params.errorCallbackReceiver = this;
|
||||
params.errorCallbackMethod = "requestError";
|
||||
}
|
||||
|
||||
accountManager.authenticatedRequest(USER_ACTIVITY_URL,
|
||||
QNetworkAccessManager::PostOperation,
|
||||
params,
|
||||
NULL,
|
||||
multipart);
|
||||
}
|
||||
|
||||
void UserActivityLogger::requestFinished(const QJsonObject& object) {
|
||||
qDebug() << object;
|
||||
}
|
||||
|
||||
void UserActivityLogger::requestError(QNetworkReply::NetworkError error,const QString& string) {
|
||||
qDebug() << error << ": " << string;
|
||||
}
|
||||
|
||||
void UserActivityLogger::launch(QString applicationVersion) {
|
||||
const QString ACTION_NAME = "launch";
|
||||
QJsonObject actionDetails;
|
||||
QString VERSION_KEY = "version";
|
||||
actionDetails.insert(VERSION_KEY, applicationVersion);
|
||||
|
||||
logAction(ACTION_NAME, actionDetails);
|
||||
}
|
||||
|
||||
void UserActivityLogger::close(int delayTime) {
|
||||
const QString ACTION_NAME = "close";
|
||||
|
||||
// In order to get the end of the session, we need to give the account manager enough time to send the packet.
|
||||
QEventLoop loop;
|
||||
// Here we connect the callbacks to stop the event loop
|
||||
JSONCallbackParameters params;
|
||||
params.jsonCallbackReceiver = &loop;
|
||||
params.errorCallbackReceiver = &loop;
|
||||
params.jsonCallbackMethod = "quit";
|
||||
params.errorCallbackMethod = "quit";
|
||||
// In case something goes wrong, we also setup a timer so that the delai is not greater than delayTime
|
||||
QTimer timer;
|
||||
connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit);
|
||||
// Now we can log it
|
||||
logAction(ACTION_NAME, QJsonObject(), params);
|
||||
timer.start(delayTime);
|
||||
loop.exec();
|
||||
}
|
||||
|
||||
void UserActivityLogger::changedDisplayName(QString displayName) {
|
||||
const QString ACTION_NAME = "changed_display_name";
|
||||
QJsonObject actionDetails;
|
||||
const QString DISPLAY_NAME = "display_name";
|
||||
|
||||
actionDetails.insert(DISPLAY_NAME, displayName);
|
||||
|
||||
logAction(ACTION_NAME, actionDetails);
|
||||
}
|
||||
|
||||
void UserActivityLogger::changedModel(QString typeOfModel, QString modelURL) {
|
||||
const QString ACTION_NAME = "changed_model";
|
||||
QJsonObject actionDetails;
|
||||
const QString TYPE_OF_MODEL = "type_of_model";
|
||||
const QString MODEL_URL = "model_url";
|
||||
|
||||
actionDetails.insert(TYPE_OF_MODEL, typeOfModel);
|
||||
actionDetails.insert(MODEL_URL, modelURL);
|
||||
|
||||
logAction(ACTION_NAME, actionDetails);
|
||||
}
|
||||
|
||||
void UserActivityLogger::changedDomain(QString domainURL) {
|
||||
const QString ACTION_NAME = "changed_domain";
|
||||
QJsonObject actionDetails;
|
||||
const QString DOMAIN_URL = "domain_url";
|
||||
|
||||
actionDetails.insert(DOMAIN_URL, domainURL);
|
||||
|
||||
logAction(ACTION_NAME, actionDetails);
|
||||
}
|
||||
|
||||
void UserActivityLogger::connectedDevice(QString typeOfDevice, QString deviceName) {
|
||||
const QString ACTION_NAME = "connected_device";
|
||||
QJsonObject actionDetails;
|
||||
const QString TYPE_OF_DEVICE = "type_of_device";
|
||||
const QString DEVICE_NAME = "device_name";
|
||||
|
||||
actionDetails.insert(TYPE_OF_DEVICE, typeOfDevice);
|
||||
actionDetails.insert(DEVICE_NAME, deviceName);
|
||||
|
||||
logAction(ACTION_NAME, actionDetails);
|
||||
|
||||
}
|
||||
|
||||
void UserActivityLogger::loadedScript(QString scriptName) {
|
||||
const QString ACTION_NAME = "loaded_script";
|
||||
QJsonObject actionDetails;
|
||||
const QString SCRIPT_NAME = "script_name";
|
||||
|
||||
actionDetails.insert(SCRIPT_NAME, scriptName);
|
||||
|
||||
logAction(ACTION_NAME, actionDetails);
|
||||
|
||||
}
|
47
libraries/networking/src/UserActivityLogger.h
Normal file
47
libraries/networking/src/UserActivityLogger.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
//
|
||||
// UserActivityLogger.h
|
||||
//
|
||||
//
|
||||
// Created by Clement on 5/21/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_UserActivityLogger_h
|
||||
#define hifi_UserActivityLogger_h
|
||||
|
||||
#include "AccountManager.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QJsonObject>
|
||||
#include <QNetworkReply>
|
||||
|
||||
class UserActivityLogger : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static UserActivityLogger& getInstance();
|
||||
|
||||
public slots:
|
||||
void logAction(QString action, QJsonObject details = QJsonObject(), JSONCallbackParameters params = JSONCallbackParameters());
|
||||
|
||||
void launch(QString applicationVersion);
|
||||
void close(int delayTime);
|
||||
void changedDisplayName(QString displayName);
|
||||
void changedModel(QString typeOfModel, QString modelURL);
|
||||
void changedDomain(QString domainURL);
|
||||
void connectedDevice(QString typeOfDevice, QString deviceName);
|
||||
void loadedScript(QString scriptName);
|
||||
|
||||
private slots:
|
||||
void requestFinished(const QJsonObject& object);
|
||||
void requestError(QNetworkReply::NetworkError error,const QString& string);
|
||||
|
||||
private:
|
||||
UserActivityLogger();
|
||||
};
|
||||
|
||||
#endif // hifi_UserActivityLogger_h
|
Loading…
Reference in a new issue