forked from cogtoolslab/cognitive-ai-benchmarking
-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.js
187 lines (169 loc) · 5.84 KB
/
app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
global.__base = __dirname + '/';
var
use_https = true,
argv = require('minimist')(process.argv.slice(2)),
https = require('https'),
fs = require('fs'),
app = require('express')(),
_ = require('lodash'),
parser = require('xmldom').DOMParser,
XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest,
sendPostRequest = require('request').post,
cors = require('cors'),
portastic = require('portastic');
////////// EXPERIMENT GLOBAL PARAMS //////////
var gameport;
var store_port;
var store_process;
var cur_path = process.cwd();
// make sure that we're launching store.js from the right path
if (cur_path.indexOf('/experiments') === -1) {
cur_path = cur_path + '/experiments/';
} else {
cur_path = cur_path + '/';
}
if (argv.gameport) {
try {
if ((argv.gameport < 8850) || (argv.gameport > 8999)) {
throw 'error';
} else {
gameport = argv.gameport;
console.log('using public facing port ' + gameport);
}
} catch (err) {
console.log('invalid gameport: choose a gameport between 8850 and 8999');
process.exit();
}
} else {
gameport = 8886;
console.log('no gameport specified: using 8886\nUse the --gameport flag to change');
}
// we launch store.js ourselves
// find free internal port
portastic.find({
min: 4000,
max: 5000,
retrieve: 1
}).then(ports => {
store_port = ports;
if (argv.local_store) {
console.log('using local store on port ' + store_port);
// launch store.js
store_process = require('child_process').spawn('node', [cur_path+'store_local.js', '--port', store_port], {stdio: 'inherit'});
console.log("⚠️ LOCAL STORAGE IS BEING USED. THIS IS NOT RECOMMENDED FOR PRODUCTION. YOU MIGHT LOOSE DATA. USE A DATABASE INSTEAD. ⚠️");
} else {
console.log('using mongoDB store on port ' + store_port);
// launch store.js
store_process = require('child_process').spawn('node', [cur_path+'store.js', '--port', store_port], {stdio: 'inherit'});
}
});
try {
var privateKey = fs.readFileSync('/etc/letsencrypt/live/cogtoolslab.org/privkey.pem'),
certificate = fs.readFileSync('/etc/letsencrypt/live/cogtoolslab.org/cert.pem'),
intermed = fs.readFileSync('/etc/letsencrypt/live/cogtoolslab.org/chain.pem'),
options = { key: privateKey, cert: certificate, ca: intermed },
server = require('https').createServer(options, app).listen(gameport),
io = require('socket.io')(server);
} catch (err) {
console.log("cannot find SSL certificates; falling back to http");
var server = app.listen(gameport),
io = require('socket.io')(server);
}
// serve stuff that the client requests
app.get('/*', (req, res) => {
serveFile(req, res);
});
io.on('connection', function (socket) {
console.log('\t :: Express :: client connected');
// on request serve the stimulus data
socket.on('getStims', function (data) {
console.log('getStims');
var proj_name = data.proj_name;
var exp_name = data.exp_name;
var iter_name = data.iter_name;
initializeWithTrials(socket, proj_name, exp_name, iter_name);
});
// write data to db upon getting current data
socket.on('currentData', function (data) {
console.log('currentData received: ' + JSON.stringify(data).substring(0,200));
// Increment games list in mongo here
var proj_name = data.projName;
var exp_name = data.expName;
var iter_name = data.iterName;
writeDataToMongo(data, proj_name, exp_name, iter_name);
});
});
FORBIDDEN_FILES = ["auth.json"]
var serveFile = function (req, res) {
var fileName = req.params[0];
if (FORBIDDEN_FILES.includes(fileName)) {
// Don't serve files that contain secrets
console.log("Forbidden file requested: " + filename);
return;
}
console.log('\t :: Express :: file requested: ' + fileName);
return res.sendFile(fileName, { root: __dirname });
};
function omit(obj, props) { //helper function to remove _id of stim object
try{
props = props instanceof Array ? props : [props]
return eval(`(({${props.join(',')}, ...o}) => o)(obj)`)
} catch (err) {
return obj;
}
}
function initializeWithTrials(socket, proj_name, collection, it_name) {
var gameid = UUID();
// var colname = 'human-physics-benchmarking-dominoes-pilot_production_1'; //insert STIMULI DATASETNAME here
sendPostRequest('http://localhost:' + store_port + '/db/getstims', {
json: {
dbname: proj_name + '_input',
colname: collection,
it_name: it_name,
gameid: gameid
}
}, (error, res, body) => {
if (!error && res.statusCode === 200 && typeof body !== 'undefined') {
// send trial list (and id) to client
var packet = {
gameid: gameid,
inputid: body['_id'], // using the mongo record ID
stims: omit(body.stims, ['_id']),
familiarization_stims: omit(body.familiarization_stims, ['_id']),
stim_version: body.stim_version, //TODO fix stim version
// TODO add other properties here
};
socket.emit('stims', packet);
} else {
console.log(`error getting stims: ${error} ${body}`);
}
});
}
var UUID = function () {
var baseName = (Math.floor(Math.random() * 10) + '' +
Math.floor(Math.random() * 10) + '' +
Math.floor(Math.random() * 10) + '' +
Math.floor(Math.random() * 10));
var template = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx';
var id = baseName + '-' + template.replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
return id;
};
var writeDataToMongo = function (data, proj_name, collection, it_name) {
var db = proj_name + '_output';
sendPostRequest(
'http://localhost:' + store_port + '/db/insert',
{
json: data,
},
(error, res, body) => {
if (!error && res.statusCode === 200) {
console.log(`sent data to store`);
} else {
console.log(`error sending data to store: ${error} ${body}`);
}
}
);
};