hulawho
Version:
hulawho api
311 lines (250 loc) • 9.24 kB
JavaScript
var async = require('async')
var mongoose = require('mongoose')
var async = require('async')
var LeaderboardModel = require('./models/schema').Leaderboard
var crypto = require('./modules/crypto_primitives')
var Game = require('./Game')
var PredictionAnalysis = require('./PredictionAnalysis')
function Leaderboard() {
}
Leaderboard.prototype.addUser = function(user, callback) {
var self = this
var entry = {user: user}
LeaderboardModel.findOne(entry, function(err, res) {
if(err) {
callback(err)
return
}
if(res) {
callback({status: 400, message: 'USER ALREADY EXISTS ON LEADERBOARD'})
return
}
var leaderboard = new LeaderboardModel(entry)
leaderboard.save(function(err, res) {
if(err) {
callback(err)
return
}
callback(null, {status: 200, message: 'LEADERBOARD ADD USER OK'})
})
})
}
Leaderboard.prototype.updateUser = function(user, data, callback) {
var self = this
data.date_updated = new Date()
LeaderboardModel.findOneAndUpdate({user: user}, data, function(err, res) {
if(err) {
callback(err)
return
}
callback(null, {status: 200, message: 'UPDATE LEADERBOARD USER OK'})
})
}
Leaderboard.prototype.update = function(callback) {
var self = this
var game = new Game()
game.getGames(function(err, res) {
if(err) {
callback(err)
return
}
var games = res.data
var userRecords = []
var async_queue = async.queue(function(task, cb) {
if (task.type == 'add_analysis') {
var analysis = new PredictionAnalysis(task.data)
analysis.addAnalysis(function(err, res) {
if(err) {
cb(err)
return
}
cb(null, res)
})
} else if (task.type == 'update_user') {
self.updateUser(task.user, task.data, function(err, res) {
if(err) {
cb(err)
return
}
cb(null, res)
})
}
}, 20)
for (var i = 0; i < games.length; i++) {
if(!games[i].result) {
continue
}
if(!(games[i].predictions.length > 0)) {
continue
}
for (var j = 0; j < games[i].predictions.length; j++) {
// compute result for the game
var gameResult = {
correct_score: false,
correct_winner: false,
score_distance: null,
points: 0
}
if(games[i].predictions[j].home_score == games[i].result.home_score && games[i].predictions[j].away_score == games[i].result.away_score) {
gameResult.correct_score = true
gameResult.correct_winner = true
gameResult.score_distance = 0
gameResult.points = 3
} else {
if((games[i].predictions[j].home_score - games[i].predictions[j].away_score) == (games[i].result.home_score - games[i].result.away_score) || ((games[i].predictions[j].home_score - games[i].predictions[j].away_score) * (games[i].result.home_score - games[i].result.away_score)) > 0) {
gameResult.correct_winner = true
gameResult.points = 1
}
gameResult.score_distance = Math.sqrt((games[i].predictions[j].home_score - games[i].result.home_score)**2 + (games[i].predictions[j].away_score - games[i].result.away_score)**2)
}
// if user record exists in array, update it, else create new user record
if (!(games[i].predictions[j].user in userRecords)) {
userRecords[games[i].predictions[j].user] = {
total: 1,
correct_score: 0,
correct_winner: 0,
score_distance: gameResult.score_distance,
points: gameResult.points
}
if(gameResult.correct_score == true) {
userRecords[games[i].predictions[j].user].correct_score += 1
}
if(gameResult.correct_winner == true) {
userRecords[games[i].predictions[j].user].correct_winner += 1
}
} else {
userRecords[games[i].predictions[j].user].total += 1
userRecords[games[i].predictions[j].user].score_distance += gameResult.score_distance
userRecords[games[i].predictions[j].user].points += gameResult.points
if(gameResult.correct_score == true) {
userRecords[games[i].predictions[j].user].correct_score += 1
}
if(gameResult.correct_winner == true) {
userRecords[games[i].predictions[j].user].correct_winner += 1
}
}
// save prediction analysis in prediction analysis collection if the prediction has not been analyzed
if(!games[i].predictions[j].analysis) {
var analysis = {
prediction: games[i].predictions[j]._id,
user: games[i].predictions[j].user,
correct_score: gameResult.correct_score,
correct_winner: gameResult.correct_winner,
score_distance: gameResult.score_distance,
points: gameResult.points
}
async_queue.push({
type: 'add_analysis',
data: analysis
}, function(err, res) {
if(err) {
console.log(err)
return
}
console.log(res)
})
}
}
}
// update the leaderboard model
for (var key in userRecords) {
var data = {
total_predictions: userRecords[key].total,
total_correct_scores: userRecords[key].correct_score,
total_correct_winners: userRecords[key].correct_winner,
mean_score_distance: (userRecords[key].score_distance/userRecords[key].total),
points: userRecords[key].points
}
async_queue.push({
type: 'update_user',
user: key,
data: data
}, function(err, res) {
if(err) {
console.log(err)
return
}
console.log(res)
})
}
async_queue.drain = function() {
callback(null, {status: 200, message: 'UPDATE LEADERBOARD OK'})
}
})
}
Leaderboard.prototype.generate = function(query, callback) {
var self = this
if(typeof query === 'function'){
callback = query
query = {}
}
var game = new Game()
game.getGames(query, function(err, res) {
if(err) {
callback(err)
return
}
var games = res.data
var userRecords = []
for (var i = 0; i < games.length; i++) {
if(!games[i].result) {
continue
}
if(!(games[i].predictions.length > 0)) {
continue
}
for (var j = 0; j < games[i].predictions.length; j++) {
// compute result for the game
var gameResult = {
correct_score: false,
correct_winner: false,
score_distance: null,
points: 0
}
if(games[i].predictions[j].home_score == games[i].result.home_score && games[i].predictions[j].away_score == games[i].result.away_score) {
gameResult.correct_score = true
gameResult.correct_winner = true
gameResult.score_distance = 0
gameResult.points = 3
} else {
if((games[i].predictions[j].home_score - games[i].predictions[j].away_score) == (games[i].result.home_score - games[i].result.away_score) || ((games[i].predictions[j].home_score - games[i].predictions[j].away_score) * (games[i].result.home_score - games[i].result.away_score)) > 0) {
gameResult.correct_winner = true
gameResult.points = 1
}
gameResult.score_distance = Math.sqrt((games[i].predictions[j].home_score - games[i].result.home_score)**2 + (games[i].predictions[j].away_score - games[i].result.away_score)**2)
}
// if user record exists in array, update it, else create new user record
if (!(games[i].predictions[j].user in userRecords)) {
userRecords[games[i].predictions[j].user] = {
total: 1,
correct_score: 0,
correct_winner: 0,
score_distance: gameResult.score_distance,
points: gameResult.points
}
if(gameResult.correct_score == true) {
userRecords[games[i].predictions[j].user].correct_score += 1
}
if(gameResult.correct_winner == true) {
userRecords[games[i].predictions[j].user].correct_winner += 1
}
} else {
userRecords[games[i].predictions[j].user].total += 1
userRecords[games[i].predictions[j].user].score_distance += gameResult.score_distance
userRecords[games[i].predictions[j].user].points += gameResult.points
if(gameResult.correct_score == true) {
userRecords[games[i].predictions[j].user].correct_score += 1
}
if(gameResult.correct_winner == true) {
userRecords[games[i].predictions[j].user].correct_winner += 1
}
}
}
}
for (var key in userRecords) {
userRecords[key].mean_score_distance = userRecords[key].score_distance/userRecords[key].total
}
callback(null, {status: 200, message: 'GENERATE LEADERBOARD OK', data: userRecords})
})
}
module.exports = Leaderboard