diff --git a/client/commonFramework/bindings.js b/client/commonFramework/bindings.js index 009bae4088..dc36502f67 100644 --- a/client/commonFramework/bindings.js +++ b/client/commonFramework/bindings.js @@ -129,7 +129,7 @@ window.common = (function(global) { }); if (common.challengeName) { - window.ga('send', 'event', 'Challenge', 'load', common.challengeName); + window.ga('send', 'event', 'Challenge', 'load', common.gaName); } $('#complete-courseware-dialog').on('hidden.bs.modal', function() { diff --git a/client/commonFramework/execute-challenge-stream.js b/client/commonFramework/execute-challenge-stream.js index b81de64486..18f7b161b5 100644 --- a/client/commonFramework/execute-challenge-stream.js +++ b/client/commonFramework/execute-challenge-stream.js @@ -20,7 +20,7 @@ window.common = (function(global) { const tail = common.arrayToNewLineString(common.tail); const combinedCode = head + code + tail; - ga('send', 'event', 'Challenge', 'ran-code', common.challengeName); + ga('send', 'event', 'Challenge', 'ran-code', common.gaName); // run checks for unsafe code return detectUnsafeCode$(code) diff --git a/client/commonFramework/show-completion.js b/client/commonFramework/show-completion.js index 5080efd629..9f8862ac01 100644 --- a/client/commonFramework/show-completion.js +++ b/client/commonFramework/show-completion.js @@ -12,7 +12,7 @@ window.common = (function(global) { 'event', 'Challenge', 'solved', - common.challengeName, + common.gaName, true ); diff --git a/common/models/challenge.json b/common/models/challenge.json index 9785a0d9cb..4f62940223 100644 --- a/common/models/challenge.json +++ b/common/models/challenge.json @@ -29,6 +29,9 @@ "suborder": { "type": "number" }, + "checksum": { + "type": "number" + }, "isBeta": { "type": "boolean", "description": "Show only during dev or on beta site. Completely omitted otherwise" diff --git a/package.json b/package.json index 5c76e9d4c2..28e8ffd8b7 100644 --- a/package.json +++ b/package.json @@ -26,16 +26,17 @@ "license": "(BSD-3-Clause AND CC-BY-SA-4.0)", "dependencies": { "accepts": "^1.3.0", + "adler32": "~0.1.7", "async": "^1.5.0", "babel-cli": "^6.3.17", "babel-core": "^6.3.26", "babel-eslint": "^4.1.4", "babel-loader": "^6.2.1", - "babel-register": "^6.3.0", "babel-plugin-add-module-exports": "^0.1.2", "babel-preset-es2015": "^6.3.13", "babel-preset-react": "^6.3.13", "babel-preset-stage-0": "^6.3.13", + "babel-register": "^6.3.0", "body-parser": "^1.13.2", "chai-jquery": "^2.0.0", "cheerio": "~0.19.0", diff --git a/seed/index.js b/seed/index.js index 28d1f70eae..bea266a763 100644 --- a/seed/index.js +++ b/seed/index.js @@ -1,6 +1,7 @@ /* eslint-disable no-process-exit */ require('babel-register'); require('dotenv').load(); +var adler32 = require('adler32'); var Rx = require('rx'), _ = require('lodash'), @@ -40,6 +41,12 @@ destroy() .replace(/\:/g, '') .replace(/\s/g, '-'); + challenge.checksum = adler32.sum( + Buffer(challenge.title + + JSON.stringify(challenge.description) + + JSON.stringify(challenge.challengeSeed) + + JSON.stringify(challenge.tests))); + challenge.fileName = fileName; challenge.helpRoom = helpRoom; challenge.order = order; diff --git a/server/boot/challenge.js b/server/boot/challenge.js index df0ad21d8a..bf7979d94f 100644 --- a/server/boot/challenge.js +++ b/server/boot/challenge.js @@ -178,7 +178,10 @@ function getRenderData$(user, challenge$, origChallengeName, solution) { // htmls specific verb: randomVerb(), phrase: randomPhrase(), - compliment: randomCompliment() + compliment: randomCompliment(), + + // Google Analytics + gaName: challenge.title + '~' + challenge.checksum } }); }); diff --git a/server/utils/getFromDisk$.js b/server/utils/getFromDisk$.js index 1f64f0551b..573880648a 100644 --- a/server/utils/getFromDisk$.js +++ b/server/utils/getFromDisk$.js @@ -1,5 +1,6 @@ import path from 'path'; import { Observable } from 'rx'; +import adler32 from 'adler32'; const basePath = process.cwd() + '/seed/challenges/'; @@ -21,6 +22,12 @@ export default function getFromDisk$(challenge) { return _challenge; }) .map(challenge => { + challenge.checksum = adler32.sum( + Buffer(challenge.title + + JSON.stringify(challenge.description) + + JSON.stringify(challenge.challengeSeed) + + JSON.stringify(challenge.tests))); + challenge.head = challenge.head || []; challenge.tail = challenge.tail || []; challenge.challengeType = '' + challenge.challengeType; diff --git a/server/views/challenges/showBonfire.jade b/server/views/challenges/showBonfire.jade index baef724af9..0b4179b58e 100644 --- a/server/views/challenges/showBonfire.jade +++ b/server/views/challenges/showBonfire.jade @@ -93,6 +93,7 @@ block content common.challengeType = !{JSON.stringify(challengeType)}; common.dashedName = !{JSON.stringify(dashedName)}; common.isCompleted = !{JSON.stringify(isCompleted)}; + common.gaName = !{JSON.stringify(gaName)}; common.username = !{JSON.stringify(user && user.username || '')}; diff --git a/server/views/challenges/showHTML.jade b/server/views/challenges/showHTML.jade index 8a6b2355d5..ac1b3588eb 100644 --- a/server/views/challenges/showHTML.jade +++ b/server/views/challenges/showHTML.jade @@ -84,6 +84,7 @@ block content common.challengeType = !{JSON.stringify(challengeType)}; common.dashedName = !{JSON.stringify(dashedName)}; common.isCompleted = !{JSON.stringify(isCompleted)}; + common.gaName = !{JSON.stringify(gaName)}; common.username = !{JSON.stringify(user && user.username || '')}; diff --git a/server/views/challenges/showJS.jade b/server/views/challenges/showJS.jade index 444fa4549f..d7246ff53f 100644 --- a/server/views/challenges/showJS.jade +++ b/server/views/challenges/showJS.jade @@ -88,6 +88,7 @@ block content common.challengeType = !{JSON.stringify(challengeType)}; common.dashedName = !{JSON.stringify(dashedName)}; common.isCompleted = !{JSON.stringify(isCompleted)}; + common.gaName = !{JSON.stringify(gaName)}; common.username = !{JSON.stringify(user && user.username || '')}; diff --git a/server/views/challenges/showStep.jade b/server/views/challenges/showStep.jade index e98b378109..199b52e1ae 100644 --- a/server/views/challenges/showStep.jade +++ b/server/views/challenges/showStep.jade @@ -49,6 +49,7 @@ block content common.challengeName = !{JSON.stringify(name)}; common.challengeType = !{JSON.stringify(challengeType)}; common.dashedName = !{JSON.stringify(dashedName || '')}; + common.gaName = !{JSON.stringify(gaName)}; common.isHonest = !{JSON.stringify(isHonest || false)}; common.isFrontEndCert = !{JSON.stringify(isFrontEndCert || false)}; common.isFullStackCert = !{JSON.stringify(isFullStackCert || false)}; diff --git a/server/views/challenges/showVideo.jade b/server/views/challenges/showVideo.jade index 62a0de1aa9..d25924534c 100644 --- a/server/views/challenges/showVideo.jade +++ b/server/views/challenges/showVideo.jade @@ -56,6 +56,7 @@ block content common.challengeName = !{JSON.stringify(name)}; common.challengeType = !{JSON.stringify(challengeType)}; common.dashedName = !{JSON.stringify(dashedName)}; + common.gaName = !{JSON.stringify(gaName)}; common.init.push(function($) { function controlEnterHandler(e) { if ( diff --git a/server/views/challenges/showZiplineOrBasejump.jade b/server/views/challenges/showZiplineOrBasejump.jade index e2a0db3783..5278e57179 100644 --- a/server/views/challenges/showZiplineOrBasejump.jade +++ b/server/views/challenges/showZiplineOrBasejump.jade @@ -68,6 +68,7 @@ block content common.challengeId = !{JSON.stringify(id)}; common.challengeName = !{JSON.stringify(name)}; common.dashedName = !{JSON.stringify(dashedName)}; + common.gaName = !{JSON.stringify(gaName)}; common.challengeType = !{JSON.stringify(challengeType)}; common.controlEnterHandler = function (e) {