// PROTOCOL SPECIFICATION // ----------------------- // /users/count - returns the number of users and how many of them are using VoiceOver // /users/vib - returns objects representing who are using VoiceOver // /users/sighted - returns objects representing who are not using VoiceOver var express = require('express'); var router = express.Router(); var debug = require('debug')('Icarus:server'); var mongoClient = require('mongodb').MongoClient; var assert = assert = require('assert'); // Connection URL var mongoUrl = 'mongodb://readOnly:readOnly@localhost:27017/icarus'; //Connect to the server and intialise the pool var icarusDb; mongoClient.connect(mongoUrl, function(err, db) { assert.equal(null, err, err); debug("Connected to MongoDB database: "+db.databaseName); icarusDb = db; }); /* GET root . */ router.get('/', function(req, res, next) { res.sendStatus(200); }); router.get('/users/count', function(req, res, next) { var collection = icarusDb.collection('resources'); var cursor = collection.aggregate( // Pipeline [ // Stage 1 { $match: { "appdata.appname":"Invisible Puzzle", "debug":false } }, // Stage 2 { $group: { "_id": "$appdata.uuid", "docs": {$sum: 1}, "voiceover": {$sum : {$cond: [{$eq:["$appdata.voiceover", true]},1,0]}} } }, // Stage 3 { $project: { "docs": 1, "vo_ratio": {$divide:["$voiceover","$docs"]} } }, // Stage 4 { $group: { "_id": 1, "users": {$sum: 1}, "vib": {$sum : {$cond: [{$gt:["$vo_ratio", 0]},1,0]}} } }, // Stage 5 { $project: { "_id": 0, "users": 1, "vib": 1 } } ] ) return_cursor(cursor, req, res, next); }); router.get('/users/vib', function(req, res, next) { var cursor = user_ids_cursor(true); return_cursor(cursor, req, res, next); }); router.get('/users/sighted', function(req, res, next) { var cursor = user_ids_cursor(false); return_cursor(cursor, req, res, next); }); function user_ids_cursor(vib){ var filter_condition = {$eq: 0}; if(vib==true){ filter_condition = {$gt: 0} } var collection = icarusDb.collection('resources'); return collection.aggregate( // Pipeline [ // Stage 1 { $match: { "appdata.appname":"Invisible Puzzle", "debug":false } }, // Stage 2 { $group: { "_id": "$appdata.uuid", "docs": {$sum: 1}, "voiceover": {$sum : {$cond: [{$eq:["$appdata.voiceover", true]},1,0]}}, "levels" : { "$addToSet" : "$userdata.level.id" }, "sonifications" : { "$addToSet" : "$userdata.sonification" } } }, // Stage 3 { $project: { "docs": 1, "vo_ratio": {$divide:["$voiceover","$docs"]}, "levels": 1, "sonification": 1 } }, // Stage 4 { $match: { "vo_ratio": filter_condition } } ] ) } router.get('/explorations/hp', function(req, res, next) { var collection = icarusDb.collection('resources'); var cursor = collection.aggregate( // Pipeline [ // Stage 1 { $match: { "appdata.appname" : "Invisible Puzzle", "userdata.event" : "exploration", "debug" : false } }, // Stage 2 { $group: { "_id" : 1, "explorations" : { "$sum" : 1 }, "with_hp" : { "$sum" : { "$cond" : [ { "$eq" : [ "$userdata.headphones", true ] }, 1, 0 ] } } } } ] ); return_cursor(cursor, req, res, next); }); router.get('/explorations/hpbylevel', function(req, res, next) { var collection = icarusDb.collection('resources'); var cursor = collection.aggregate( // Pipeline [ // Stage 1 { $match: { "appdata.appname" : "Invisible Puzzle", "userdata.event" : "exploration", "debug" : false } }, // Stage 2 { $group: { "_id" : "$userdata.level.id", "explorations" : { "$sum" : 1 }, "with_hp" : { "$sum" : { "$cond" : [ { "$eq" : [ "$userdata.headphones", true ] }, 1, 0 ] } } } }, // Stage 3 { $project: { "_id": 1, "explorations": 1, "hp_ratio": {$divide:["$with_hp","$explorations"]} } }, // Stage 4 { $sort: { "_id": 1 } } ] ); return_cursor(cursor, req, res, next); }); function return_cursor(cursor, req, res, next){ cursor.toArray(function(err, result) { if(err!=null){ debug(err); next(err); }else{ if(result==undefined){ res.sendStatus(404); }else{ res.send(200,result); } } }); } module.exports = router;