pngs/nedap/server.js

172 lines
4.1 KiB
JavaScript
Raw Normal View History

2010-12-04 20:20:25 +01:00
var Connect = require('connect');
var wss = require('websocket-server');
2010-12-04 20:20:25 +01:00
var ltx = require('ltx');
2010-12-06 19:10:44 +01:00
var WS_KEY = 'nedap-kneemFothbedchoadHietEnobKavLub1';
2011-04-23 19:57:58 +02:00
var MIME_HTML = 'text/html; charset=UTF-8';
2010-12-04 20:20:25 +01:00
var backend, question, answers, scores;
function html(body) {
return "<!DOCTYPE html>\n" +
"<html><head><title>Pentanews Game Show</title></head>\n" +
2010-12-10 17:26:23 +01:00
"<link href='style.css' rel='stylesheet' type='text/css'>" +
2010-12-04 20:20:25 +01:00
"<body><h1>Pentanews Game Show</h1>\n" +
body +
"</body></html>";
}
2011-04-22 00:27:30 +02:00
var voteTokens = {};
var TOKEN_TIMEOUT = 30 * 1000;
var Token = {
generate: function() {
var token = Math.round(Math.random() * 10000000).toString();
voteTokens[token] = setTimeout(function() {
delete voteTokens[token];
}, TOKEN_TIMEOUT);
return token;
},
validate: function(token) {
if (voteTokens.hasOwnProperty(token)) {
clearTimeout(voteTokens[token]);
delete voteTokens[token];
return true;
} else {
return false;
}
}
};
2011-04-22 17:40:39 +02:00
var updateBackendTimeout;
function updateBackend() {
if (!updateBackendTimeout) {
updateBackendTimeout = setTimeout(function() {
backend.send(JSON.stringify({ scores: scores }));
updateBackendTimeout = undefined;
}, 50);
}
}
2010-12-04 20:20:25 +01:00
function nedap(app) {
app.get('/', function(req, res) {
if (question && answers) {
2010-12-06 19:10:44 +01:00
console.log({question:question,answers:answers})
2010-12-04 20:20:25 +01:00
var form = new ltx.Element('form',
{ action: '/',
method: 'POST',
enctype: 'application/x-www-form-urlencoded' });
2010-12-06 19:10:44 +01:00
form.c('p').t(question);
2010-12-04 20:20:25 +01:00
var ul = form.c('ul');
for(var i = 0; i < answers.length; i++) {
ul.c('li').
c('input', { type: 'radio',
id: 'a'+i,
name: 'a',
value: ''+i }).
c('label', { for: 'a'+i }).
2010-12-06 19:10:44 +01:00
t(answers[i].text);
2010-12-04 20:20:25 +01:00
}
2011-04-22 00:27:30 +02:00
form.c('input', { type: 'hidden',
name: 'token',
value: Token.generate() });
2010-12-04 20:20:25 +01:00
form.c('input', { type: 'submit',
value: 'Submit' });
2011-04-23 19:57:58 +02:00
res.writeHead(200, { 'Content-type': MIME_HTML });
2010-12-04 20:20:25 +01:00
res.write(html(form.toString()));
res.end();
} else {
2011-04-23 19:57:58 +02:00
res.writeHead(404, { 'Content-type': MIME_HTML });
2010-12-10 17:26:23 +01:00
res.write(html('<p>No question left on server.</p>'));
2010-12-04 20:20:25 +01:00
res.end();
}
});
app.post('/', function(req, res) {
2011-04-23 21:36:08 +02:00
var a;
if (req.body && (a = req.body.a) && /^\d+$/.test(a)) {
2010-12-04 20:20:25 +01:00
var i = parseInt(a, 10);
if (scores && i < scores.length && Token.validate(req.body.token)) {
2010-12-04 20:20:25 +01:00
scores[i]++;
2011-04-22 17:40:39 +02:00
updateBackend();
2010-12-04 20:20:25 +01:00
2011-04-23 19:57:58 +02:00
res.writeHead(303, { 'Content-type': MIME_HTML,
2010-12-10 17:26:23 +01:00
'Location': '/thanks' });
2010-12-04 20:20:25 +01:00
res.end();
} else {
2011-04-23 19:57:58 +02:00
res.writeHead(400, { 'Content-type': MIME_HTML,
'Location': '/' });
2011-04-23 21:36:08 +02:00
res.write(html("<p>Face validation error.</p>"));
2010-12-04 20:20:25 +01:00
res.end();
}
} else {
2011-04-23 21:36:08 +02:00
res.writeHead(400, { 'Content-type': MIME_HTML,
'Location': '/' });
res.write(html("<p>Huh?</p>"));
2010-12-04 20:20:25 +01:00
res.end();
}
});
2010-12-10 17:26:23 +01:00
app.get('/thanks', function(req, res) {
2011-04-23 19:57:58 +02:00
res.writeHead(200, { 'Content-type': MIME_HTML });
2010-12-10 17:26:23 +01:00
res.write(html("<p>Thanks, your vote may have been counted.</p>"));
res.end();
});
2010-12-04 20:20:25 +01:00
}
var server = Connect.createServer(
Connect.logger(),
Connect.bodyDecoder(),
Connect.router(nedap),
Connect.staticProvider(__dirname + '/static'),
Connect.errorHandler({ dumpExceptions: true, showStack: true })
);
wss.createServer({ server: server }).on('connection', function(conn) {
2010-12-06 19:10:44 +01:00
var authed = false;
2010-12-04 20:20:25 +01:00
2010-12-06 19:10:44 +01:00
conn.on('message', function(data) {
if (!authed) {
if (data.toString() === WS_KEY) {
console.warn('Authorized WebSocket');
backend = conn;
authed = true;
var reset = function() {
backend = null;
};
conn.on('close', reset);
conn.on('error', reset);
} else {
console.warn('Unauthorized backend WebSocket');
conn.close();
}
} else {
2010-12-04 22:04:58 +01:00
try {
var msg = JSON.parse(data);
console.log({msg: msg});
if (msg.joker) {
question = msg.joker.question;
answers = msg.joker.answers;
scores = [];
for(var i = 0; i < answers.length; i++)
scores[i] = 0;
}
if (msg.clear) {
question = null;
answers = null;
scores = null;
}
} catch (e) {
console.error(e.stack);
2010-12-04 20:20:25 +01:00
}
2010-12-06 19:10:44 +01:00
}
});
2010-12-04 20:20:25 +01:00
});
2011-04-22 23:06:06 +02:00
server.listen(80, '::');