server/src/assets/js/mtdc-tracking-worker.js
author ymh <ymh.work@gmail.com>
Wed, 27 Jul 2016 15:26:23 +0200
changeset 112 2ec47574a371
parent 108 a7480ebe1f4d
permissions -rw-r--r--
improve tracking informations on id and add tracking for search

/* 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);