mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-28 18:15:52 -05:00
Merge branch 'master' into production
This commit is contained in:
commit
e2e7b876a4
14 changed files with 46 additions and 35 deletions
|
@ -10,7 +10,7 @@ module.exports = class Simulator
|
|||
@trigger 'statusUpdate', 'Starting simulation!'
|
||||
@retryDelayInSeconds = 10
|
||||
@taskURL = '/queue/scoring'
|
||||
|
||||
|
||||
destroy: ->
|
||||
@off()
|
||||
@cleanupSimulation()
|
||||
|
@ -25,17 +25,21 @@ module.exports = class Simulator
|
|||
success: @setupSimulationAndLoadLevel
|
||||
|
||||
handleFetchTaskError: (errorData) =>
|
||||
console.log "There were no games to score. Error: #{JSON.stringify errorData}"
|
||||
console.log "Retrying in #{@retryDelayInSeconds}"
|
||||
@trigger 'statusUpdate', 'There were no games to simulate! Trying again in 10 seconds.'
|
||||
console.error "There was a horrible Error: #{JSON.stringify errorData}"
|
||||
@trigger 'statusUpdate', 'There was an error fetching games to simulate. Retrying in 10 seconds.'
|
||||
@simulateAnotherTaskAfterDelay()
|
||||
|
||||
handleNoGamesResponse: ->
|
||||
@trigger 'statusUpdate', 'There were no games to simulate--nice. Retrying in 10 seconds.'
|
||||
@simulateAnotherTaskAfterDelay()
|
||||
|
||||
simulateAnotherTaskAfterDelay: =>
|
||||
console.log "Retrying in #{@retryDelayInSeconds}"
|
||||
retryDelayInMilliseconds = @retryDelayInSeconds * 1000
|
||||
_.delay @fetchAndSimulateTask, retryDelayInMilliseconds
|
||||
|
||||
setupSimulationAndLoadLevel: (taskData) =>
|
||||
setupSimulationAndLoadLevel: (taskData, textStatus, jqXHR) =>
|
||||
return @handleNoGamesResponse() if jqXHR.status is 204
|
||||
@trigger 'statusUpdate', 'Setting up simulation!'
|
||||
@task = new SimulationTask(taskData)
|
||||
@supermodel = new SuperModel()
|
||||
|
|
|
@ -151,7 +151,7 @@ class CocoModel extends Backbone.Model
|
|||
return null unless schema.links?
|
||||
linkObject = _.find schema.links, rel: "db"
|
||||
return null unless linkObject
|
||||
return null if linkObject.href.match("thang_type") and not @isObjectID(data) # Skip loading hardcoded Thang Types for now (TODO)
|
||||
return null if linkObject.href.match("thang.type") and not @isObjectID(data) # Skip loading hardcoded Thang Types for now (TODO)
|
||||
|
||||
# not fully extensible, but we can worry about that later
|
||||
link = linkObject.href
|
||||
|
|
|
@ -112,7 +112,7 @@ module.exports = class Level extends CocoModel
|
|||
if path.match(/\/systems\/\d+\/config\//) and data?.indieSprites?.length
|
||||
# Ugh, we need to make sure we grab the IndieSprite ThangTypes
|
||||
for indieSprite in data.indieSprites
|
||||
link = "/db/thang_type/#{indieSprite.thangType}/version"
|
||||
link = "/db/thang.type/#{indieSprite.thangType}/version"
|
||||
model = CocoModel.getOrMakeModelFromLink link, shouldLoadProjection
|
||||
models.push model if model
|
||||
else if path is '/'
|
||||
|
|
|
@ -218,8 +218,8 @@ module.exports = class ThangType extends CocoModel
|
|||
@loadUniversalWizard: ->
|
||||
return @wizardType if @wizardType
|
||||
wizOriginal = "52a00d55cf1818f2be00000b"
|
||||
url = "/db/thang_type/#{wizOriginal}/version"
|
||||
url = "/db/thang.type/#{wizOriginal}/version"
|
||||
@wizardType = new module.exports()
|
||||
@wizardType.url = -> url
|
||||
@wizardType.fetch()
|
||||
@wizardType
|
||||
@wizardType
|
||||
|
|
|
@ -22,7 +22,7 @@ module.exports = class WizardSettingsView extends CocoView
|
|||
|
||||
loadWizard: ->
|
||||
@wizardThangType = new ThangType()
|
||||
@wizardThangType.url = -> '/db/thang_type/wizard'
|
||||
@wizardThangType.url = -> '/db/thang.type/wizard'
|
||||
@wizardThangType.fetch()
|
||||
@wizardThangType.once 'sync', @initCanvas, @
|
||||
|
||||
|
@ -67,7 +67,7 @@ module.exports = class WizardSettingsView extends CocoView
|
|||
updateSwatchVisibility: (colorGroup) ->
|
||||
enabled = colorGroup.find('.color-group-checkbox').prop('checked')
|
||||
colorGroup.find('.minicolors-swatch').toggle Boolean(enabled)
|
||||
|
||||
|
||||
updateColorSettings: (colorGroup) =>
|
||||
wizardSettings = _.cloneDeep(me.get('wizard')) or {}
|
||||
wizardSettings.colorConfig ?= {}
|
||||
|
@ -108,4 +108,4 @@ module.exports = class WizardSettingsView extends CocoView
|
|||
@movieClip.regX = reg.x
|
||||
@movieClip.regY = reg.y
|
||||
@stage.addChild @movieClip
|
||||
@stage.update()
|
||||
@stage.update()
|
||||
|
|
|
@ -19,7 +19,7 @@ componentOriginals =
|
|||
"physics.Physical" : "524b75ad7fc0f6d519000001"
|
||||
|
||||
class ThangTypeSearchCollection extends CocoCollection
|
||||
url: '/db/thang_type/search?project=true'
|
||||
url: '/db/thang.type/search?project=true'
|
||||
model: ThangType
|
||||
|
||||
module.exports = class ThangsTabView extends View
|
||||
|
|
|
@ -122,6 +122,7 @@ module.exports = class MyMatchesTabView extends CocoView
|
|||
failure = => @setRankingButtonText(button, 'failed')
|
||||
|
||||
ajaxData = { session: sessionID, levelID: @level.id, originalLevelID: @level.attributes.original, levelMajorVersion: @level.attributes.version.major }
|
||||
console.log "Posting game for ranking from My Matches view."
|
||||
$.ajax '/queue/scoring', {
|
||||
type: 'POST'
|
||||
data: ajaxData
|
||||
|
|
|
@ -66,6 +66,7 @@ module.exports = class VictoryModal extends View
|
|||
ajaxData = session: @session.id, levelID: @level.id, originalLevelID: @level.get('original'), levelMajorVersion: @level.get('version').major
|
||||
ladderURL = "/play/ladder/#{@level.get('slug')}#my-matches"
|
||||
goToLadder = -> Backbone.Mediator.publish 'router:navigate', route: ladderURL
|
||||
console.log "Posting game for ranking from victory modal."
|
||||
$.ajax '/queue/scoring',
|
||||
type: 'POST'
|
||||
data: ajaxData
|
||||
|
|
|
@ -174,7 +174,7 @@ LevelThangSchema = c.object {
|
|||
},
|
||||
id: thang # TODO: figure out if we can make this unique and how to set dynamic defaults
|
||||
# TODO: split thangType into "original" and "majorVersion" like the rest for consistency
|
||||
thangType: c.objectId(links: [{rel: "db", href: "/db/thang_type/{($)}/version"}], title: "Thang Type", description: "A reference to the original Thang template being configured.", format: 'thang-type')
|
||||
thangType: c.objectId(links: [{rel: "db", href: "/db/thang.type/{($)}/version"}], title: "Thang Type", description: "A reference to the original Thang template being configured.", format: 'thang-type')
|
||||
components: c.array {title: "Components", description: "Thangs are configured by changing the Components attached to them.", uniqueItems: true, format: 'thang-components-array'}, ThangComponentSchema # TODO: uniqueness should be based on "original", not whole thing
|
||||
|
||||
LevelSystemSchema = c.object {
|
||||
|
@ -252,4 +252,3 @@ module.exports = LevelSchema
|
|||
# 3. tv4.addSchema(metaschema.id, metaschema)
|
||||
# 4. S = <paste big schema here>
|
||||
# 5. tv4.validateMultiple(S, metaschema) and look for errors
|
||||
|
||||
|
|
|
@ -61,4 +61,4 @@ LevelThangTypeSchema.plugin(plugins.PermissionsPlugin)
|
|||
LevelThangTypeSchema.plugin(plugins.NamedPlugin)
|
||||
LevelThangTypeSchema.plugin(plugins.SearchablePlugin, {searchable: ['name', 'description']})
|
||||
|
||||
module.exports = LevelThangType = mongoose.model('level.thang_type', LevelThangTypeSchema)
|
||||
module.exports = LevelThangType = mongoose.model('level.thang.type', LevelThangTypeSchema)
|
||||
|
|
|
@ -84,7 +84,9 @@ module.exports.dispatchTaskToConsumer = (req, res) ->
|
|||
if isUserAnonymous(req) then return errors.forbidden res, "You need to be logged in to simulate games"
|
||||
|
||||
scoringTaskQueue.receiveMessage (err, message) ->
|
||||
if err? or messageIsInvalid(message) then return errors.gatewayTimeoutError res, "Queue Receive Error:#{err}"
|
||||
if err? or messageIsInvalid(message)
|
||||
res.send 204, "No games to score. #{message}"
|
||||
return res.end()
|
||||
console.log "Received Message"
|
||||
messageBody = parseTaskQueueMessage req, res, message
|
||||
return unless messageBody?
|
||||
|
@ -153,13 +155,16 @@ module.exports.processTaskResult = (req, res) ->
|
|||
|
||||
levelOriginalID = levelSession.level.original
|
||||
levelOriginalMajorVersion = levelSession.level.majorVersion
|
||||
findNearestBetterSessionID levelOriginalID, levelOriginalMajorVersion, originalSessionID, sessionNewScore, opponentNewScore, opponentID ,opposingTeam, (err, opponentSessionID) ->
|
||||
findNearestBetterSessionID levelOriginalID, levelOriginalMajorVersion, originalSessionID, sessionNewScore, opponentNewScore, opponentID, opposingTeam, (err, opponentSessionID) ->
|
||||
if err? then return errors.serverError res, "There was an error finding the nearest sessionID!"
|
||||
unless opponentSessionID then return sendResponseObject req, res, {"message":"There were no more games to rank(game is at top!"}
|
||||
|
||||
addPairwiseTaskToQueue [originalSessionID, opponentSessionID], (err, success) ->
|
||||
if err? then return errors.serverError res, "There was an error sending the pairwise tasks to the queue!"
|
||||
sendResponseObject req, res, {"message":"The scores were updated successfully and more games were sent to the queue!"}
|
||||
if opponentSessionID
|
||||
addPairwiseTaskToQueue [originalSessionID, opponentSessionID], (err, success) ->
|
||||
if err? then return errors.serverError res, "There was an error sending the pairwise tasks to the queue!"
|
||||
sendResponseObject req, res, {"message":"The scores were updated successfully and more games were sent to the queue!"}
|
||||
else
|
||||
LevelSession.update {_id: originalSessionID}, {isRanking: false}, {multi: false}, (err, affected) ->
|
||||
if err? then return errors.serverError res, "There was an error marking the victorious session as not being ranked."
|
||||
return sendResponseObject req, res, {"message":"There were no more games to rank (game is at top)!"}
|
||||
else
|
||||
console.log "Player lost, achieved rank #{originalSessionRank}"
|
||||
LevelSession.update {_id: originalSessionID}, {isRanking: false}, {multi: false}, (err, affected) ->
|
||||
|
|
|
@ -102,7 +102,7 @@ sendLadderUpdateEmail = (session, daysAgo) ->
|
|||
score_history_graph_url: getScoreHistoryGraphURL session, daysAgo
|
||||
defeat: defeatContext
|
||||
victory: victoryContext
|
||||
log.info "Sending ladder update email to #{context.recipient.address} with #{context.email_data.wins} wins and #{context.email_data.losses} since #{daysAgo} day(s) ago."
|
||||
log.info "Sending ladder update email to #{context.recipient.address} with #{context.email_data.wins} wins and #{context.email_data.losses} losses since #{daysAgo} day(s) ago."
|
||||
sendwithus.api.send context, (err, result) ->
|
||||
log.error "Error sending ladder update email: #{err} with result #{result}" if err
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ module.exports.setupRoutes = (app) ->
|
|||
return
|
||||
|
||||
|
||||
options = { DEBUG: not config.isProduction }
|
||||
module.exports.api = new sendwithusAPI swuAPIKey, options
|
||||
debug = not config.isProduction
|
||||
module.exports.api = new sendwithusAPI swuAPIKey, debug
|
||||
module.exports.templates =
|
||||
welcome_email: 'utnGaBHuSU4Hmsi7qrAypU'
|
||||
ladder_update_email: 'JzaZxf39A4cKMxpPZUfWy4'
|
||||
|
|
|
@ -3,6 +3,7 @@ jsonschema = require('./user_schema')
|
|||
crypto = require('crypto')
|
||||
{salt, isProduction} = require('../../server_config')
|
||||
mail = require '../commons/mail'
|
||||
log = require 'winston'
|
||||
|
||||
sendwithus = require '../sendwithus'
|
||||
|
||||
|
@ -27,7 +28,7 @@ UserSchema.post('init', ->
|
|||
UserSchema.methods.isAdmin = ->
|
||||
p = @get('permissions')
|
||||
return p and 'admin' in p
|
||||
|
||||
|
||||
UserSchema.statics.updateMailChimp = (doc, callback) ->
|
||||
return callback?() unless isProduction
|
||||
return callback?() if doc.updatedMailChimp
|
||||
|
@ -41,25 +42,25 @@ UserSchema.statics.updateMailChimp = (doc, callback) ->
|
|||
return callback?() # don't add totally unsubscribed people to the list
|
||||
subsChanged = doc.currentSubscriptions isnt JSON.stringify(emailSubs)
|
||||
return callback?() unless emailChanged or subsChanged
|
||||
|
||||
|
||||
params = {}
|
||||
params.id = mail.MAILCHIMP_LIST_ID
|
||||
params.email = if existingProps then {leid:existingProps.leid} else {email:doc.get('email')}
|
||||
params.merge_vars = { groupings: [ {id: mail.MAILCHIMP_GROUP_ID, groups: newGroups} ] }
|
||||
params.update_existing = true
|
||||
params.double_optin = false
|
||||
|
||||
|
||||
onSuccess = (data) ->
|
||||
doc.set('mailChimp', data)
|
||||
doc.updatedMailChimp = true
|
||||
doc.save()
|
||||
callback?()
|
||||
|
||||
|
||||
onFailure = (error) ->
|
||||
console.error 'failed to subscribe', error, callback?
|
||||
log.error 'failed to subscribe', error, callback?
|
||||
doc.updatedMailChimp = true
|
||||
callback?()
|
||||
|
||||
|
||||
mc.lists.subscribe params, onSuccess, onFailure
|
||||
|
||||
|
||||
|
@ -75,9 +76,9 @@ UserSchema.pre('save', (next) ->
|
|||
data =
|
||||
email_id: sendwithus.templates.welcome_email
|
||||
recipient:
|
||||
address: @get 'email'
|
||||
address: @get 'email'
|
||||
sendwithus.api.send data, (err, result) ->
|
||||
console.log 'error', err, 'result', result
|
||||
log.error 'error', err, 'result', result if err
|
||||
next()
|
||||
)
|
||||
|
||||
|
@ -90,4 +91,4 @@ UserSchema.statics.hashPassword = (password) ->
|
|||
shasum.update(salt + password)
|
||||
shasum.digest('hex')
|
||||
|
||||
module.exports = User = mongoose.model('User', UserSchema)
|
||||
module.exports = User = mongoose.model('User', UserSchema)
|
||||
|
|
Loading…
Reference in a new issue