mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-12-13 17:21:19 -05:00
Merge branch 'master' into production
This commit is contained in:
commit
9404dcdb32
6 changed files with 65 additions and 34 deletions
|
@ -28,12 +28,11 @@ module.exports = class LevelBus extends Bus
|
||||||
constructor: ->
|
constructor: ->
|
||||||
super(arguments...)
|
super(arguments...)
|
||||||
@changedSessionProperties = {}
|
@changedSessionProperties = {}
|
||||||
highLoad = false
|
saveDelay = window.serverConfig?.sessionSaveDelay
|
||||||
[wait, maxWait] = switch
|
[wait, maxWait] = switch
|
||||||
when not application.isProduction() then [1, 5] # Save quickly in development.
|
when not application.isProduction or not saveDelay then [1, 5] # Save quickly in development.
|
||||||
when not highLoad then [4, 10] # Save slowly when in production.
|
when me.isAnonymous() then [saveDelay.anonymous.min, saveDelay.anonymous.max]
|
||||||
when not me.isAnonymous() then [10, 30] # Save even more slowly during HoC scaling.
|
else [saveDelay.registered.min, saveDelay.registered.max]
|
||||||
else [20, 60] # Save super slowly if anonymous during HoC scaling.
|
|
||||||
@saveSession = _.debounce @reallySaveSession, wait * 1000, {maxWait: maxWait * 1000}
|
@saveSession = _.debounce @reallySaveSession, wait * 1000, {maxWait: maxWait * 1000}
|
||||||
@playerIsIdle = false
|
@playerIsIdle = false
|
||||||
|
|
||||||
|
|
|
@ -5,14 +5,39 @@ module.exports = MandateSchema = {
|
||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
default:
|
default:
|
||||||
simulationThroughputRatio: 1
|
simulationThroughputRatio: 1
|
||||||
properties: {
|
sessionSaveDelay:
|
||||||
|
registered: {min: 4, max: 10}
|
||||||
|
anonymous: {min: 5, max: 15}
|
||||||
|
#registered: {min: 10, max: 30} # High load, like during HoC scaling
|
||||||
|
#anonymous: {min: 20, max: 60}
|
||||||
|
properties:
|
||||||
simulationThroughputRatio:
|
simulationThroughputRatio:
|
||||||
name: 'Simulation Throughput Ratio'
|
name: 'Simulation Throughput Ratio'
|
||||||
description: '0-1 fraction of requests for a match to simulate that should be granted.'
|
description: '0-1 fraction of requests for a match to simulate that should be granted.'
|
||||||
type: 'number'
|
type: 'number'
|
||||||
minimum: 0
|
minimum: 0
|
||||||
maximum: 1
|
maximum: 1
|
||||||
}
|
sessionSaveDelay:
|
||||||
|
name: 'Session Save Delay'
|
||||||
|
description: 'How often we save level sessions after code changes--min and max wait in seconds.'
|
||||||
|
type: 'object'
|
||||||
|
properties:
|
||||||
|
registered:
|
||||||
|
description: 'How often to save for registered players.'
|
||||||
|
type: 'object'
|
||||||
|
additionalProperties: false
|
||||||
|
requiredProperties: ['min', 'max']
|
||||||
|
properties:
|
||||||
|
min: {type: 'number', minimum: 1, exclusiveMinimum: true, format: 'seconds'}
|
||||||
|
max: {type: 'number', minimum: 5, exclusiveMinimum: true, format: 'seconds'}
|
||||||
|
anonymous:
|
||||||
|
description: 'How often to save for anonymous players.'
|
||||||
|
type: 'object'
|
||||||
|
additionalProperties: false
|
||||||
|
requiredProperties: ['min', 'max']
|
||||||
|
properties:
|
||||||
|
min: {type: 'number', minimum: 1, exclusiveMinimum: true, format: 'seconds'}
|
||||||
|
max: {type: 'number', minimum: 5, exclusiveMinimum: true, format: 'seconds'}
|
||||||
}
|
}
|
||||||
|
|
||||||
c.extendBasicProperties MandateSchema, 'Mandate'
|
c.extendBasicProperties MandateSchema, 'Mandate'
|
||||||
|
|
|
@ -5,11 +5,14 @@
|
||||||
margin-top: 20px
|
margin-top: 20px
|
||||||
|
|
||||||
.login-btn
|
.login-btn
|
||||||
margin-right: 10px
|
margin-right: 0px
|
||||||
|
|
||||||
|
#create-account-btn
|
||||||
|
margin-left: 10px
|
||||||
|
|
||||||
#not-found-img
|
#not-found-img
|
||||||
max-width: 20%
|
max-width: 20%
|
||||||
margin: 20px 0
|
margin: 20px 0
|
||||||
|
|
||||||
#links-row
|
#links-row
|
||||||
margin-top: 50px
|
margin-top: 50px
|
||||||
|
|
|
@ -18,12 +18,12 @@ if includeSpellList
|
||||||
.glyphicon.glyphicon-repeat
|
.glyphicon.glyphicon-repeat
|
||||||
span.spl(data-i18n="play_level.reload") Reload
|
span.spl(data-i18n="play_level.reload") Reload
|
||||||
|
|
||||||
if levelType !== 'hero' && levelType !== 'hero-ladder' && levelType !== 'hero-coop'
|
if me.level() >= 15
|
||||||
.btn.btn-small.btn-illustrated.fullscreen-code(title=maximizeShortcutVerbose)
|
.btn.btn-small.btn-illustrated.fullscreen-code(title=maximizeShortcutVerbose)
|
||||||
.glyphicon.glyphicon-fullscreen
|
.glyphicon.glyphicon-fullscreen
|
||||||
.glyphicon.glyphicon-resize-small
|
.glyphicon.glyphicon-resize-small
|
||||||
|
|
||||||
if codeLanguage === 'javascript' && levelType !== 'hero' && levelType !== 'hero-ladder' && levelType !== 'hero-coop'
|
if codeLanguage === 'javascript' && me.level() >= 15
|
||||||
.btn.btn-small.btn-illustrated.beautify-code(title=beautifyShortcutVerbose)
|
.btn.btn-small.btn-illustrated.beautify-code(title=beautifyShortcutVerbose)
|
||||||
.glyphicon.glyphicon-magnet
|
.glyphicon.glyphicon-magnet
|
||||||
|
|
||||||
|
|
|
@ -40,15 +40,13 @@ findLeads((err, leads) => {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// TEMP
|
// // TEMP
|
||||||
// for (const email in leads) {
|
// for (const email in leads) {
|
||||||
// if (leads[email].coco_schoolName) {
|
// console.log(email);
|
||||||
// console.log(email);
|
// console.log(leads[email]);
|
||||||
// console.log(leads[email]);
|
// break;
|
||||||
// // break;
|
|
||||||
// }
|
|
||||||
// }
|
// }
|
||||||
// TEMP
|
// // TEMP
|
||||||
log(`Num leads created ${numLeadsCreated}`);
|
log(`Num leads created ${numLeadsCreated}`);
|
||||||
log("Script runtime: " + (new Date() - scriptStartTime));
|
log("Script runtime: " + (new Date() - scriptStartTime));
|
||||||
});
|
});
|
||||||
|
@ -187,7 +185,7 @@ function addIntercomData(leads, done) {
|
||||||
}
|
}
|
||||||
function getUser(email) {
|
function getUser(email) {
|
||||||
const options = {
|
const options = {
|
||||||
url: `https://api.intercom.io/users?email=${email}`,
|
url: `https://api.intercom.io/users?email=${encodeURIComponent(email)}`,
|
||||||
auth: {
|
auth: {
|
||||||
user: intercomAppId,
|
user: intercomAppId,
|
||||||
pass: intercomApiKey
|
pass: intercomApiKey
|
||||||
|
@ -256,7 +254,7 @@ function updateLeads(leads, done) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function updateLead(email) {
|
function updateLead(email) {
|
||||||
const url = `https://${closeIoApiKey}:X@app.close.io/api/v1/lead/?query=email_address:${email}`;
|
const url = `https://${closeIoApiKey}:X@app.close.io/api/v1/lead/?query=email_address:${encodeURIComponent(email)}`;
|
||||||
request.get(url, (error, response, body) => {
|
request.get(url, (error, response, body) => {
|
||||||
if (error) return done(error);
|
if (error) return done(error);
|
||||||
const data = JSON.parse(body);
|
const data = JSON.parse(body);
|
||||||
|
|
|
@ -17,6 +17,7 @@ auth = require './server/routes/auth'
|
||||||
routes = require './server/routes'
|
routes = require './server/routes'
|
||||||
UserHandler = require './server/users/user_handler'
|
UserHandler = require './server/users/user_handler'
|
||||||
hipchat = require './server/hipchat'
|
hipchat = require './server/hipchat'
|
||||||
|
Mandate = require './server/models/Mandate'
|
||||||
global.tv4 = require 'tv4' # required for TreemaUtils to work
|
global.tv4 = require 'tv4' # required for TreemaUtils to work
|
||||||
global.jsondiffpatch = require 'jsondiffpatch'
|
global.jsondiffpatch = require 'jsondiffpatch'
|
||||||
global.stripe = require('stripe')(config.stripe.secretKey)
|
global.stripe = require('stripe')(config.stripe.secretKey)
|
||||||
|
@ -58,15 +59,15 @@ setupErrorMiddleware = (app) ->
|
||||||
err = new errors.UnprocessableEntity(err.response)
|
err = new errors.UnprocessableEntity(err.response)
|
||||||
if err.code is 409 and err.response
|
if err.code is 409 and err.response
|
||||||
err = new errors.Conflict(err.response)
|
err = new errors.Conflict(err.response)
|
||||||
|
|
||||||
# TODO: Make all errors use this
|
# TODO: Make all errors use this
|
||||||
if err instanceof errors.NetworkError
|
if err instanceof errors.NetworkError
|
||||||
return res.status(err.code).send(err.toJSON())
|
return res.status(err.code).send(err.toJSON())
|
||||||
|
|
||||||
if err.status and 400 <= err.status < 500
|
if err.status and 400 <= err.status < 500
|
||||||
res.status(err.status).send("Error #{err.status}")
|
res.status(err.status).send("Error #{err.status}")
|
||||||
return
|
return
|
||||||
|
|
||||||
res.status(err.status ? 500).send(error: "Something went wrong!")
|
res.status(err.status ? 500).send(error: "Something went wrong!")
|
||||||
message = "Express error: #{req.method} #{req.path}: #{err.message}"
|
message = "Express error: #{req.method} #{req.path}: #{err.message}"
|
||||||
log.error "#{message}, stack: #{err.stack}"
|
log.error "#{message}, stack: #{err.stack}"
|
||||||
|
@ -180,17 +181,22 @@ setupFallbackRouteToIndex = (app) ->
|
||||||
log.error "Error modifying main.html: #{err}" if err
|
log.error "Error modifying main.html: #{err}" if err
|
||||||
# insert the user object directly into the html so the application can have it immediately. Sanitize </script>
|
# insert the user object directly into the html so the application can have it immediately. Sanitize </script>
|
||||||
user = if req.user then JSON.stringify(UserHandler.formatEntity(req, req.user)).replace(/\//g, '\\/') else '{}'
|
user = if req.user then JSON.stringify(UserHandler.formatEntity(req, req.user)).replace(/\//g, '\\/') else '{}'
|
||||||
|
|
||||||
data = data.replace '"serverConfigTag"', JSON.stringify
|
Mandate.findOne({}).cache(5 * 60 * 1000).exec (err, mandate) ->
|
||||||
picoCTF: config.picoCTF,
|
if err
|
||||||
production: config.isProduction
|
log.error "Error getting mandate config: #{err}"
|
||||||
|
configData = {}
|
||||||
data = data.replace('"userObjectTag"', user)
|
else
|
||||||
data = data.replace('"amActuallyTag"', JSON.stringify(req.session.amActually))
|
configData = _.omit mandate?.toObject() or {}, '_id'
|
||||||
res.header 'Cache-Control', 'no-cache, no-store, must-revalidate'
|
configData.picoCTF = config.picoCTF
|
||||||
res.header 'Pragma', 'no-cache'
|
configData.production = config.isProduction
|
||||||
res.header 'Expires', 0
|
data = data.replace '"serverConfigTag"', JSON.stringify configData
|
||||||
res.send 200, data
|
data = data.replace('"userObjectTag"', user)
|
||||||
|
data = data.replace('"amActuallyTag"', JSON.stringify(req.session.amActually))
|
||||||
|
res.header 'Cache-Control', 'no-cache, no-store, must-revalidate'
|
||||||
|
res.header 'Pragma', 'no-cache'
|
||||||
|
res.header 'Expires', 0
|
||||||
|
res.send 200, data
|
||||||
|
|
||||||
setupFacebookCrossDomainCommunicationRoute = (app) ->
|
setupFacebookCrossDomainCommunicationRoute = (app) ->
|
||||||
app.get '/channel.html', (req, res) ->
|
app.get '/channel.html', (req, res) ->
|
||||||
|
|
Loading…
Reference in a new issue