2014-08-14 11:55:43 -07:00
UserCodeProblem = require ' ./UserCodeProblem '
Handler = require ' ../commons/Handler '
class UserCodeProblemHandler extends Handler
modelClass: UserCodeProblem
jsonSchema: require ' ../../app/schemas/models/user_code_problem '
editableProperties: [
' code '
' codeSnippet '
' errHint '
' errId '
' errLevel '
' errMessage '
2014-10-24 14:05:51 -07:00
' errMessageNoLineInfo '
2014-08-14 11:55:43 -07:00
' errRange '
' errType '
' language '
' levelID '
]
makeNewInstance: (req) ->
ucp = super ( req )
ucp . set ( ' creator ' , req . user . _id )
ucp
2015-01-05 13:42:14 -08:00
getByRelationship: (req, res, args...) ->
return @ getCommonLevelProblemsBySlug ( req , res ) if args [ 1 ] is ' common_problems '
super ( arguments . . . )
getCommonLevelProblemsBySlug: (req, res) ->
# Returns an ordered array of common user code problems with: language, message, hint, count
# Parameters:
# slug - level slug
# startDay - Inclusive, optional, e.g. '2014-12-14'
# endDay - Exclusive, optional, e.g. '2014-12-16'
levelSlug = req . query . slug or req . body . slug
startDay = req . query . startDay or req . body . startDay
endDay = req . query . endDay or req . body . endDay
return @ sendSuccess res , [ ] unless levelSlug ?
# Cache results for 1 day
@ commonLevelProblemsCache ? = { }
@ commonLevelProblemsCachedSince ? = new Date ( )
if ( new Date ( ) ) - @ commonLevelProblemsCachedSince > 86400 * 1000 # Dumb cache expiration
@commonLevelProblemsCache = { }
@commonLevelProblemsCachedSince = new Date ( )
cacheKey = levelSlug
cacheKey += ' s ' + startDay if startDay ?
cacheKey += ' e ' + endDay if endDay ?
return @ sendSuccess res , commonProblems if commonProblems = @ commonLevelProblemsCache [ cacheKey ]
# Build query
match = if startDay ? or endDay ? then { $match: { $and: [ ] } } else { $match: { } }
match [ " $match " ] [ " $and " ] . push created: { $gte: new Date ( startDay + " T00:00:00.000Z " ) } if startDay ?
match [ " $match " ] [ " $and " ] . push created: { $lt: new Date ( endDay + " T00:00:00.000Z " ) } if endDay ?
group = { " $group " : { " _id " : { " errMessage " : " $errMessageNoLineInfo " , " errHint " : " $errHint " , " language " : " $language " , " levelID " : " $levelID " } , " count " : { " $sum " : 1 } } }
sort = { $sort : { " _id.levelID " : 1 , count : - 1 , " _id.language " : 1 } }
query = UserCodeProblem . aggregate match , group , sort
query . exec (err, data) =>
if err ? then return @ sendDatabaseError res , err
# Build per-level common problem lists
commonProblems = { }
for item in data
levelID = item . _id . levelID
commonProblems [ levelID ] ? = [ ]
commonProblems [ levelID ] . push
language: item . _id . language
message: item . _id . errMessage
hint: item . _id . errHint
count: item . count
# Cache all the levels
for levelID of commonProblems
cacheKey = levelID
cacheKey += ' s ' + startDay if startDay ?
cacheKey += ' e ' + endDay if endDay ?
@ commonLevelProblemsCache [ cacheKey ] = commonProblems [ levelID ]
@ sendSuccess res , commonProblems [ levelSlug ]
2014-08-14 11:55:43 -07:00
module.exports = new UserCodeProblemHandler ( )