mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-30 10:56:53 -05:00
Add common user code problems to campaign editor
In level view, showing data from last 30 days, with top 20 issues by count.
This commit is contained in:
parent
0df9de551c
commit
b4a0fe146e
3 changed files with 106 additions and 3 deletions
|
@ -38,9 +38,31 @@
|
||||||
td= levelPlaytimes[i].average.toFixed(2)
|
td= levelPlaytimes[i].average.toFixed(2)
|
||||||
else
|
else
|
||||||
div Loading...
|
div Loading...
|
||||||
|
|
||||||
|
h4 Common Problems
|
||||||
|
if commonProblems
|
||||||
|
if commonProblems.startDay
|
||||||
|
if commonProblems.endDay
|
||||||
|
div(style='font-size:10pt') #{commonProblems.startDay} to #{commonProblems.endDay}
|
||||||
|
else
|
||||||
|
div(style='font-size:10pt') #{commonProblems.startDay} to today
|
||||||
|
table.table.table-bordered.table-condensed.table-hover(style='font-size:10pt')
|
||||||
|
thead
|
||||||
|
tr
|
||||||
|
td Language
|
||||||
|
td Error Message
|
||||||
|
td Error Hint
|
||||||
|
td Count
|
||||||
|
tbody
|
||||||
|
- for (var i = 0; i < commonProblems.length && i < 20; i++)
|
||||||
|
tr
|
||||||
|
td= commonProblems[i].language
|
||||||
|
td= commonProblems[i].message
|
||||||
|
td= commonProblems[i].hint
|
||||||
|
td= commonProblems[i].count
|
||||||
|
else
|
||||||
|
div Loading...
|
||||||
|
|
||||||
if level.get('tasks')
|
if level.get('tasks')
|
||||||
.tasks
|
.tasks
|
||||||
h3 Tasks (read only)
|
h3 Tasks (read only)
|
||||||
|
|
|
@ -15,12 +15,14 @@ module.exports = class CampaignLevelView extends CocoView
|
||||||
@listenToOnce @fullLevel, 'sync', => @render?()
|
@listenToOnce @fullLevel, 'sync', => @render?()
|
||||||
|
|
||||||
@levelSlug = @level.get('slug')
|
@levelSlug = @level.get('slug')
|
||||||
|
@getCommonLevelProblems()
|
||||||
@getLevelCompletions()
|
@getLevelCompletions()
|
||||||
@getLevelPlaytimes()
|
@getLevelPlaytimes()
|
||||||
|
|
||||||
getRenderData: ->
|
getRenderData: ->
|
||||||
c = super()
|
c = super()
|
||||||
c.level = if @fullLevel.loaded then @fullLevel else @level
|
c.level = if @fullLevel.loaded then @fullLevel else @level
|
||||||
|
c.commonProblems = @commonProblems
|
||||||
c.levelCompletions = @levelCompletions
|
c.levelCompletions = @levelCompletions
|
||||||
c.levelPlaytimes = @levelPlaytimes
|
c.levelPlaytimes = @levelPlaytimes
|
||||||
c
|
c
|
||||||
|
@ -29,6 +31,27 @@ module.exports = class CampaignLevelView extends CocoView
|
||||||
@$el.addClass('hidden')
|
@$el.addClass('hidden')
|
||||||
@trigger 'hidden'
|
@trigger 'hidden'
|
||||||
|
|
||||||
|
getCommonLevelProblems: ->
|
||||||
|
# Fetch last 30 days of common level problems
|
||||||
|
startDay = new Date()
|
||||||
|
startDay.setDate(startDay.getUTCDate() - 29)
|
||||||
|
startDay = startDay.getUTCFullYear() + '-' + (startDay.getUTCMonth() + 1) + '-' + startDay.getUTCDate()
|
||||||
|
|
||||||
|
success = (data) =>
|
||||||
|
return if @destroyed
|
||||||
|
@commonProblems = data
|
||||||
|
@commonProblems.startDay = startDay
|
||||||
|
@render()
|
||||||
|
|
||||||
|
# TODO: Why do we need this url dash?
|
||||||
|
request = @supermodel.addRequestResource 'common_problems', {
|
||||||
|
url: '/db/user_code_problem/-/common_problems'
|
||||||
|
data: {startDay: startDay, slug: @levelSlug}
|
||||||
|
method: 'POST'
|
||||||
|
success: success
|
||||||
|
}, 0
|
||||||
|
request.load()
|
||||||
|
|
||||||
getLevelCompletions: ->
|
getLevelCompletions: ->
|
||||||
# Fetch last 7 days of level completion counts
|
# Fetch last 7 days of level completion counts
|
||||||
success = (data) =>
|
success = (data) =>
|
||||||
|
|
|
@ -23,4 +23,62 @@ class UserCodeProblemHandler extends Handler
|
||||||
ucp.set('creator', req.user._id)
|
ucp.set('creator', req.user._id)
|
||||||
ucp
|
ucp
|
||||||
|
|
||||||
|
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]
|
||||||
|
|
||||||
module.exports = new UserCodeProblemHandler()
|
module.exports = new UserCodeProblemHandler()
|
||||||
|
|
Loading…
Reference in a new issue