/* globals operative _ Cookies $ */
/* eslint no-console: 0 */
(function(root) {
'use strict';
if (typeof root.Mtdc !== 'object') {
root.Mtdc = {};
}
var Mtdc = root.Mtdc;
Mtdc.TrackingWorker = function(renkan, opts){
var options = _.defaults(opts, {
debounceDelay: 1000,
trackingUriTemplates: {
'renkan': 'urn:mtdc:renkan:renkan:${renkan_id}',
'node': 'urn:mtdc:renkan:node:${renkan_id}:${node_id}',
'edge': 'urn:mtdc:renkan:edge:${renkan_id}:${edge_id}',
'view': 'urn:mtdc:renkan:view:${renkan_id}:${view_id}'
}
});
function _sendTrackingInfo() {
var trackingMessages = this.trackingMessages;
this.trackingMessages = [];
if(trackingMessages.length === 0) {
return;
}
$.ajax({
method: 'POST',
url: this.trackingUrl,
headers: {
'X-CSRFToken': this.csrftoken
},
data: JSON.stringify(trackingMessages),
contentType: 'application/json'
}).fail(function(){
console.log('send tracking data failed', trackingMessages);
}); // this is fire and forget. Nothong to do on done
}
var trackingWorker = {
trackingMessages: [],
currentUser: renkan.current_user,
renkan: renkan,
trackingUrl: options.trackingUrl,
trackingCloseUrl: options.trackingCloseUrl,
getUUID4 : function() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0,
v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
},
_init: function() {
this.sendTrackingInfo = _.debounce(_.bind(_sendTrackingInfo, this), options.debounceDelay);
this.csrftoken = Cookies.get('csrftoken');
this.registration = options.registration ? options.registration : this.getUUID4();
this.trackingUriTemplates = _.mapValues(options.trackingUriTemplates, _.template);
return this;
},
_pushTrackingMessage: function(msg) {
this.trackingMessages.push(msg);
this.sendTrackingInfo();
},
flushTrackingInfo() {
//this.sendTrackingInfo.flush();
},
_getBaseMsg: function(verb) {
var timestamp = new Date(),
verbNode = {
add: {
id: 'http://activitystrea.ms/schema/1.0/create',
display: { 'fr-FR': 'a créé' }
},
update: {
id: 'http://activitystrea.ms/schema/1.0/update',
display: { 'fr-FR': 'a modifié' }
},
delete: {
id: 'http://activitystrea.ms/schema/1.0/delete',
display: { 'fr-FR': 'a supprimé' }
},
move: {
id: 'http://activitystrea.ms/schema/1.0/move',
display: { 'fr-FR': 'a déplacé'}
},
close: {
id: 'http://activitystrea.ms/schema/1.0/close',
display: { 'fr-FR': 'a fermé'}
},
search: {
id: 'http://activitystrea.ms/schema/1.0/search',
display: { 'fr-FR': 'a cherché'}
}
}[verb];
return {
actor: {
objectType: 'Agent',
name: this.currentUser,
account: {
homePage: 'https://www.metaeducation.fr/Utilisateurs/',
name: this.currentUser
}
},
verb: verbNode,
object: {
objectType: 'Activity'
},
context: {
registration: this.registration,
extensions: {
'http://liris.renkantracking.org/application': 'Outil carte mentale'
}
},
timestamp: timestamp.toISOString()
};
},
_getObjectUri: function(objectType, objectId) {
var template = this.trackingUriTemplates[objectType];
var templateParams = {'renkan_id': this.renkan.project.get('id')};
templateParams[objectType+'_id'] = objectId;
return template(templateParams);
},
_sendNodeMsg: function(verb, nodeData, changedData, previousData) {
this._sendObjectMsg('node', 'http://www.w3.org/ns/activitystreams#Node', verb, nodeData, changedData, previousData);
},
_sendEdgeMsg: function(verb, nodeData, changedData, previousData) {
this._sendObjectMsg('edge', 'http://www.w3.org/ns/activitystreams#Edge', verb, nodeData, changedData, previousData);
},
_sendViewMsg: function(verb, viewData, changedData, previousData) {
this._sendObjectMsg('view', 'http://www.w3.org/ns/activitystreams#View', verb, viewData, changedData, previousData);
},
_sendObjectMsg: function(objectType, objectTypeUrl, verb, objData, changedData, previousData) {
var msg = this._getBaseMsg(verb);
msg.object = _.merge(msg.object, {
id: this._getObjectUri(objectType, objData._id), //TODO full url ???
definition: {
name: {
'fr-FR': objData.title
},
description: {
'fr-FR': objData.description
},
type: objectTypeUrl,
extensions: {
'http://www.w3.org/ns/activitystreams#Data': objData,
'http://www.w3.org/ns/activitystreams#DataChanged': changedData, //this part are not sent if undefined
'http://www.w3.org/ns/activitystreams#DataPrevious': previousData //this part are not sent if undefined
}
}
});
msg.context = _.merge(msg.context, {
extensions: {
'http://liris.renkantracking.org/fromCreate': objData.origin
}
});
this._pushTrackingMessage(msg);
},
addNode: function(nodeData) {
this._sendNodeMsg('add', nodeData);
},
deleteNode: function(nodeData) {
this._sendNodeMsg('delete', nodeData);
},
updateNode: function(nodeData, changedData, previousData) {
if('position' in changedData) {
this._sendNodeMsg('move', nodeData, { position: changedData['position']}, { position: previousData['position']});
delete changedData['position'];
delete previousData['position'];
}
if(_.isEmpty(changedData)) {
return;
}
this._sendNodeMsg('update', nodeData, changedData, previousData);
},
addEdge: function(edgeData) {
this._sendEdgeMsg('add', edgeData);
},
deleteEdge: function(edgeData) {
this._sendEdgeMsg('delete', edgeData);
},
updateEdge: function(edgeData, changedData, previousData) {
this._sendEdgeMsg('update', edgeData, changedData, previousData);
},
addView: function(edgeData) {
this._sendViewMsg('add', edgeData);
},
deleteView: function(edgeData) {
this._sendViewMsg('delete', edgeData);
},
updateView: function(viewData, changedData, previousData) {
this._sendViewMsg('update', viewData, changedData, previousData);
},
searchProject: function(searchData) {
var msg = this._getBaseMsg('search');
msg.object = _.merge(msg.object, {
id: this._getObjectUri('renkan', this.renkan.project.get('id')),
definition: {
name: {
'fr-FR': this.renkan.project.get('title')
},
type: 'http://www.w3.org/ns/activitystreams#Renkan',
extensions: {
'http://www.w3.org/ns/activitystreams#Data': searchData
}
}
});
this._pushTrackingMessage(msg);
},
closeProject: function() {
this.flushTrackingInfo();
$.ajax({
method: 'POST',
url: this.trackingCloseUrl,
async: false,
headers: {
'X-CSRFToken': this.csrftoken
},
data: {
'renkan_guid': this.renkan.project.get('id'),
'registration': this.registration
}
}).fail(function(){
console.log('send tracking data failed');
}); // this is fire and forget. Nothong tpo do on failed
}
};
return trackingWorker._init();
};
})(window);