2014-01-22 17:57:41 -05:00
|
|
|
Level = require('./Level')
|
|
|
|
Session = require('./sessions/LevelSession')
|
2014-03-19 22:42:42 -04:00
|
|
|
User = require '../users/User'
|
2014-01-22 17:57:41 -05:00
|
|
|
SessionHandler = require('./sessions/level_session_handler')
|
|
|
|
Feedback = require('./feedbacks/LevelFeedback')
|
|
|
|
Handler = require('../commons/Handler')
|
2014-01-03 13:32:13 -05:00
|
|
|
mongoose = require('mongoose')
|
|
|
|
|
|
|
|
LevelHandler = class LevelHandler extends Handler
|
|
|
|
modelClass: Level
|
|
|
|
editableProperties: [
|
|
|
|
'description'
|
|
|
|
'documentation'
|
|
|
|
'background'
|
|
|
|
'nextLevel'
|
|
|
|
'scripts'
|
|
|
|
'thangs'
|
|
|
|
'systems'
|
|
|
|
'victory'
|
|
|
|
'name'
|
|
|
|
'i18n'
|
|
|
|
'icon'
|
2014-02-20 14:42:01 -05:00
|
|
|
'goals'
|
2014-03-07 16:14:27 -05:00
|
|
|
'type'
|
|
|
|
'showsGuide'
|
2014-01-03 13:32:13 -05:00
|
|
|
]
|
|
|
|
|
2014-02-14 17:55:30 -05:00
|
|
|
postEditableProperties: ['name']
|
|
|
|
|
2014-01-03 13:32:13 -05:00
|
|
|
getByRelationship: (req, res, args...) ->
|
|
|
|
return @getSession(req, res, args[0]) if args[1] is 'session'
|
2014-02-07 18:51:05 -05:00
|
|
|
return @getLeaderboard(req, res, args[0]) if args[1] is 'leaderboard'
|
2014-03-02 16:24:41 -05:00
|
|
|
return @getMySessions(req, res, args[0]) if args[1] is 'my_sessions'
|
2014-01-03 13:32:13 -05:00
|
|
|
return @getFeedback(req, res, args[0]) if args[1] is 'feedback'
|
2014-03-14 14:30:04 -04:00
|
|
|
return @getRandomSessionPair(req,res,args[0]) if args[1] is 'random_session_pair'
|
2014-03-19 22:42:42 -04:00
|
|
|
return @getLeaderboardFriends(req, res, args[0]) if args[1] is 'leaderboard_friends'
|
2014-03-14 14:30:04 -04:00
|
|
|
|
2014-01-03 13:32:13 -05:00
|
|
|
return @sendNotFoundError(res)
|
|
|
|
|
2014-02-14 17:55:30 -05:00
|
|
|
fetchLevelByIDAndHandleErrors: (id, req, res, callback) ->
|
2014-01-03 13:32:13 -05:00
|
|
|
@getDocumentForIdOrSlug id, (err, level) =>
|
|
|
|
return @sendDatabaseError(res, err) if err
|
|
|
|
return @sendNotFoundError(res) unless level?
|
2014-02-14 17:55:30 -05:00
|
|
|
return @sendUnauthorizedError(res) unless @hasAccessToDocument(req, level, 'get')
|
|
|
|
callback err, level
|
2014-01-03 13:32:13 -05:00
|
|
|
|
2014-02-14 17:55:30 -05:00
|
|
|
getSession: (req, res, id) ->
|
2014-02-24 23:27:38 -05:00
|
|
|
return @sendNotFoundError(res) unless req.user
|
2014-02-14 17:55:30 -05:00
|
|
|
@fetchLevelByIDAndHandleErrors id, req, res, (err, level) =>
|
|
|
|
sessionQuery =
|
|
|
|
level:
|
|
|
|
original: level.original.toString()
|
|
|
|
majorVersion: level.version.major
|
2014-01-03 13:32:13 -05:00
|
|
|
creator: req.user.id
|
2014-02-07 14:50:40 -05:00
|
|
|
|
2014-02-14 17:55:30 -05:00
|
|
|
if req.query.team?
|
|
|
|
sessionQuery.team = req.query.team
|
2014-03-07 18:15:49 -05:00
|
|
|
|
|
|
|
# TODO: generalize this for levels based on their teams
|
|
|
|
else if level.get('type') is 'ladder'
|
2014-02-14 17:55:30 -05:00
|
|
|
sessionQuery.team = 'humans'
|
2014-02-07 14:50:40 -05:00
|
|
|
|
2014-01-03 13:32:13 -05:00
|
|
|
Session.findOne(sessionQuery).exec (err, doc) =>
|
|
|
|
return @sendDatabaseError(res, err) if err
|
2014-02-14 17:55:30 -05:00
|
|
|
return @sendSuccess(res, doc) if doc?
|
|
|
|
@createAndSaveNewSession sessionQuery, req, res
|
2014-01-03 13:32:13 -05:00
|
|
|
|
2014-02-14 17:55:30 -05:00
|
|
|
|
|
|
|
createAndSaveNewSession: (sessionQuery, req, res) =>
|
|
|
|
initVals = sessionQuery
|
|
|
|
|
|
|
|
initVals.state =
|
|
|
|
complete:false
|
|
|
|
scripts:
|
|
|
|
currentScript:null # will not save empty objects
|
|
|
|
|
|
|
|
initVals.permissions = [
|
|
|
|
{
|
|
|
|
target:req.user.id
|
|
|
|
access:'owner'
|
|
|
|
}
|
|
|
|
{
|
|
|
|
target:'public'
|
|
|
|
access:'write'
|
|
|
|
}
|
|
|
|
]
|
|
|
|
session = new Session(initVals)
|
|
|
|
|
|
|
|
session.save (err) =>
|
2014-02-07 14:50:40 -05:00
|
|
|
return @sendDatabaseError(res, err) if err
|
2014-02-14 17:55:30 -05:00
|
|
|
@sendSuccess(res, @formatEntity(req, session))
|
|
|
|
# TODO: tying things like @formatEntity and saveChangesToDocument don't make sense
|
|
|
|
# associated with the handler, because the handler might return a different type
|
|
|
|
# of model, like in this case. Refactor to move that logic to the model instead.
|
2014-02-07 14:50:40 -05:00
|
|
|
|
2014-03-10 13:56:33 -04:00
|
|
|
getMySessions: (req, res, slugOrID) ->
|
|
|
|
findParameters = {}
|
|
|
|
if Handler.isID slugOrID
|
|
|
|
findParameters["_id"] = slugOrID
|
|
|
|
else
|
|
|
|
findParameters["slug"] = slugOrID
|
|
|
|
selectString = 'original version.major permissions'
|
|
|
|
query = Level.findOne(findParameters)
|
|
|
|
.select(selectString)
|
|
|
|
.lean()
|
|
|
|
|
|
|
|
query.exec (err, level) =>
|
|
|
|
return @sendDatabaseError(res, err) if err
|
|
|
|
return @sendNotFoundError(res) unless level?
|
2014-02-14 17:55:30 -05:00
|
|
|
sessionQuery =
|
|
|
|
level:
|
|
|
|
original: level.original.toString()
|
|
|
|
majorVersion: level.version.major
|
2014-03-02 16:24:41 -05:00
|
|
|
creator: req.user._id+''
|
2014-03-10 13:56:33 -04:00
|
|
|
|
|
|
|
query = Session.find(sessionQuery).select('-screenshot')
|
2014-02-14 17:55:30 -05:00
|
|
|
query.exec (err, results) =>
|
|
|
|
if err then @sendDatabaseError(res, err) else @sendSuccess res, results
|
2014-02-13 18:14:08 -05:00
|
|
|
|
2014-02-14 17:55:30 -05:00
|
|
|
getLeaderboard: (req, res, id) ->
|
|
|
|
@validateLeaderboardRequestParameters req
|
|
|
|
[original, version] = id.split '.'
|
|
|
|
version = parseInt(version) ? 0
|
|
|
|
scoreQuery = {}
|
|
|
|
scoreQuery[if req.query.order is 1 then "$gte" else "$lte"] = req.query.scoreOffset
|
|
|
|
|
|
|
|
sessionsQueryParameters =
|
|
|
|
level:
|
|
|
|
original: original
|
|
|
|
majorVersion: version
|
2014-02-13 18:14:08 -05:00
|
|
|
team: req.query.team
|
|
|
|
totalScore: scoreQuery
|
|
|
|
submitted: true
|
|
|
|
|
2014-02-14 17:55:30 -05:00
|
|
|
sortParameters =
|
|
|
|
"totalScore": req.query.order
|
2014-02-07 14:50:40 -05:00
|
|
|
|
2014-02-14 17:55:30 -05:00
|
|
|
selectProperties = [
|
|
|
|
'totalScore'
|
|
|
|
'creatorName'
|
|
|
|
'creator'
|
|
|
|
]
|
2014-03-14 14:57:17 -04:00
|
|
|
|
2014-02-14 17:55:30 -05:00
|
|
|
query = Session
|
|
|
|
.find(sessionsQueryParameters)
|
|
|
|
.limit(req.query.limit)
|
2014-03-14 14:57:17 -04:00
|
|
|
.sort(sortParameters)
|
2014-02-14 17:55:30 -05:00
|
|
|
.select(selectProperties.join ' ')
|
|
|
|
|
|
|
|
query.exec (err, resultSessions) =>
|
2014-01-03 13:32:13 -05:00
|
|
|
return @sendDatabaseError(res, err) if err
|
2014-02-14 17:55:30 -05:00
|
|
|
resultSessions ?= []
|
|
|
|
@sendSuccess res, resultSessions
|
2014-03-19 22:42:42 -04:00
|
|
|
|
|
|
|
|
|
|
|
getLeaderboardFriends: (req, res, id) ->
|
|
|
|
friendIDs = req.body.friendIDs or []
|
|
|
|
return res.send([]) unless friendIDs.length
|
|
|
|
|
|
|
|
query = User.find({facebookID:{$in:friendIDs}})
|
|
|
|
.select('facebookID name')
|
|
|
|
.lean()
|
|
|
|
|
|
|
|
query.exec (err, userResults) ->
|
|
|
|
return res.send([]) unless userResults.length
|
|
|
|
[id, version] = id.split('.')
|
|
|
|
userIDs = (r._id+'' for r in userResults)
|
|
|
|
q = {'level.original':id, 'level.majorVersion': parseInt(version), creator: {$in:userIDs}, totalScore:{$exists:true}}
|
|
|
|
query = Session.find(q)
|
|
|
|
.select('creator creatorName totalScore team')
|
|
|
|
.lean()
|
|
|
|
|
|
|
|
query.exec (err, sessionResults) ->
|
|
|
|
return res.send([]) unless sessionResults.length
|
|
|
|
res.send(sessionResults)
|
|
|
|
userMap = {}
|
|
|
|
userMap[u._id] = u.facebookID for u in userResults
|
|
|
|
session.facebookID = userMap[session.creator] for session in sessionResults
|
|
|
|
res.send(sessionResults)
|
|
|
|
|
2014-03-14 15:54:52 -04:00
|
|
|
getRandomSessionPair: (req, res, slugOrID) ->
|
2014-03-14 14:30:04 -04:00
|
|
|
findParameters = {}
|
2014-03-14 15:54:52 -04:00
|
|
|
if Handler.isID slugOrID
|
|
|
|
findParameters["_id"] = slugOrID
|
|
|
|
else
|
|
|
|
findParameters["slug"] = slugOrID
|
|
|
|
selectString = 'original version'
|
|
|
|
query = Level.findOne(findParameters)
|
|
|
|
.select(selectString)
|
|
|
|
.lean()
|
2014-03-14 14:30:04 -04:00
|
|
|
|
2014-03-14 15:54:52 -04:00
|
|
|
query.exec (err, level) =>
|
|
|
|
return @sendDatabaseError(res, err) if err
|
|
|
|
return @sendNotFoundError(res) unless level?
|
|
|
|
|
|
|
|
sessionsQueryParameters =
|
|
|
|
level:
|
|
|
|
original: level.original.toString()
|
|
|
|
majorVersion: level.version.major
|
|
|
|
submitted:true
|
|
|
|
|
|
|
|
console.log sessionsQueryParameters
|
|
|
|
|
2014-03-14 14:30:04 -04:00
|
|
|
|
2014-03-14 15:54:52 -04:00
|
|
|
query = Session
|
|
|
|
.find(sessionsQueryParameters)
|
|
|
|
.select('team')
|
|
|
|
.lean()
|
2014-03-14 14:30:04 -04:00
|
|
|
|
2014-03-14 15:54:52 -04:00
|
|
|
query.exec (err, resultSessions) =>
|
|
|
|
return @sendDatabaseError res, err if err? or not resultSessions
|
|
|
|
|
|
|
|
teamSessions = _.groupBy resultSessions, 'team'
|
|
|
|
console.log teamSessions
|
|
|
|
sessions = []
|
|
|
|
numberOfTeams = 0
|
|
|
|
for team of teamSessions
|
|
|
|
numberOfTeams += 1
|
|
|
|
sessions.push _.sample(teamSessions[team])
|
|
|
|
if numberOfTeams != 2 then return @sendDatabaseError res, "There aren't sessions of 2 teams, so cannot choose random opponents!"
|
|
|
|
|
|
|
|
@sendSuccess res, sessions
|
|
|
|
|
2014-03-14 14:30:04 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
2014-02-14 17:55:30 -05:00
|
|
|
|
|
|
|
validateLeaderboardRequestParameters: (req) ->
|
|
|
|
req.query.order = parseInt(req.query.order) ? -1
|
|
|
|
req.query.scoreOffset = parseFloat(req.query.scoreOffset) ? 100000
|
|
|
|
req.query.team ?= 'humans'
|
|
|
|
req.query.limit = parseInt(req.query.limit) ? 20
|
2014-01-03 13:32:13 -05:00
|
|
|
|
2014-02-14 17:55:30 -05:00
|
|
|
getFeedback: (req, res, id) ->
|
2014-02-24 23:27:38 -05:00
|
|
|
return @sendNotFoundError(res) unless req.user
|
2014-02-14 17:55:30 -05:00
|
|
|
@fetchLevelByIDAndHandleErrors id, req, res, (err, level) =>
|
|
|
|
feedbackQuery =
|
2014-01-03 13:32:13 -05:00
|
|
|
creator: mongoose.Types.ObjectId(req.user.id.toString())
|
|
|
|
'level.original': level.original.toString()
|
|
|
|
'level.majorVersion': level.version.major
|
|
|
|
|
|
|
|
Feedback.findOne(feedbackQuery).exec (err, doc) =>
|
|
|
|
return @sendDatabaseError(res, err) if err
|
|
|
|
return @sendNotFoundError(res) unless doc?
|
2014-01-14 17:13:47 -05:00
|
|
|
@sendSuccess(res, doc)
|
2014-01-03 13:32:13 -05:00
|
|
|
|
|
|
|
module.exports = new LevelHandler()
|