Advertisement
Guest User

Untitled

a guest
Mar 31st, 2017
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.68 KB | None | 0 0
  1. /**
  2. * @file Exports a function that returns an Express router instance for
  3. * defining various request handlers.
  4. */
  5. 'use strict';
  6.  
  7. // Required Node.js modules.
  8. const bcrypt = require('bcrypt');
  9. const express = require('express');
  10.  
  11. // Required project modules.
  12. const auth = require('./auth.js');
  13. const debug = require('../utils/debug.js');
  14. const question = require('../utils/question.js');
  15. const rooms = require('../utils/rooms.js');
  16. const sequence = require('../utils/sequence.js');
  17. const shuffle = require('../utils/shuffle.js');
  18.  
  19. // Alias object prototypes.
  20. const Question = question.Question;
  21. const RoomManager = rooms.RoomManager;
  22.  
  23. // Define local constants.
  24. const SALT_ROUNDS = 10;
  25.  
  26.  
  27. /**
  28. * Creates and returns an Express-compatible router function.
  29. * @param {EventEmitter} app
  30. * @return {Function}
  31. */
  32. module.exports = function(app) {
  33.  
  34. let router = express.Router();
  35.  
  36.  
  37. // GET http://localhost:3000
  38. router.get('/', (request, response) => {
  39. console.log('index');
  40. request.db.transact([
  41. { sql: 'SELECT COUNT(*) FROM student;' },
  42. { sql: 'SELECT * FROM student LIMIT 1;' },
  43. { sql: 'SELECT * FROM student WHERE username = $1::text;', params: [ 'connor' ] }
  44. ], (error, results) => {
  45. if (error) {
  46. return console.log(error);
  47. }
  48. console.log(results[0].rows);
  49. });
  50. response.render('index');
  51. });
  52.  
  53.  
  54. // GET http://localhost:3000/signin
  55. router.get('/signin', (request, response) => {
  56. response.render('signin', {
  57. pageTitle: 'Sign In'
  58. });
  59. });
  60.  
  61.  
  62. // GET http://localhost:3000/quizzes-available
  63. router.get('/quizzes-available', auth, (request, response) => {
  64. let sql = 'SELECT q.id, q.title FROM student_in_section s INNER JOIN quiz q ON s.section_id = q.section_id WHERE s.student_id = $1::int;',
  65. params = [ request.session.user.id ];
  66.  
  67. request.db.query(sql, params, (error, results) => {
  68. if (error) {
  69. return console.log(error);
  70. }
  71.  
  72. response.render('quizzes-available', {
  73. pageTitle: 'Available Quizzes',
  74. groupId: request.session.user.student_group_id,
  75. quizzes: results.rows
  76. });
  77. });
  78. });
  79.  
  80.  
  81. // POST http://localhost:3000/signin
  82. router.post('/signin', (request, response) => {
  83. let username = request.body.username,
  84. password = request.body.password;
  85.  
  86. let sql = 'SELECT id, first_name, last_name, password, student_group_id FROM student WHERE username = $1::text LIMIT 1;',
  87. params = [ username ];
  88.  
  89. request.db.query(sql, params, (error, results) => {
  90. if (error) {
  91. return console.log(error);
  92. }
  93.  
  94. if (results.rows.length === 0) {
  95. return response.render('signin', {
  96. pageTitle: 'Sign In',
  97. error: 'Username/password mismatch.'
  98. });
  99. }
  100.  
  101. bcrypt.compare(password, results.rows[0].password).then(match => {
  102. if (match === true) {
  103. request.session.user = results.rows[0];
  104. return response.redirect('quizzes-available');
  105. }
  106.  
  107. response.render('signin', {
  108. pageTitle: 'Sign In',
  109. error: 'Username/password mismatch.'
  110. });
  111. });
  112. });
  113. });
  114.  
  115.  
  116. // GET http://localhost:3000/register
  117. router.get('/register', (request, response) => {
  118. response.render('register', {
  119. pageTitle: 'Sign Up'
  120. });
  121. });
  122.  
  123.  
  124. // POST http://localhost:3000/register
  125. router.post('/register', (request, response) => {
  126. let username = request.body.username,
  127. password = request.body.password,
  128. fName = request.body.fName,
  129. lName = request.body.lName,
  130. iNum = request.body.iNum;
  131.  
  132. bcrypt.hash(password, SALT_ROUNDS, (error, hash) => {
  133. if (error){
  134. return console.log(error);
  135. }
  136.  
  137. let sql = 'INSERT INTO student(username, password, first_name, last_name, i_number) VALUES ($1::text, $2::text, $3::text, $4::text, $5::text);',
  138. params = [ username, hash, fName, lName, iNum ];
  139.  
  140. request.db.query(sql, params, (error, results) => {
  141. if (error) {
  142. return console.log(error);
  143. }
  144.  
  145. response.redirect('/signin');
  146. });
  147. });
  148. });
  149.  
  150.  
  151. /**
  152. * Keeps track of which client websocket connections belong to which
  153. * user group for the application /group/:gid endpoint.
  154. * @type {RoomManager}
  155. */
  156. let groups = new RoomManager;
  157.  
  158.  
  159. // GET http://localhost:3000/group/:group_id/quiz/:quiz_id
  160. router.get('/group/:group_id/quiz/:quiz_id', auth, (request, response, next) => {
  161. if (request.session.user.student_group_id === Number(request.params.group_id)) {
  162. return next();
  163. }
  164. response.redirect('/quizzes-available');
  165. }, (request, response) => {
  166. request.ws.once('connection', socket => {
  167. let key = `${request.params.group_id}:${request.params.quiz_id}`;
  168. let group = groups.add(key).add(socket).broadcast({
  169. type: 'joined',
  170. id: request.session.user.id,
  171. first_name: request.session.user.first_name
  172. });
  173.  
  174. socket.send(JSON.stringify({
  175. timestamp: Math.floor(new Date() / 1000),
  176. type: 'identification',
  177. id: request.session.user.id,
  178. first_name: request.session.user.first_name
  179. }));
  180.  
  181. new Promise((resolve, reject) => {
  182. if (group.questions !== undefined && group.questions.length) {
  183. return resolve(group.questions);
  184. }
  185.  
  186. let sql = 'SELECT q.id AS question_id, q.content AS question_content, qa.id AS answer_id, qa.content AS answer_content FROM question q INNER JOIN question_answer qa ON qa.question_id = q.id WHERE q.quiz_id = $1::int ORDER BY q.id, qa.id;',
  187. params = [ request.params.quiz_id ];
  188.  
  189. request.db.query(sql, params).then(result => {
  190. let questions = [];
  191.  
  192. while(result.rows.length) {
  193. let answers = shuffle(result.rows.splice(0, 4)),
  194. question = new Question(answers[0]['question_id'], answers[0]['question_content']);
  195.  
  196. for (const answer of answers) {
  197. question.addAnswer(answer['answer_id'], answer['answer_content']);
  198. }
  199. questions.push(question);
  200. }
  201.  
  202. group.questions = questions;
  203. resolve(group.questions);
  204. });
  205. }).then(questions => {
  206. sequence(questions, (results, question, next) => {
  207. if (group.currentQuestion === undefined) {
  208. group.currentQuestion = 0;
  209. group.broadcast(group.questions[group.currentQuestion].toJSON());
  210. }
  211.  
  212. function response(data) {
  213. let parsed = JSON.parse(data);
  214.  
  215. if (!parsed.type) {
  216. return;
  217. }
  218.  
  219. // if type === 'appeal'
  220.  
  221. if (parsed.type !== 'answerConfirm') {
  222. return group.broadcast(parsed);
  223. }
  224.  
  225. let sql = 'SELECT correct FROM question_answer WHERE id = $1::int LIMIT 1;',
  226. params = [ parsed['answer_id'] ];
  227.  
  228. request.db.query(sql, params, (error, result) => {
  229. if (error) {
  230. return console.log(error);
  231. }
  232.  
  233. let sql = 'INSERT INTO group_answer(student_group_id,question_answer_id) VALUES ($1::int, $2::int);',
  234. params = [ request.params.group_id, parsed['answer_id'] ];
  235.  
  236. request.db.query(sql,params,function(){
  237.  
  238.  
  239. if (result.rows[0].correct === true) {
  240. socket.removeEventListener('message', response);
  241. group.broadcast({
  242. type: 'answerCorrect',
  243. answer_id : Number(parsed['answer_id'])
  244. });
  245.  
  246. setTimeout(() => {
  247. if (++group.currentQuestion < group.questions.length) {
  248. group.broadcast(group.questions[group.currentQuestion].toJSON());
  249. }
  250. next();
  251. }, 5000);
  252. } else {
  253. group.broadcast({
  254. type: 'answerIncorrect',
  255. answer_id : Number(parsed['answer_id'])
  256. });
  257. }
  258. });
  259.  
  260. });
  261. };
  262.  
  263. socket.on('message', response);
  264. }, () => {
  265.  
  266. let sql = 'INSERT INTO grade (student_group_id, quiz_id, score) SELECT t.student_group_id AS student_group_id,t.quiz_id AS quiz_id, SUM(t.answers) AS total_score FROM (SELECT ga.student_group_id AS student_group_id,qz.id AS quiz_id, CASE WHEN COUNT(qa.id) = 1 THEN 4 WHEN COUNT(qa.id) = 2 THEN 2 WHEN COUNT(qa.id) = 3 THEN 1 WHEN COUNT(qa.id) = 4 THEN 0 END AS answers FROM group_answer ga INNER JOIN question_answer qa ON ga.question_answer_id = qa.id INNER JOIN question qn ON qa.question_id = qn.id INNER JOIN quiz qz ON qn.quiz_id = qz.id WHERE ga.student_group_id = $1::int AND qz.id = $2::int GROUP BY ga.student_group_id, qz.id, qa.question_id) AS t GROUP BY t.student_group_id, t.quiz_id;',
  267. params = [request.params.group_id, request.params.quiz_id];
  268.  
  269. request.db.query(sql,params,function(){
  270. group.broadcast({
  271. type: 'notice',
  272. message: 'QUIZ OVER'
  273. });
  274.  
  275. response.redirect('/');
  276. });
  277. });
  278. });
  279.  
  280. socket.on('close', error => {
  281. group.remove(socket).broadcast({
  282. type: 'left',
  283. id: request.session.user.id
  284. });
  285. });
  286. });
  287.  
  288. response.render('quiz');
  289. });
  290.  
  291. return router;
  292. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement