2014-01-22 23:57:41 +01:00
Level = require ( ' ./Level ' )
Session = require ( ' ./sessions/LevelSession ' )
2014-03-19 19:42:42 -07:00
User = require ' ../users/User '
2014-01-22 23:57:41 +01:00
SessionHandler = require ( ' ./sessions/level_session_handler ' )
Feedback = require ( ' ./feedbacks/LevelFeedback ' )
Handler = require ( ' ../commons/Handler ' )
2014-01-03 10:32:13 -08: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 11:42:01 -08:00
' goals '
2014-03-07 13:14:27 -08:00
' type '
' showsGuide '
2014-01-03 10:32:13 -08:00
]
2014-02-14 14:55:30 -08:00
postEditableProperties: [ ' name ' ]
2014-01-03 10:32:13 -08:00
getByRelationship: (req, res, args...) ->
return @ getSession ( req , res , args [ 0 ] ) if args [ 1 ] is ' session '
2014-02-07 15:51:05 -08:00
return @ getLeaderboard ( req , res , args [ 0 ] ) if args [ 1 ] is ' leaderboard '
2014-03-20 14:40:17 -07:00
return @ getMyLeaderboardRank ( req , res , args [ 0 ] ) if args [ 1 ] is ' leaderboard_rank '
2014-03-02 13:24:41 -08:00
return @ getMySessions ( req , res , args [ 0 ] ) if args [ 1 ] is ' my_sessions '
2014-01-03 10:32:13 -08:00
return @ getFeedback ( req , res , args [ 0 ] ) if args [ 1 ] is ' feedback '
2014-03-14 11:30:04 -07:00
return @ getRandomSessionPair ( req , res , args [ 0 ] ) if args [ 1 ] is ' random_session_pair '
2014-03-23 09:30:01 -07:00
return @ getLeaderboardFacebookFriends ( req , res , args [ 0 ] ) if args [ 1 ] is ' leaderboard_facebook_friends '
return @ getLeaderboardGPlusFriends ( req , res , args [ 0 ] ) if args [ 1 ] is ' leaderboard_gplus_friends '
2014-04-04 13:38:36 -07:00
return @ getHistogramData ( req , res , args [ 0 ] ) if args [ 1 ] is ' histogram_data '
2014-03-14 11:30:04 -07:00
2014-01-03 10:32:13 -08:00
return @ sendNotFoundError ( res )
2014-02-14 14:55:30 -08:00
fetchLevelByIDAndHandleErrors: (id, req, res, callback) ->
2014-01-03 10:32:13 -08:00
@ getDocumentForIdOrSlug id , (err, level) =>
return @ sendDatabaseError ( res , err ) if err
return @ sendNotFoundError ( res ) unless level ?
2014-02-14 14:55:30 -08:00
return @ sendUnauthorizedError ( res ) unless @ hasAccessToDocument ( req , level , ' get ' )
callback err , level
2014-01-03 10:32:13 -08:00
2014-02-14 14:55:30 -08:00
getSession: (req, res, id) ->
2014-02-24 20:27:38 -08:00
return @ sendNotFoundError ( res ) unless req . user
2014-02-14 14:55:30 -08:00
@ fetchLevelByIDAndHandleErrors id , req , res , (err, level) =>
sessionQuery =
level:
original: level . original . toString ( )
majorVersion: level . version . major
2014-01-03 10:32:13 -08:00
creator: req . user . id
2014-02-07 11:50:40 -08:00
2014-02-14 14:55:30 -08:00
if req . query . team ?
sessionQuery.team = req . query . team
2014-03-07 15:15:49 -08:00
# TODO: generalize this for levels based on their teams
else if level . get ( ' type ' ) is ' ladder '
2014-02-14 14:55:30 -08:00
sessionQuery.team = ' humans '
2014-02-07 11:50:40 -08:00
2014-01-03 10:32:13 -08:00
Session . findOne ( sessionQuery ) . exec (err, doc) =>
return @ sendDatabaseError ( res , err ) if err
2014-02-14 14:55:30 -08:00
return @ sendSuccess ( res , doc ) if doc ?
@ createAndSaveNewSession sessionQuery , req , res
2014-01-03 10:32:13 -08:00
2014-02-14 14:55:30 -08: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 11:50:40 -08:00
return @ sendDatabaseError ( res , err ) if err
2014-02-14 14:55:30 -08: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 11:50:40 -08:00
2014-03-10 10:56:33 -07: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 14:55:30 -08:00
sessionQuery =
level:
original: level . original . toString ( )
majorVersion: level . version . major
2014-03-02 13:24:41 -08:00
creator: req . user . _id + ' '
2014-03-10 10:56:33 -07:00
query = Session . find ( sessionQuery ) . select ( ' -screenshot ' )
2014-02-14 14:55:30 -08:00
query . exec (err, results) =>
if err then @ sendDatabaseError ( res , err ) else @ sendSuccess res , results
2014-04-04 13:38:36 -07:00
getHistogramData: (req, res,slug) ->
query = Session . aggregate [
{ $match: { " levelID " : slug , " submitted " : true , " team " : req . query . team } }
{ $project: { totalScore: 1 , _id: 0 } }
]
query . exec (err, data) =>
if err ? then return @ sendDatabaseError res , err
valueArray = _ . pluck data , " totalScore "
@ sendSuccess res , valueArray
2014-02-13 15:14:08 -08:00
2014-02-14 14:55:30 -08:00
getLeaderboard: (req, res, id) ->
2014-03-20 14:40:17 -07:00
sessionsQueryParameters = @ makeLeaderboardQueryParameters ( req , id )
2014-02-13 15:14:08 -08:00
2014-02-14 14:55:30 -08:00
sortParameters =
" totalScore " : req . query . order
2014-03-20 14:40:17 -07:00
selectProperties = [ ' totalScore ' , ' creatorName ' , ' creator ' ]
2014-03-14 11:57:17 -07:00
2014-02-14 14:55:30 -08:00
query = Session
. find ( sessionsQueryParameters )
. limit ( req . query . limit )
2014-03-14 11:57:17 -07:00
. sort ( sortParameters )
2014-02-14 14:55:30 -08:00
. select ( selectProperties . join ' ' )
query . exec (err, resultSessions) =>
2014-01-03 10:32:13 -08:00
return @ sendDatabaseError ( res , err ) if err
2014-02-14 14:55:30 -08:00
resultSessions ? = [ ]
@ sendSuccess res , resultSessions
2014-03-19 19:42:42 -07:00
2014-03-20 14:40:17 -07:00
getMyLeaderboardRank: (req, res, id) ->
req.query.order = 1
sessionsQueryParameters = @ makeLeaderboardQueryParameters ( req , id )
Session . count sessionsQueryParameters , (err, count) =>
return @ sendDatabaseError ( res , err ) if err
res . send JSON . stringify ( count + 1 )
makeLeaderboardQueryParameters: (req, id) ->
@ validateLeaderboardRequestParameters req
[ original , version ] = id . split ' . '
version = parseInt ( version ) ? 0
scoreQuery = { }
scoreQuery [ if req . query . order is 1 then " $gt " else " $lt " ] = req . query . scoreOffset
query =
level:
original: original
majorVersion: version
team: req . query . team
totalScore: scoreQuery
submitted: true
query
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-03-19 19:42:42 -07:00
2014-03-23 09:30:01 -07:00
getLeaderboardFacebookFriends: (req, res, id) -> @ getLeaderboardFriends ( req , res , id , ' facebookID ' )
getLeaderboardGPlusFriends: (req, res, id) -> @ getLeaderboardFriends ( req , res , id , ' gplusID ' )
getLeaderboardFriends: (req, res, id, serviceProperty) ->
2014-03-19 19:42:42 -07:00
friendIDs = req . body . friendIDs or [ ]
return res . send ( [ ] ) unless friendIDs . length
2014-03-23 09:30:01 -07:00
q = { }
q [ serviceProperty ] = { $in : friendIDs }
query = User . find ( q ) . select ( " #{ serviceProperty } name " ) . lean ( )
2014-03-19 19:42:42 -07:00
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 )
2014-03-23 09:30:01 -07:00
. select ( ' creator creatorName totalScore team ' )
. lean ( )
2014-03-19 19:42:42 -07:00
query . exec (err, sessionResults) ->
return res . send ( [ ] ) unless sessionResults . length
userMap = { }
2014-03-23 09:30:01 -07:00
userMap [ u . _id ] = u [ serviceProperty ] for u in userResults
session [ serviceProperty ] = userMap [ session . creator ] for session in sessionResults
2014-03-19 19:42:42 -07:00
res . send ( sessionResults )
2014-03-23 09:30:01 -07:00
2014-03-14 12:54:52 -07:00
getRandomSessionPair: (req, res, slugOrID) ->
2014-03-14 11:30:04 -07:00
findParameters = { }
2014-03-14 12:54:52 -07: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 11:30:04 -07:00
2014-03-14 12:54:52 -07: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 11:30:04 -07:00
2014-03-14 12:54:52 -07:00
query = Session
. find ( sessionsQueryParameters )
. select ( ' team ' )
. lean ( )
2014-03-14 11:30:04 -07:00
2014-03-14 12:54:52 -07: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 11:30:04 -07:00
2014-02-14 14:55:30 -08:00
getFeedback: (req, res, id) ->
2014-02-24 20:27:38 -08:00
return @ sendNotFoundError ( res ) unless req . user
2014-02-14 14:55:30 -08:00
@ fetchLevelByIDAndHandleErrors id , req , res , (err, level) =>
feedbackQuery =
2014-01-03 10:32:13 -08: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 23:13:47 +01:00
@ sendSuccess ( res , doc )
2014-01-03 10:32:13 -08:00
module.exports = new LevelHandler ( )