Skip to content

Commit 300a6c9

Browse files
committed
#141: initial analytics support
1 parent 68b5cec commit 300a6c9

File tree

7 files changed

+127
-4
lines changed

7 files changed

+127
-4
lines changed

app.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ commander
3838

3939
global.commander = commander;
4040

41+
var trackStats = require(path.join(global.pathToApp, 'core/trackStats'));
42+
4143
app.set('views', path.join(__dirname, 'core/views'));
4244
app.set('user', path.join(__dirname, global.opts.core.common.pathToUser));
4345

@@ -52,12 +54,17 @@ var log = logger.log;
5254
global.log = log;
5355

5456
if (commander.html) {
57+
trackStats.staticEvent('features', 'enabled html parser');
58+
5559
global.opts.plugins.htmlParser.enabled = true;
5660
global.opts.plugins.htmlParser.onStart = true;
5761
}
5862
if (commander.port) global.opts.core.server.port = parseInt(commander.port);
5963
if (commander.hostname) global.opts.core.server.hostname = commander.hostname;
60-
if (!commander.watch) global.opts.core.watch.enabled = false;
64+
if (!commander.watch) {
65+
trackStats.staticEvent('features', 'disabled watch');
66+
global.opts.core.watch.enabled = false;
67+
}
6168
/* /Globals */
6269

6370

@@ -241,6 +248,12 @@ if (!module.parent) {
241248
process.exit(1);
242249
}
243250
});
251+
} else {
252+
if (global.opts.core.common.trackAnonymusStatistics) {
253+
trackStats.staticEvent('start', 'default');
254+
} else {
255+
trackStats.staticEvent('start', 'no stats', true);
256+
}
244257
}
245258
}
246259
/* Server start */

core/middlewares/clarify.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ var _ = require('lodash');
88
var jsdom = require('jsdom');
99
var ejs = require('ejs');
1010

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

