Skip to content

Commit

Permalink
#141: initial analytics support
Browse files Browse the repository at this point in the history
  • Loading branch information
robhrt7 committed Aug 31, 2015
1 parent 68b5cec commit 300a6c9
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 4 deletions.
15 changes: 14 additions & 1 deletion app.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ commander

global.commander = commander;

var trackStats = require(path.join(global.pathToApp, 'core/trackStats'));

app.set('views', path.join(__dirname, 'core/views'));
app.set('user', path.join(__dirname, global.opts.core.common.pathToUser));

Expand All @@ -52,12 +54,17 @@ var log = logger.log;
global.log = log;

if (commander.html) {
trackStats.staticEvent('features', 'enabled html parser');

global.opts.plugins.htmlParser.enabled = true;
global.opts.plugins.htmlParser.onStart = true;
}
if (commander.port) global.opts.core.server.port = parseInt(commander.port);
if (commander.hostname) global.opts.core.server.hostname = commander.hostname;
if (!commander.watch) global.opts.core.watch.enabled = false;
if (!commander.watch) {
trackStats.staticEvent('features', 'disabled watch');
global.opts.core.watch.enabled = false;
}
/* /Globals */


Expand Down Expand Up @@ -241,6 +248,12 @@ if (!module.parent) {
process.exit(1);
}
});
} else {
if (global.opts.core.common.trackAnonymusStatistics) {
trackStats.staticEvent('start', 'default');
} else {
trackStats.staticEvent('start', 'no stats', true);
}
}
}
/* Server start */
3 changes: 3 additions & 0 deletions core/middlewares/clarify.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ var _ = require('lodash');
var jsdom = require('jsdom');
var ejs = require('ejs');

var trackStats = require(path.join(global.pathToApp, 'core/trackStats'));
var pathToApp = path.dirname(require.main.filename);
var specUtils = require(path.join(pathToApp, 'core/lib/specUtils'));
var parseData = require(path.join(pathToApp, 'core/lib/parseData'));
Expand Down Expand Up @@ -313,6 +314,8 @@ module.exports.process = function(req, res, next) {
html = msg;
}

trackStats.page('clarify', req.sessionID);

res.send(html);
}).fail(function(err) {
var msg = 'ERROR: Could not find requested or default template for Clarify';
Expand Down
4 changes: 4 additions & 0 deletions core/middlewares/send.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
'use strict';

var path = require('path');
var prettyHrtime = require('pretty-hrtime');
var trackStats = require(path.join(global.pathToApp, 'core/trackStats'));

/**
* In case if request contains rendered html, then send it as response and stop spec content post-processing.
Expand All @@ -11,6 +13,8 @@ var prettyHrtime = require('pretty-hrtime');
* */
exports.process = function (req, res, next) {
if (req.specData && req.specData.renderedHtml) {
trackStats.specs(req);

global.log.trace('Spec loading time: ', prettyHrtime(process.hrtime(global.specLoadTime)));

res.send(req.specData.renderedHtml);
Expand Down
76 changes: 76 additions & 0 deletions core/trackStats.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
var url = require('url');
var path = require('path');
var macaddress = require('macaddress');
var ua = require('universal-analytics');
var log = require(path.join(global.pathToApp, 'core/logger')).log;
var crypto = require('crypto');

var generateMachineID = function(){
var macNums = macaddress.networkInterfaces();
var unique = '';
var macItem;

for (macItem in macNums) {
var val = macNums[macItem];

if (val.mac) {
unique += val.mac;
} else if (val.ipv4) {
unique += val.ipv4;
}
}

return 'host_' + crypto.createHash('md5').update(unique).digest('hex').slice(0, 5);
};

var staticVisitor = ua('UA-66924051-1', generateMachineID(), {strictCidFormat: false});

// Track page visits by unique session ID
var trackPage = function(opts){
if (!global.opts.core.common.trackAnonymusStatistics) return;

var visitor = ua('UA-66924051-1', opts.sessionID, {strictCidFormat: false});

log.trace('track page', opts.pageName);

visitor.pageview(opts.pageName).send();
};

// Track host-initiated events (by unique machine id)
var staticEvent = function(group, event, force){
if (!force && !global.opts.core.common.trackAnonymusStatistics) return;

log.trace('track event', group, event);

staticVisitor.event(group, event).send();
};

module.exports.specs = function(req) {
var pageName = 'spec';
var sessionID = req.sessionID;

var parsedUrl = url.parse(req.url, true);
var q = parsedUrl.query || {};

if (q.internal) return;

if (req.originalPath === '/') {
pageName = '/';
} else if (req.specData && req.specData.info && req.specData.info.role === 'navigation') {
pageName = 'navigation';
}

trackPage({
sessionID: sessionID,
pageName: pageName
});
};

module.exports.page = function(pageName, sessionID) {
trackPage({
sessionID: sessionID,
pageName: pageName
});
};

module.exports.staticEvent = staticEvent;
21 changes: 21 additions & 0 deletions core/warn.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
'use strict';

var path = require('path');

var rootPath = __dirname.replace(/^\w:\\/, function (match) {
return match.toLowerCase();
});
var enginePath = global.pathToApp = path.join(rootPath, '../');

var loadOptions = require('./loadOptions');
var options = global.opts = loadOptions(enginePath);

var trackStats = require(path.join(global.pathToApp, 'core/trackStats'));

if (options && options.core.common && options.core.common.trackAnonymusStatistics) {
trackStats.staticEvent('install', 'default');

console.log('\n[SOURCEJS] Note: engine tracks anonymous usage statistics. To disable it, edit `core.common.trackAnonymusStatistics` configuration.\n');
} else {
trackStats.staticEvent('install', 'no stats', true);
}
4 changes: 3 additions & 1 deletion options.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ module.exports = {
infoFile: 'info.json',

// Name of options field in info.json, used to override configuration per spec
infoFileOptions: 'sourcejs'
infoFileOptions: 'sourcejs',

trackAnonymusStatistics: true
},

// Server options are passed to app.listen (https://nodejs.org/api/http.html#http_server_listen_port_hostname_backlog_callback)
Expand Down
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"async": "~0.9.0",
"body-parser": "~1.6.4",
"cheerio": "^0.19.0",
"chokidar": "git+https://github.com/operatino/chokidar.git",
"colors": "0.6.x",
"commander": "^2.8.1",
"compression": "~1.0.11",
Expand All @@ -25,6 +26,7 @@
"flat": "^1.2.1",
"fs-extra": "~0.11.1",
"fs-finder": "operatino/node-fs-finder#fix-windows-find-up",
"fsevents": "^0.3.8",
"grunt": "~0.4.5",
"grunt-autoprefixer": "~1.0.0",
"grunt-cli": "^0.1.13",
Expand All @@ -43,17 +45,19 @@
"load-grunt-tasks": "~0.3.0",
"lodash": "^3.10.1",
"log4js": "~0.6.20",
"macaddress": "^0.2.8",
"marked": "^0.3.2",
"path": "^0.4.9",
"phantomjs": "1.9.7-15",
"pretty-hrtime": "^1.0.0",
"q": "^1.1.1",
"serve-favicon": "^2.2.0",
"time-grunt": "~0.2.10",
"tinyforever": "0.0.3"
"tinyforever": "0.0.3",
"universal-analytics": "^0.3.9"
},
"scripts": {
"postinstall": "node ./core/postInstall && grunt update",
"postinstall": "node ./core/postInstall && grunt update && node ./core/warn",
"build": "npm i",
"start": "node app",
"test": "grunt ci-pre-run && node app.js --test",
Expand Down

0 comments on commit 300a6c9

Please sign in to comment.