From d2e837d44b625e80cefc7cf325c2badc58e6eae9 Mon Sep 17 00:00:00 2001 From: Luigi Pinca Date: Sun, 24 Mar 2019 09:11:12 +0100 Subject: [PATCH] formatted code with prettier --- README.md | 6 +- app.js | 89 +++-- config.json | 9 +- lib/captcha.js | 3 +- lib/email/mailer.js | 45 ++- lib/match.js | 50 +-- lib/middleware/ban-handler.js | 12 +- lib/middleware/error-handler.js | 6 +- lib/prng.js | 11 +- lib/redis-clients.js | 10 +- lib/rooms.js | 208 +++++----- lib/sparks.js | 89 +++-- lib/stats.js | 31 +- lib/utils.js | 62 ++- public/js/app.js | 661 +++++++++++++++++--------------- public/js/bootstrap.min.js | 304 ++++++++++++++- public/js/leaderboards.js | 18 +- routes/site.js | 34 +- routes/user.js | 207 +++++----- util/artist-ids.js | 42 +- util/load_sample_tracks.js | 71 ++-- 21 files changed, 1140 insertions(+), 828 deletions(-) diff --git a/README.md b/README.md index e21ffaa..19e7f99 100644 --- a/README.md +++ b/README.md @@ -68,9 +68,9 @@ compatibility. ## Bug tracker -Have a bug? Please create an [issue](https://github.com/lpinca/binb/issues) -here on GitHub, with a description of the problem, how to reproduce it and in -what browser it occurred. +Have a bug? Please create an [issue](https://github.com/lpinca/binb/issues) here +on GitHub, with a description of the problem, how to reproduce it and in what +browser it occurred. ## Copyright and license diff --git a/app.js b/app.js index 7d80413..0227497 100644 --- a/app.js +++ b/app.js @@ -1,59 +1,62 @@ 'use strict'; -/** - * Module dependencies. - */ - -var banHandler = require('./lib/middleware/ban-handler') - , errorHandler = require('./lib/middleware/error-handler') - , express = require('express') - , favicon = require('serve-favicon') - , http = require('http') - , port = require('./config').port - , session = require('express-session') - , RedisStore = require('connect-redis')(session) - , secret = process.env.SITE_SECRET || 'shhhh, very secret' - , cookieParser = require('cookie-parser')(secret) - , site = require('./routes/site') - , urlencoded = require('body-parser').urlencoded - , user = require('./routes/user') - , usersdb = require('./lib/redis-clients').users; +const banHandler = require('./lib/middleware/ban-handler'); +const errorHandler = require('./lib/middleware/error-handler'); +const express = require('express'); +const favicon = require('serve-favicon'); +const http = require('http'); +const port = require('./config').port; +const session = require('express-session'); +const RedisStore = require('connect-redis')(session); +const secret = process.env.SITE_SECRET || 'shhhh, very secret'; +const cookieParser = require('cookie-parser')(secret); +const site = require('./routes/site'); +const urlencoded = require('body-parser').urlencoded; +const user = require('./routes/user'); +const usersdb = require('./lib/redis-clients').users; /** * Setting up Express. */ -var app = express() - , production = process.env.NODE_ENV === 'production' - , pub = __dirname + '/public' // Path to public directory - , sessionstore = new RedisStore({client: usersdb}) - , server = http.createServer(app); // HTTP server object +const app = express(); +const production = process.env.NODE_ENV === 'production'; +const pub = __dirname + '/public'; // Path to public directory +const sessionstore = new RedisStore({ client: usersdb }); +const server = http.createServer(app); // HTTP server object // Configuration app.set('view engine', 'pug'); -app.use('/static', express.static(pub, {maxAge: 2419200000})); // 4 weeks = 2419200000 ms -app.use(favicon(pub + '/img/favicon.ico', {maxAge: 2419200000})); +app.use('/static', express.static(pub, { maxAge: 2419200000 })); // 4 weeks = 2419200000 ms +app.use(favicon(pub + '/img/favicon.ico', { maxAge: 2419200000 })); app.use(banHandler); -app.use(urlencoded({extended: false})); +app.use(urlencoded({ extended: false })); app.use(cookieParser); -app.use(session({ - cookie: { - secure: production, - maxAge: 14400000 // 4 h = 14400000 ms - }, - proxy: production, - resave: false, - rolling: true, - saveUninitialized: true, - secret: secret, - store: sessionstore -})); +app.use( + session({ + cookie: { + secure: production, + maxAge: 14400000 // 4 h = 14400000 ms + }, + proxy: production, + resave: false, + rolling: true, + saveUninitialized: true, + secret: secret, + store: sessionstore + }) +); // Routes app.get('/', site.home); app.get('/artworks', site.artworks); app.get('/changepasswd', site.validationErrors, site.changePasswd); -app.post('/changepasswd', user.validateChangePasswd, user.checkOldPasswd, user.changePasswd); +app.post( + '/changepasswd', + user.validateChangePasswd, + user.checkOldPasswd, + user.changePasswd +); app.get('/leaderboards', user.leaderboards); app.get('/login', site.validationErrors, site.login); app.post('/login', user.validateLogin, user.checkUser, user.authenticate); @@ -64,7 +67,13 @@ app.get('/resetpasswd', site.validationErrors, site.resetPasswd); app.post('/resetpasswd', user.resetPasswd); app.get('/sliceleaderboard', user.sliceLeaderboard); app.get('/signup', site.validationErrors, site.signup); -app.post('/signup', user.validateSignUp, user.userExists, user.emailExists, user.createAccount); +app.post( + '/signup', + user.validateSignUp, + user.userExists, + user.emailExists, + user.createAccount +); app.get('/:room', site.room); app.get('/user/:username', user.profile); diff --git a/config.json b/config.json index c114617..de7bf86 100644 --- a/config.json +++ b/config.json @@ -1,13 +1,6 @@ { "gameswithnorepeats": 3, "port": 8138, - "rooms": [ - "hits", - "pop", - "rock", - "rap", - "oldies", - "mixed" - ], + "rooms": ["hits", "pop", "rock", "rap", "oldies", "mixed"], "songsinarun": 15 } diff --git a/lib/captcha.js b/lib/captcha.js index 640bdc0..644ba2d 100644 --- a/lib/captcha.js +++ b/lib/captcha.js @@ -2,7 +2,8 @@ const { createCanvas } = require('canvas'); -const characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; +const characters = + 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; /** * Captcha constructor. diff --git a/lib/email/mailer.js b/lib/email/mailer.js index 2f88d1f..4885c62 100644 --- a/lib/email/mailer.js +++ b/lib/email/mailer.js @@ -1,25 +1,21 @@ 'use strict'; -/** - * Module dependencies. - */ - -var fs = require('fs') - , pug = require('pug') - , nodemailer = require('nodemailer') - , texttemplate = fs.readFileSync(__dirname + '/template.txt', 'utf-8'); +const fs = require('fs'); +const pug = require('pug'); +const nodemailer = require('nodemailer'); +const texttemplate = fs.readFileSync(__dirname + '/template.txt', 'utf-8'); /** * Generate the HTML version of the message. */ -var HTMLMessage = pug.compileFile(__dirname + '/template.pug'); +const HTMLMessage = pug.compileFile(__dirname + '/template.pug'); /** * Generate the plaintext version of the message. */ -var plaintextMessage = function(token) { +const plaintextMessage = function(token) { return texttemplate.replace(//, token); }; @@ -27,7 +23,7 @@ var plaintextMessage = function(token) { * Create a reusable transport method. */ -var transport = nodemailer.createTransport({ +const transport = nodemailer.createTransport({ service: 'SendGrid', auth: { user: process.env.SENDGRID_USER, @@ -40,17 +36,20 @@ var transport = nodemailer.createTransport({ */ exports.sendEmail = function(to, token, callback) { - transport.sendMail({ - from: 'binb ', - to: to, - subject: 'binb password recovery', - html: HTMLMessage({ token: token }), - text: plaintextMessage(token) - }, function(err, info) { - if (err) { - return callback(err); + transport.sendMail( + { + from: 'binb ', + to: to, + subject: 'binb password recovery', + html: HTMLMessage({ token: token }), + text: plaintextMessage(token) + }, + function(err, info) { + if (err) { + return callback(err); + } + + callback(null, info); } - - callback(null, info); - }); + ); }; diff --git a/lib/match.js b/lib/match.js index 594c978..f45d1c8 100644 --- a/lib/match.js +++ b/lib/match.js @@ -12,8 +12,8 @@ * Cambridge, UK: Cambridge University Press. pp 263-264. ISBN 0-521-58519-8. */ -var checkDistance = function(s1, s2) { - var k = Math.log(s1.length); +const checkDistance = function(s1, s2) { + let k = Math.log(s1.length); k = Math.round(k); if (k === 0) { @@ -23,8 +23,11 @@ var checkDistance = function(s1, s2) { return false; } - var d = [] - , i, j, l, m; + const d = []; + let i; + let j; + let l; + let m; for (i = 0; i <= s1.length; i++) { d[i] = []; // Now d is a matrix with s1.length + 1 rows @@ -35,22 +38,22 @@ var checkDistance = function(s1, s2) { } for (i = 1; i <= s1.length; i++) { - l = ((i - k) < 1) ? 1 : i - k; - m = ((i + k) > s2.length) ? s2.length : i + k; + l = i - k < 1 ? 1 : i - k; + m = i + k > s2.length ? s2.length : i + k; for (j = l; j <= m; j++) { - if (s1.charAt(i-1) === s2.charAt(j-1)) { - d[i][j] = d[i-1][j-1]; + if (s1.charAt(i - 1) === s2.charAt(j - 1)) { + d[i][j] = d[i - 1][j - 1]; continue; } - if (j === l && d[i][j-1] === undefined) { - d[i][j] = Math.min(d[i-1][j-1] + 1, d[i-1][j] + 1); + if (j === l && d[i][j - 1] === undefined) { + d[i][j] = Math.min(d[i - 1][j - 1] + 1, d[i - 1][j] + 1); continue; } - if (j === m && d[i-1][j] === undefined) { - d[i][j] = Math.min(d[i][j-1] + 1, d[i-1][j-1] + 1); + if (j === m && d[i - 1][j] === undefined) { + d[i][j] = Math.min(d[i][j - 1] + 1, d[i - 1][j - 1] + 1); continue; } - d[i][j] = Math.min(d[i][j-1] + 1, d[i-1][j-1] + 1, d[i-1][j] + 1); + d[i][j] = Math.min(d[i][j - 1] + 1, d[i - 1][j - 1] + 1, d[i - 1][j] + 1); } } @@ -61,7 +64,7 @@ var checkDistance = function(s1, s2) { * Supported artist name abbreviations. */ -var abbreviations = { +const abbreviations = { bfmv: 'bullet for my valentine', brmc: 'black rebel motorcycle club', ccr: 'creedence clearwater revival', @@ -88,7 +91,7 @@ module.exports = function(pattern, guess, enableartistrules) { return true; } - var _pattern; + let _pattern; if (~pattern.indexOf('.')) { // Ignore dots @@ -99,7 +102,7 @@ module.exports = function(pattern, guess, enableartistrules) { } if (~pattern.indexOf('-')) { // Ignore dashes - _pattern = pattern.replace(/\-/g, ''); + _pattern = pattern.replace(/-/g, ''); if (checkDistance(_pattern, guess)) { return true; } @@ -121,11 +124,11 @@ module.exports = function(pattern, guess, enableartistrules) { if (enableartistrules) { // Split artist name on " & " and ", " (it can be composed by more names) - var splits = pattern.split(/ & |, /) - , multipleartists = splits.length !== 1; + const splits = pattern.split(/ & |, /); + const multipleartists = splits.length !== 1; - for (var i = 0; i < splits.length; i++) { - var artist = splits[i]; + for (let i = 0; i < splits.length; i++) { + const artist = splits[i]; if (multipleartists) { if (checkDistance(artist, guess)) { return true; @@ -139,7 +142,7 @@ module.exports = function(pattern, guess, enableartistrules) { } if (artist.indexOf('the ') === 0) { // Ignore "the" at the beginning of artist name - var nothe = artist.replace(/^the /, ''); + const nothe = artist.replace(/^the /, ''); if (checkDistance(nothe, guess)) { return true; } @@ -160,8 +163,7 @@ module.exports = function(pattern, guess, enableartistrules) { return true; } } - } - else { + } else { if (~pattern.indexOf(',')) { // Ignore commas _pattern = pattern.replace(/,/g, ''); @@ -171,7 +173,7 @@ module.exports = function(pattern, guess, enableartistrules) { } if (/\(.+\)\??(?: \[.+\])?/.test(pattern)) { // Ignore additional info e.g. "(Love Theme from Titanic)" - var normalized = pattern.replace(/\(.+\)\??(?: \[.+\])?/, '').trim(); + const normalized = pattern.replace(/\(.+\)\??(?: \[.+\])?/, '').trim(); if (checkDistance(normalized, guess)) { return true; } diff --git a/lib/middleware/ban-handler.js b/lib/middleware/ban-handler.js index a561c08..2f84383 100644 --- a/lib/middleware/ban-handler.js +++ b/lib/middleware/ban-handler.js @@ -1,12 +1,8 @@ 'use strict'; -/** - * Module dependencies. - */ - -var db = require('../redis-clients').users - , forwarded = require('forwarded-for') - , utils = require('../utils'); +const db = require('../redis-clients').users; +const forwarded = require('forwarded-for'); +const utils = require('../utils'); /** * Expose a middleware to filter banned IPs. @@ -15,7 +11,7 @@ var db = require('../redis-clients').users module.exports = function(req, res, next) { res.setHeader('Cache-Control', 'no-store, no-cache'); - var address = forwarded(req, req.headers); + const address = forwarded(req, req.headers); db.ttl(['ban:' + address.ip], function(err, ttl) { if (err) { diff --git a/lib/middleware/error-handler.js b/lib/middleware/error-handler.js index 13c364a..9749519 100644 --- a/lib/middleware/error-handler.js +++ b/lib/middleware/error-handler.js @@ -1,10 +1,6 @@ 'use strict'; -/** - * Module dependencies. - */ - -var http = require('http'); +const http = require('http'); /** * Basic error handling middleware. diff --git a/lib/prng.js b/lib/prng.js index bceeacc..ad3e774 100644 --- a/lib/prng.js +++ b/lib/prng.js @@ -1,17 +1,14 @@ 'use strict'; -/** - * Module dependencies. - */ +const crypto = require('crypto'); -var crypto = require('crypto') - , rrange = 4294967296; +const rrange = 4294967296; /** * Return an integer, pseudo-random number in the range [0, 2^32). */ -var nextInt = function() { +const nextInt = function() { return crypto.randomBytes(4).readUInt32BE(0); }; @@ -19,7 +16,7 @@ var nextInt = function() { * Return a floating-point, pseudo-random number in the range [0, 1). */ -var rand = function() { +const rand = function() { return nextInt() / rrange; }; diff --git a/lib/redis-clients.js b/lib/redis-clients.js index dda178f..be060a6 100644 --- a/lib/redis-clients.js +++ b/lib/redis-clients.js @@ -1,17 +1,13 @@ 'use strict'; -/** - * Module dependencies. - */ - -var redis = require('redis'); +const redis = require('redis'); /** * Setting up redis clients. */ -var songsclient = redis.createClient({ auth_pass: process.env.DB_AUTH }) - , usersclient = redis.createClient({ auth_pass: process.env.DB_AUTH }); +const songsclient = redis.createClient({ auth_pass: process.env.DB_AUTH }); +const usersclient = redis.createClient({ auth_pass: process.env.DB_AUTH }); songsclient.on('error', function(err) { console.error(err.message); diff --git a/lib/rooms.js b/lib/rooms.js index 1f96581..c955b97 100644 --- a/lib/rooms.js +++ b/lib/rooms.js @@ -1,30 +1,27 @@ 'use strict'; -/** - * Module dependencies. - */ - -var amatch = require('./match') - , clients = require('./redis-clients') - , config = require('../config') - , fifolength = config.songsinarun * config.gameswithnorepeats - , primus - , randInt = require('./prng').randInt - , rooms = {} // The Object that contains all the room instances - , songsdb = clients.songs - , sparks - , updateStats = require('./stats') - , usersdb = clients.users - , utils = require('./utils') - , isString = utils.isString - , isUsername = utils.isUsername; +const amatch = require('./match'); +const clients = require('./redis-clients'); +const config = require('../config'); +const randInt = require('./prng').randInt; +const updateStats = require('./stats'); +const utils = require('./utils'); + +const fifolength = config.songsinarun * config.gameswithnorepeats; +const rooms = {}; // The Object that contains all the room instances +const songsdb = clients.songs; +const usersdb = clients.users; +const isString = utils.isString; +const isUsername = utils.isUsername; +let primus; +let sparks; /** * Expose a function to set up the rooms. */ module.exports = function(options) { - var refs = require('./sparks')(options); + const refs = require('./sparks')(options); primus = refs.primus; sparks = refs.sparks; config.rooms.forEach(function(room) { @@ -39,22 +36,22 @@ module.exports.rooms = rooms; */ function Room(roomname) { - this.artist = null; // Artists in lowercase - this.artistName = null; // Artists of the track - this.artworkUrl = null; // The URL of the album cover - this.feat = null; // Featured artists - this.finishline = 1; // A counter to handle the 3 fastest answers - this.playedtracks = []; // The list of already played songs - this.previewUrl = null; // The URL for the preview of the track + this.artist = null; // Artists in lowercase + this.artistName = null; // Artists of the track + this.artworkUrl = null; // The URL of the album cover + this.feat = null; // Featured artists + this.finishline = 1; // A counter to handle the 3 fastest answers + this.playedtracks = []; // The list of already played songs + this.previewUrl = null; // The URL for the preview of the track this.roomname = roomname; - this.songcounter = 0; // A counter for the track of the current game - this.songtimeleft = 0; // Remaining time for the current playing track - this.status = 3; // The room status - this.title = null; // Title in lowercase - this.trackName = null; // Title of the track + this.songcounter = 0; // A counter for the track of the current game + this.songtimeleft = 0; // Remaining time for the current playing track + this.status = 3; // The room status + this.title = null; // Title in lowercase + this.trackName = null; // Title of the track this.trackViewUrl = null; // The iTunes URL of the track - this.trackscount = 0; // The number of available tracks in the room - this.totusers = 0; // The number of players in the room + this.trackscount = 0; // The number of available tracks in the room + this.totusers = 0; // The number of players in the room this.usersData = Object.create(null); this.initialize(); @@ -64,18 +61,18 @@ function Room(roomname) { * Room states. */ -Room.PLAYING = 0; // A track is playing -Room.LOADING = 1; // A track is loading -Room.ENDING = 2; // The game is over -Room.STARTING = 3; // A new game is about to start +Room.PLAYING = 0; // A track is playing +Room.LOADING = 1; // A track is loading +Room.ENDING = 2; // The game is over +Room.STARTING = 3; // A new game is about to start /** * Add points and collect players' statistics. */ Room.prototype.addPointsAndStats = function(nickname, allinone) { - var stats = {} - , userData = this.usersData[nickname]; + const stats = {}; + const userData = this.usersData[nickname]; switch (this.finishline) { case 1: @@ -145,8 +142,8 @@ Room.prototype.addPointsAndStats = function(nickname, allinone) { */ Room.prototype.addUser = function(spark, loggedin) { - var nickname = spark.nickname - , usersData = this.usersData; + const nickname = spark.nickname; + const usersData = this.usersData; sparks[nickname] = spark; @@ -179,7 +176,10 @@ Room.prototype.addUser = function(spark, loggedin) { status: this.status } }); - primus.room(this.roomname).except(spark.id).send('newuser', nickname, usersData); + primus + .room(this.roomname) + .except(spark.id) + .send('newuser', nickname, usersData); }; /** @@ -187,11 +187,11 @@ Room.prototype.addUser = function(spark, loggedin) { */ Room.prototype.gameOver = function() { - var podium = [] - , usersData = this.usersData; + const podium = []; + const usersData = this.usersData; // Build podium - for (var key in usersData) { + for (const key in usersData) { podium.push(usersData[key]); } podium.sort(function(a, b) { @@ -226,7 +226,7 @@ Room.prototype.gameOver = function() { */ Room.prototype.initialize = function() { - var room = this; + const room = this; songsdb.zcard([this.roomname], function(err, card) { if (err) { @@ -243,7 +243,7 @@ Room.prototype.initialize = function() { */ Room.prototype.onChatMessage = function(msg, spark, to) { - var from = spark.nickname; + const from = spark.nickname; if (isString(to)) { // Check if the recipient is in the room @@ -255,12 +255,16 @@ Room.prototype.onChatMessage = function(msg, spark, to) { } // Censor answers from chat - var feat = this.feat - , msglcase = msg.toLowerCase(); - - if (this.status === Room.PLAYING && (amatch(this.artist, msglcase, true) || - (feat && amatch(feat, msglcase, true)) || amatch(this.title, msglcase))) { - var notice = 'You are probably right, but you have to use the box above.'; + const feat = this.feat; + const msglcase = msg.toLowerCase(); + + if ( + this.status === Room.PLAYING && + (amatch(this.artist, msglcase, true) || + (feat && amatch(feat, msglcase, true)) || + amatch(this.title, msglcase)) + ) { + const notice = 'You are probably right, but you have to use the box above.'; spark.send('chatmsg', notice, 'binb', from); return; } @@ -277,14 +281,14 @@ Room.prototype.onGuess = function(spark, guess) { return; } - var artist = this.artist - , feat = this.feat - , title = this.title - , userData = this.usersData[spark.nickname]; + const artist = this.artist; + const feat = this.feat; + const title = this.title; + const userData = this.usersData[spark.nickname]; // The user hasn't guessed anything if (!userData.matched) { - if ((artist === title) && amatch(title, guess, true)) { + if (artist === title && amatch(title, guess, true)) { return this.onPair(spark, true); } if (amatch(artist, guess, true) || (feat && amatch(feat, guess, true))) { @@ -332,7 +336,7 @@ Room.prototype.onIgnore = function(who, executor, callback) { */ Room.prototype.onKick = function(who, why, executor, duration, callback) { - var room = this; + const room = this; if (typeof duration === 'function') { callback = duration; @@ -352,9 +356,9 @@ Room.prototype.onKick = function(who, why, executor, duration, callback) { // Check if the target player is in the room if (room.usersData[who]) { - var notice = 'you have been kicked by ' + executor + - (why && ' (' + why + ')') + '.'; - var target = sparks[who]; + const notice = + 'you have been kicked by ' + executor + (why && ' (' + why + ')') + '.'; + const target = sparks[who]; if (duration) { usersdb.setex('ban:' + target.address.ip, duration, who); @@ -373,9 +377,9 @@ Room.prototype.onKick = function(who, why, executor, duration, callback) { */ Room.prototype.onMatch = function(spark, what) { - var nickname = spark.nickname - , usersData = this.usersData - , userData = usersData[nickname]; + const nickname = spark.nickname; + const usersData = this.usersData; + const userData = usersData[nickname]; userData.matched = what; userData.points++; @@ -407,8 +411,8 @@ Room.prototype.onPair = function(spark, allinone) { */ Room.prototype.join = function(spark, nickname) { - var feedback - , room = this; + let feedback; + const room = this; if (nickname === 'binb') { feedback = 'That name is reserved.'; @@ -455,7 +459,7 @@ Room.prototype.join = function(spark, nickname) { Room.prototype.onUnignore = function(who, executor) { if (this.usersData[who]) { - var notice = executor + ' has stopped ignoring you.'; + const notice = executor + ' has stopped ignoring you.'; sparks[who].send('chatmsg', notice, 'binb', who); } }; @@ -465,7 +469,7 @@ Room.prototype.onUnignore = function(who, executor) { */ Room.prototype.removeUser = function(nickname) { - var usersData = this.usersData; + const usersData = this.usersData; // Delete the references delete sparks[nickname]; @@ -483,10 +487,10 @@ Room.prototype.removeUser = function(nickname) { */ Room.prototype.resetPoints = function(roundonly) { - var usersData = this.usersData - , userData; + const usersData = this.usersData; + let userData; - for (var key in usersData) { + for (const key in usersData) { userData = usersData[key]; if (!roundonly) { userData.points = 0; @@ -509,15 +513,15 @@ Room.prototype.resetPoints = function(roundonly) { Room.prototype.sendLoadTrack = function() { this.status = Room.LOADING; - var index = randInt(this.trackscount) - , room = this; + const index = randInt(this.trackscount); + const room = this; songsdb.zrange([this.roomname, index, index], function(err, res) { if (err) { throw err; } - var id = res[0]; + const id = res[0]; // Check if extracted track is in the list of already played tracks if (~room.playedtracks.indexOf(id)) { return room.sendLoadTrack(); @@ -525,30 +529,33 @@ Room.prototype.sendLoadTrack = function() { room.playedtracks.push(id); - songsdb.hmget([ - 'song:' + id - , 'artistName' - , 'trackName' - , 'previewUrl' - , 'artworkUrl60' - , 'trackViewUrl' - ], function(err, replies) { - if (err) { - throw err; + songsdb.hmget( + [ + 'song:' + id, + 'artistName', + 'trackName', + 'previewUrl', + 'artworkUrl60', + 'trackViewUrl' + ], + function(err, replies) { + if (err) { + throw err; + } + + room.artistName = replies[0]; + room.artist = room.artistName.toLowerCase(); + room.trackName = replies[1]; + room.title = room.trackName.toLowerCase(); + room.feat = /feat\. (.+?)[)\]]/.test(room.title) ? RegExp.$1 : null; + room.previewUrl = replies[2]; + room.artworkUrl = replies[3]; + room.trackViewUrl = replies[4]; + primus.room(room.roomname).send('loadtrack', room.previewUrl); + + setTimeout(room.sendPlayTrack.bind(room), 5000); } - - room.artistName = replies[0]; - room.artist = room.artistName.toLowerCase(); - room.trackName = replies[1]; - room.title = room.trackName.toLowerCase(); - room.feat = /feat\. (.+?)[)\]]/.test(room.title) ? RegExp.$1 : null; - room.previewUrl = replies[2]; - room.artworkUrl = replies[3]; - room.trackViewUrl = replies[4]; - primus.room(room.roomname).send('loadtrack', room.previewUrl); - - setTimeout(room.sendPlayTrack.bind(room), 5000); - }); + ); }); }; @@ -598,12 +605,11 @@ Room.prototype.sendTrackInfo = function() { */ Room.prototype.startTimer = function(end, delay) { - var interval - , room = this; + const room = this; room.songtimeleft = end - Date.now(); - interval = setInterval(function() { + const interval = setInterval(function() { room.songtimeleft = end - Date.now(); if (room.songtimeleft < delay) { clearInterval(interval); diff --git a/lib/sparks.js b/lib/sparks.js index c2509f2..abc4732 100644 --- a/lib/sparks.js +++ b/lib/sparks.js @@ -1,24 +1,21 @@ 'use strict'; -/** - * Module dependencies. - */ - -var config = require('../config') - , db = require('./redis-clients').users - , fs = require('fs') - , uglify = require('uglify-js') - , Primus = require('primus') - , primus - , primusemitter = require('primus-emitter') - , primusrooms = require('primus-rooms') - , rooms = require('./rooms').rooms - , sessionstore - , sparks = Object.create(null) // Sparks of all rooms - , utils = require('./utils') - , banDuration = utils.banDuration - , isFunction = utils.isFunction - , isString = utils.isString; +const config = require('../config'); +const db = require('./redis-clients').users; +const fs = require('fs'); +const Primus = require('primus'); +const primusemitter = require('primus-emitter'); +const primusrooms = require('primus-rooms'); +const rooms = require('./rooms').rooms; +const uglify = require('uglify-js'); +const utils = require('./utils'); + +const banDuration = utils.banDuration; +const isFunction = utils.isFunction; +const isString = utils.isString; +const sparks = Object.create(null); // Sparks of all rooms +let primus; +let sessionstore; /** * Expose a function to set up Primus. @@ -34,18 +31,14 @@ module.exports = function(options) { emitter: primusemitter, rooms: primusrooms }, - rooms: {wildcard: false}, + rooms: { wildcard: false }, transformer: 'websockets' }); // Remove unneeded middleware - [ - 'cors', - 'no-cache', - 'primus.js', - 'spec', - 'x-xss' - ].forEach(function(middleware) { + ['cors', 'no-cache', 'primus.js', 'spec', 'x-xss'].forEach(function( + middleware + ) { primus.remove(middleware); }); @@ -56,26 +49,26 @@ module.exports = function(options) { primus.on('joinroom', joinRoom); primus.on('log', function(type) { if (type === 'error') { - var err = arguments[1]; + const err = arguments[1]; console.error(err.stack || err.message); } }); // Minify and store the client-side library in the public directory - var library = uglify.minify(primus.library()); + const library = uglify.minify(primus.library()); fs.writeFileSync(__dirname + '/../public/js/primus.min.js', library.code); - return {primus: primus, sparks: sparks}; + return { primus: primus, sparks: sparks }; }; /** * Authorization handler. */ -var authorize = function(req, authorized) { - var cookies = req.signedCookies; +function authorize(req, authorized) { + const cookies = req.signedCookies; if (!cookies['connect.sid']) { - var err = new Error('connect.sid cookie not transmitted'); + const err = new Error('connect.sid cookie not transmitted'); console.error(err.message); return authorized(err); } @@ -97,26 +90,30 @@ var authorize = function(req, authorized) { authorized(); }); }); -}; +} /** * Handle `connection` event. */ -var connection = function(spark) { - var nickname = spark.request.cookies.nickname - , user = spark.request.user - , room = spark.query.room; +function connection(spark) { + const nickname = spark.request.cookies.nickname; + const user = spark.request.user; + const room = spark.query.room; - spark.send('overview', config.rooms.reduce(function(data, room) { - data[room] = rooms[room].totusers; - return data; - }, {})); + spark.send( + 'overview', + config.rooms.reduce(function(data, room) { + data[room] = rooms[room].totusers; + return data; + }, {}) + ); if (!~config.rooms.indexOf(room)) return; if (user) { - if (sparks[user]) { // User already in a room + if (sparks[user]) { + // User already in a room spark.send('alreadyinaroom'); } else { spark.nickname = user; @@ -137,13 +134,13 @@ var connection = function(spark) { } }); } -}; +} /** * Handle `joinroom` event. */ -var joinRoom = function(room, spark) { +function joinRoom(room, spark) { room = rooms[room]; spark.on('ban', function(who, why, duration, callback) { if ( @@ -188,4 +185,4 @@ var joinRoom = function(room, spark) { room.onUnignore(who, spark.nickname); } }); -}; +} diff --git a/lib/stats.js b/lib/stats.js index 7a6f22e..2f81f7b 100644 --- a/lib/stats.js +++ b/lib/stats.js @@ -1,16 +1,12 @@ 'use strict'; -/** - * Module dependencies. - */ - -var db = require('./redis-clients').users; +const db = require('./redis-clients').users; /** * Update user statistics. */ -var updateStats = function(key, multi, username, stats) { +const updateStats = function(key, multi, username, stats) { if (stats.points) { // Update total points multi.hincrby(key, 'totpoints', stats.points); @@ -51,25 +47,24 @@ var updateStats = function(key, multi, username, stats) { */ module.exports = function(username, stats) { - var key = 'user:' + username - , multi = db.multi(); + const key = 'user:' + username; + const multi = db.multi(); if (stats.guesstime) { - var args = [ - key - , 'bestscore' - , 'bestguesstime' - , 'worstguesstime' - , 'totguesstime' - , 'guessed' + const args = [ + key, + 'bestscore', + 'bestguesstime', + 'worstguesstime', + 'totguesstime', + 'guessed' ]; db.hmget(args, function(err, replies) { if (err) { return console.error(err.message); } if (stats.guesstime < 1000) { - stats.guesstime = replies[4] !== '0' - ? Math.round(replies[3] / replies[4]) - : 15000; + stats.guesstime = + replies[4] !== '0' ? Math.round(replies[3] / replies[4]) : 15000; } if (stats.userscore > replies[0]) { // Set personal best diff --git a/lib/utils.js b/lib/utils.js index 9f92af9..8f2a8d2 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -1,10 +1,6 @@ 'use strict'; -/** - * Module dependencies. - */ - -var db = require('./redis-clients').users; +const db = require('./redis-clients').users; /** * Convert the duration of a ban from minutes to seconds and return the value. @@ -21,18 +17,18 @@ exports.banDuration = function(str) { */ exports.buildLeaderboards = function(pointsresults, timesresults) { - var obj = { + const obj = { pointsleaderboard: [], timesleaderboard: [] }; - for (var i=0; ibestguesstime' - , 'get' - , '#' - , 'get' - , 'user:*->bestguesstime' - , 'limit' - , offset - , '30' + const params = [ + 'users', + 'by', + 'user:*->bestguesstime', + 'get', + '#', + 'get', + 'user:*->bestguesstime', + 'limit', + offset, + '30' ]; return params; }; @@ -129,7 +121,7 @@ exports.sortParams = function(offset) { */ exports.unban = function(ip, spark, callback) { - var issuedby = spark.nickname; + const issuedby = spark.nickname; db.hget(['user:' + issuedby, 'role'], function(err, role) { if (err) { @@ -161,7 +153,7 @@ exports.unban = function(ip, spark, callback) { } replies.forEach(function(key) { - var bannedip = key.slice(4); + const bannedip = key.slice(4); db.get([key], function(err, reply) { if (err) { return console.error(err.message); diff --git a/public/js/app.js b/public/js/app.js index 7d23a4a..99f0ae0 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -1,108 +1,108 @@ (function() { 'use strict'; - var $cassettewheels = $('#cassette .wheel') - , $chat = $('#chat') - , $chatwrapper = $('#chat-outer-wrapper') - , $countdown = $('#countdown') - , $feedback = $('#feedback') - , $guessbox = $('#guess') - , $messagebox = $('#message') - , $modal = $('#modal') - , $points = $('#summary .points') - , $progress = $('#progress') - , $rank = $('#summary .rank') - , $recipient = $('#recipient') - , $tapeleft = $('#tape-left') - , $taperight = $('#tape-right') - , $togglechat = $('#toggle-chat') - , $touchplay - , $track = $('#summary .track') - , $tracks = $('#tracks') - , $users = $('#users') - , audio - , elapsedtime = 0 - , historycursor = 0 - , historyvalues = [] - , ignoredplayers = {} - , isplaying - , nickname - , primus - , pvtmsgto - , replyto - , roomname = location.pathname.replace(/\//g, '') - , roundpoints = 0 - , subscriber = false - , timer - , urlregex = /(https?:\/\/[\-A-Za-z0-9+&@#\/%?=~_()|!:,.;]*[\-A-Za-z0-9+&@#\/%=~_()|])/ - , users = [] - , userscounters = {}; + var $cassettewheels = $('#cassette .wheel'); + var $chat = $('#chat'); + var $chatwrapper = $('#chat-outer-wrapper'); + var $countdown = $('#countdown'); + var $feedback = $('#feedback'); + var $guessbox = $('#guess'); + var $messagebox = $('#message'); + var $modal = $('#modal'); + var $points = $('#summary .points'); + var $progress = $('#progress'); + var $rank = $('#summary .rank'); + var $recipient = $('#recipient'); + var $tapeleft = $('#tape-left'); + var $taperight = $('#tape-right'); + var $togglechat = $('#toggle-chat'); + var $touchplay; + var $track = $('#summary .track'); + var $tracks = $('#tracks'); + var $users = $('#users'); + var audio; + var elapsedtime = 0; + var historycursor = 0; + var historyvalues = []; + var ignoredplayers = {}; + var isplaying; + var nickname; + var primus; + var pvtmsgto; + var replyto; + var roomname = location.pathname.replace(/\//g, ''); + var roundpoints = 0; + var subscriber = false; + var timer; + var urlregex = /(https?:\/\/[-A-Za-z0-9+&@#/%?=~_()|!:,.;]*[-A-Za-z0-9+&@#/%=~_()|])/; + var users = []; + var userscounters = {}; var amstrings = [ - 'Do you also know the title?' - , 'Exactly, now tell me the title!' - , 'Yes, that\'s the artist. What about the title?' + 'Do you also know the title?', + 'Exactly, now tell me the title!', + "Yes, that's the artist. What about the title?" ]; var bmstrings = [ - 'Congratulations' - , 'Exactly' - , 'Excellent' - , 'Good job!' - , 'Great!' - , 'I\'m proud of you' - , 'Keep it up!' - , 'Perfect' - , 'Super duper' - , 'That\'s it!' - , 'Very well done' - , 'Woohoo!' - , 'Yeah true, do you like this track?' - , 'Yes, you\'re right' - , 'You make it look easy' - , 'You remembered' - , 'You rock!' + 'Congratulations', + 'Exactly', + 'Excellent', + 'Good job!', + 'Great!', + "I'm proud of you", + 'Keep it up!', + 'Perfect', + 'Super duper', + "That's it!", + 'Very well done', + 'Woohoo!', + 'Yeah true, do you like this track?', + "Yes, you're right", + 'You make it look easy', + 'You remembered', + 'You rock!' ]; var nmstrings = [ - 'Are you kidding?' - , 'Don\'t give up' - , 'Fail' - , 'Haha, what?!' - , 'Incorrect answer' - , 'It is not that hard' - , 'Keep trying' - , 'No way!' - , 'No' - , 'Nope' - , 'Nope, sorry!' - , 'Oh, come on!' - , 'That\'s wrong' - , 'Try again' - , 'What?!' - , 'Wrong' + 'Are you kidding?', + "Don't give up", + 'Fail', + 'Haha, what?!', + 'Incorrect answer', + 'It is not that hard', + 'Keep trying', + 'No way!', + 'No', + 'Nope', + 'Nope, sorry!', + 'Oh, come on!', + "That's wrong", + 'Try again', + 'What?!', + 'Wrong' ]; var states = [ - 'A song is already playing, please wait for the next one...' - , 'Game is about to start...' - , 'Game is over' - , 'New game will start soon...' + 'A song is already playing, please wait for the next one...', + 'Game is about to start...', + 'Game is over', + 'New game will start soon...' ]; var tmstrings = [ - 'Correct, do you also know the artist?' - , 'Now tell me the artist!' - , 'Yes, you guessed the title. Who is the artist?' + 'Correct, do you also know the artist?', + 'Now tell me the artist!', + 'Yes, you guessed the title. Who is the artist?' ]; var addCassetteBackdrop = function() { var html = [ - '
' - , '' - , '
' + '
', + '', + '
' ].join(''); var $touchbackdrop = $(html); @@ -157,7 +157,7 @@ $recipient.text('To ' + usrname + ':'); var width = $recipient.outerWidth(true) + 1; $recipient.hide(); - $messagebox.animate({ 'width': '-=' + width + 'px' }, 'fast', function() { + $messagebox.animate({ width: '-=' + width + 'px' }, 'fast', function() { $recipient.show(); }); @@ -179,10 +179,10 @@ clearInterval(timer); cassetteAnimation(Date.now() + 5000, false); - var artistName = data.artistName.replace(/"/g, '"') - , trackName = data.trackName.replace(/"/g, '"') - , attrs = '' - , rp = ''; + var artistName = data.artistName.replace(/"/g, '"'); + var trackName = data.trackName.replace(/"/g, '"'); + var attrs = ''; + var rp = ''; if (roundpoints > 0) { rp = '+' + roundpoints; @@ -193,16 +193,18 @@ } var html = [ - '
  • ' - , '' - , '
    ' - , '
    ' + artistName + '
    ' - , '
    ' + trackName + '
    ' - , '
    ' - , '
    ' - , '
    ' + rp + '
    ' - , '' - , '
  • ' + '
  • ', + '', + '
    ', + '
    ' + artistName + '
    ', + '
    ' + trackName + '
    ', + '
    ', + '
    ', + '
    ' + rp + '
    ', + '', + '
  • ' ].join(''); $tracks.prepend(html); @@ -210,65 +212,61 @@ var addVolumeControl = function() { var html = [ - '
    ' - , '' - , '
    ' - , '
    ' - , '
    ' // Outer background - , '
    ' // Rail - , '
    ' // Current volume - , '
    ' // Handle - , '
    ' - , '
    ' + '
    ', + '', + '
    ', + '
    ', + '
    ', // Outer background + '
    ', // Rail + '
    ', // Current volume + '
    ', // Handle + '
    ', + '
    ' ].join(''); - var $volumebutton = $(html) - , $icon = $volumebutton.find('#icon') - , $volumecurrent = $volumebutton.find('#volume-current') - , $volumehandle = $volumebutton.find('#volume-handle') - , $volumeslider = $volumebutton.find('#volume-slider') - , $volumetotal = $volumebutton.find('#volume-total') - , clicked = false - , mouseisdown = false - , mouseisover = false - , oldvalue = 1; + var $volumebutton = $(html); + var $icon = $volumebutton.find('#icon'); + var $volumecurrent = $volumebutton.find('#volume-current'); + var $volumehandle = $volumebutton.find('#volume-handle'); + var $volumeslider = $volumebutton.find('#volume-slider'); + var $volumetotal = $volumebutton.find('#volume-total'); + var clicked = false; + var mouseisdown = false; + var mouseisover = false; + var oldvalue = 1; $volumebutton.appendTo('#volume'); var handleIcon = function(volume) { if (volume === 0) { $icon.removeClass().addClass('icons volume-none'); - } - else if (volume <= 0.33) { + } else if (volume <= 0.33) { $icon.removeClass().addClass('icons volume-low'); - } - else if (volume <= 0.66) { + } else if (volume <= 0.66) { $icon.removeClass().addClass('icons volume-medium'); - } - else { + } else { $icon.removeClass().addClass('icons volume-high'); } }; var handleVolumeMove = function(e) { - var railheight = $volumetotal.height() - , totaloffset = $volumetotal.offset() - , totalTop = parseInt($volumetotal.css('top').replace(/px/, ''), 10) - , newy = e.pageY - totaloffset.top - , volume = (railheight - newy) / railheight; + var railheight = $volumetotal.height(); + var totaloffset = $volumetotal.offset(); + var totalTop = parseInt($volumetotal.css('top').replace(/px/, ''), 10); + var newy = e.pageY - totaloffset.top; + var volume = (railheight - newy) / railheight; clicked = false; if (newy < 0) { newy = 0; - } - else if (newy > railheight) { + } else if (newy > railheight) { newy = railheight; } $volumecurrent.height(railheight - newy); $volumecurrent.css('top', newy + totalTop); - $volumehandle.css('top', totalTop + newy - ($volumehandle.height() / 2)); + $volumehandle.css('top', totalTop + newy - $volumehandle.height() / 2); volume = Math.max(0, volume); volume = Math.min(volume, 1); @@ -283,19 +281,23 @@ return $volumeslider.hide(); } - var totalheight = $volumetotal.height() - , totalposition = $volumetotal.position() - , newtop = totalheight - (totalheight * volume); + var totalheight = $volumetotal.height(); + var totalposition = $volumetotal.position(); + var newtop = totalheight - totalheight * volume; - $volumecurrent.height(totalheight - newtop ); + $volumecurrent.height(totalheight - newtop); $volumecurrent.css('top', totalposition.top + newtop); - $volumehandle.css('top', totalposition.top + newtop - ($volumehandle.height() / 2)); + $volumehandle.css( + 'top', + totalposition.top + newtop - $volumehandle.height() / 2 + ); }; var setCookie = function(volume) { var d = new Date(); d.setTime(d.getTime() + 31536000000); // One year in milliseconds - document.cookie = 'volume=' + volume + ';path=/;expires=' + d.toGMTString() + ';'; + document.cookie = + 'volume=' + volume + ';path=/;expires=' + d.toGMTString() + ';'; }; var setVolume = function(volume) { @@ -326,38 +328,45 @@ } }); - $volumebutton.hover(function() { - mouseisover = true; - $volumeslider.show(); - }, function() { - mouseisover = false; - if (!mouseisdown) { - $volumeslider.hide(); + $volumebutton.hover( + function() { + mouseisover = true; + $volumeslider.show(); + }, + function() { + mouseisover = false; + if (!mouseisdown) { + $volumeslider.hide(); + } } - }); - - $volumeslider.on('mouseover', function() { - mouseisover = true; - }).on('mousedown', function(e) { - handleVolumeMove(e); - mouseisdown = true; - return false; - }); + ); - $(document).on('mouseup', function() { - mouseisdown = false; - if (!mouseisover) { - $volumeslider.hide(); - } - }).on('mousemove', function(e) { - if (mouseisdown) { + $volumeslider + .on('mouseover', function() { + mouseisover = true; + }) + .on('mousedown', function(e) { handleVolumeMove(e); - } - }); + mouseisdown = true; + return false; + }); + + $(document) + .on('mouseup', function() { + mouseisdown = false; + if (!mouseisover) { + $volumeslider.hide(); + } + }) + .on('mousemove', function(e) { + if (mouseisdown) { + handleVolumeMove(e); + } + }); (function() { - if (/volume\s*\=/.test(document.cookie)) { - var value = document.cookie.replace(/.*volume\s*\=\s*([^;]*);?.*/, '$1'); + if (/volume\s*=/.test(document.cookie)) { + var value = document.cookie.replace(/.*volume\s*=\s*([^;]*);?.*/, '$1'); value = parseFloat(value); positionVolumeHandle(value); return setVolume(value); @@ -370,16 +379,16 @@ // Called when a registered user already in a room, tries to enter in another room var alreadyInARoom = function() { var html = [ - '' - , '' + '', + '' ].join(''); $(html).appendTo($modal); @@ -388,14 +397,14 @@ // Start cassette animation var cassetteAnimation = function(endtime, forward) { - var deg - , factor - , millisleft - , offsetleft - , offsetright - , secleft - , step - , width; + var deg; + var factor; + var millisleft; + var offsetleft; + var offsetright; + var secleft; + var step; + var width; (step = function() { millisleft = endtime - Date.now(); @@ -415,8 +424,7 @@ deg = -360 + 360 * factor; offsetleft = 20 + 24 * factor; offsetright = 106 + 24 * factor; - } - else { + } else { $countdown.text(Math.round(secleft)); factor = secleft / 5; width = 148 * factor; @@ -437,8 +445,10 @@ // Prompt for name and send it var chooseNickname = function(msg) { msg = msg - ? '' + msg + '
    Try with another one:' - : 'What\'s your name?'; + ? '' + + msg + + '
    Try with another one:' + : "What's your name?"; if ($modal.hasClass('in')) { $('.modal-body p').html(msg); @@ -446,30 +456,30 @@ } var html = [ - '' - , '' - , '' + '', + '', + '' ].join(''); $(html).appendTo($modal); - var $button = $('#join') - , $login = $('#login'); + var $button = $('#join'); + var $login = $('#login'); $button.on('click', function() { var value = $login.val(); @@ -479,7 +489,7 @@ return primus.send('nickname', value); } - chooseNickname('Nickname can\'t be empty.'); + chooseNickname("Nickname can't be empty."); }); $login.on('keyup', function(event) { @@ -497,7 +507,7 @@ var width = $recipient.outerWidth(true) + 1; $recipient.css('margin-right', '0'); $recipient.text(''); - $messagebox.animate({ 'width': '+=' + width + 'px' }, 'fast'); + $messagebox.animate({ width: '+=' + width + 'px' }, 'fast'); var $el = $('.name').filter(function() { return $(this).text() === pvtmsgto; @@ -513,8 +523,8 @@ // Game over countdown var countDown = function(endtime) { - var millisleft = endtime - Date.now() - , secleft = millisleft / 1000; + var millisleft = endtime - Date.now(); + var secleft = millisleft / 1000; $('.modal-footer span').text(Math.round(secleft)); @@ -537,34 +547,39 @@ }; var encodeEntities = function(str) { - return str.replace(/&/g, '&').replace(//g, '>'); + return str + .replace(/&/g, '&') + .replace(//g, '>'); }; var gameOver = function(podium) { var html = [ - '' - , '