317+
trackStats.page('clarify', req.sessionID);
318+
316319
res.send(html);
317320
}).fail(function(err) {
318321
var msg = 'ERROR: Could not find requested or default template for Clarify';

core/middlewares/send.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
'use strict';
22

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

57
/**
68
* In case if request contains rendered html, then send it as response and stop spec content post-processing.
@@ -11,6 +13,8 @@ var prettyHrtime = require('pretty-hrtime');
1113
* */
1214
exports.process = function (req, res, next) {
1315
if (req.specData && req.specData.renderedHtml) {
16+
trackStats.specs(req);
17+
1418
global.log.trace('Spec loading time: ', prettyHrtime(process.hrtime(global.specLoadTime)));
1519

1620
res.send(req.specData.renderedHtml);

core/trackStats.js

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
var url = require('url');
2+
var path = require('path');
3+
var macaddress = require('macaddress');
4+
var ua = require('universal-analytics');
5+
var log = require(path.join(global.pathToApp, 'core/logger')).log;
6+
var crypto = require('crypto');
7+
8+
var generateMachineID = function(){
9+
var macNums = macaddress.networkInterfaces();
10+
var unique = '';
11+
var macItem;
12+
13+
for (macItem in macNums) {
14+
var val = macNums[macItem];
15+
16+
if (val.mac) {
17+
unique += val.mac;
18+
} else if (val.ipv4) {
19+
unique += val.ipv4;
20+
}
21+
}
22+
23+
return 'host_' + crypto.createHash('md5').update(unique).digest('hex').slice(0, 5);
24+
};
25+
26+
var staticVisitor = ua('UA-66924051-1', generateMachineID(), {strictCidFormat: false});
27+
28+
// Track page visits by unique session ID
29+
var trackPage = function(opts){
30+
if (!global.opts.core.common.trackAnonymusStatistics) return;
31+
32+
var visitor = ua('UA-66924051-1', opts.sessionID, {strictCidFormat: false});
33+
34+
log.trace('track page', opts.pageName);
35+
36+
visitor.pageview(opts.pageName).send();
37+
};
38+
39+
// Track host-initiated events (by unique machine id)
40+
var staticEvent = function(group, event, force){
41+
if (!force && !global.opts.core.common.trackAnonymusStatistics) return;
42+
43+
log.trace('track event', group, event);
44+
45+
staticVisitor.event(group, event).send();
46+
};
47+
48+
module.exports.specs = function(req) {
49+
var pageName = 'spec';
50+
var sessionID = req.sessionID;
51+
52+
var parsedUrl = url.parse(req.url, true);
53+
var q = parsedUrl.query || {};
54+
55+
if (q.internal) return;
56+
57+
if (req.originalPath === '/') {
58+
pageName = '/';
59+
} else if (req.specData && req.specData.info && req.specData.info.role === 'navigation') {
60+
pageName = 'navigation';
61+
}
62+
63+
trackPage({
64+
sessionID: sessionID,
65+
pageName: pageName
66+
});
67+
};
68+
69+
module.exports.page = function(pageName, sessionID) {
70+
trackPage({
71+
sessionID: sessionID,
72+
pageName: pageName
73+
});
74+
};
75+
76+
module.exports.staticEvent = staticEvent;

core/warn.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
'use strict';
2+
3+
var path = require('path');
4+
5+
var rootPath = __dirname.replace(/^\w:\\/, function (match) {
6+
return match.toLowerCase();
7+
});
8+
var enginePath = global.pathToApp = path.join(rootPath, '../');
9+
10+
var loadOptions = require('./loadOptions');
11+
var options = global.opts = loadOptions(enginePath);
12+
13+
var trackStats = require(path.join(global.pathToApp, 'core/trackStats'));
14+
15+
if (options && options.core.common && options.core.common.trackAnonymusStatistics) {
16+
trackStats.staticEvent('install', 'default');
17+
18+
console.log('\n[SOURCEJS] Note: engine tracks anonymous usage statistics. To disable it, edit `core.common.trackAnonymusStatistics` configuration.\n');
19+
} else {
20+
trackStats.staticEvent('install', 'no stats', true);
21+
}

options.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ module.exports = {
2424
infoFile: 'info.json',
2525

2626
// Name of options field in info.json, used to override configuration per spec
27-
infoFileOptions: 'sourcejs'
27+
infoFileOptions: 'sourcejs',
28+
29+
trackAnonymusStatistics: true
2830
},
2931

3032
// Server options are passed to app.listen (https://nodejs.org/api/http.html#http_server_listen_port_hostname_backlog_callback)

package.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"async": "~0.9.0",
1313
"body-parser": "~1.6.4",
1414
"cheerio": "^0.19.0",
15+
"chokidar": "git+https://github.com/operatino/chokidar.git",
1516
"colors": "0.6.x",
1617
"commander": "^2.8.1",
1718
"compression": "~1.0.11",
@@ -25,6 +26,7 @@
2526
"flat": "^1.2.1",
2627
"fs-extra": "~0.11.1",
2728
"fs-finder": "operatino/node-fs-finder#fix-windows-find-up",
29+
"fsevents": "^0.3.8",
2830
"grunt": "~0.4.5",
2931
"grunt-autoprefixer": "~1.0.0",
3032
"grunt-cli": "^0.1.13",
@@ -43,17 +45,19 @@
4345
"load-grunt-tasks": "~0.3.0",
4446
"lodash": "^3.10.1",
4547
"log4js": "~0.6.20",
48+
"macaddress": "^0.2.8",
4649
"marked": "^0.3.2",
4750
"path": "^0.4.9",
4851
"phantomjs": "1.9.7-15",
4952
"pretty-hrtime": "^1.0.0",
5053
"q": "^1.1.1",
5154
"serve-favicon": "^2.2.0",
5255
"time-grunt": "~0.2.10",
53-
"tinyforever": "0.0.3"
56+
"tinyforever": "0.0.3",
57+
"universal-analytics": "^0.3.9"
5458
},
5559
"scripts": {
56-
"postinstall": "node ./core/postInstall && grunt update",
60+
"postinstall": "node ./core/postInstall && grunt update && node ./core/warn",
5761
"build": "npm i",
5862
"start": "node app",
5963
"test": "grunt ci-pre-run && node app.js --test",

0 commit comments

Comments
 (0)