mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-04-26 14:03:28 -04:00
Merge remote-tracking branch 'upstream/master' into i18n-norwegian
This commit is contained in:
commit
fc46075b35
32 changed files with 188 additions and 60 deletions
app
core
lib/simulator
models
views
account
admin
common
core
editor
ladder
LadderPlayModal.coffeeLadderTabView.coffeeLadderView.coffeeMainLadderView.coffeeSimulateTabView.coffee
modal
play
user
scripts/analytics
server/queues
|
@ -23,10 +23,9 @@ definitionSchemas =
|
|||
init = ->
|
||||
return if app
|
||||
if not window.userObject._id
|
||||
$.ajax('/auth/whoami', {success: (res) ->
|
||||
$.ajax '/auth/whoami', cache: false, success: (res) ->
|
||||
window.userObject = res
|
||||
init()
|
||||
})
|
||||
return
|
||||
|
||||
app = require 'core/application'
|
||||
|
|
|
@ -136,6 +136,7 @@ module.exports = class Simulator extends CocoClass
|
|||
parse: true
|
||||
error: @handleFetchTaskError
|
||||
success: @setupSimulationAndLoadLevel
|
||||
cache: false
|
||||
|
||||
handleFetchTaskError: (errorData) =>
|
||||
console.error "There was a horrible Error: #{JSON.stringify errorData}"
|
||||
|
|
|
@ -367,6 +367,7 @@ class CocoModel extends Backbone.Model
|
|||
me.fetch (success: -> Backbone.Mediator.publish('achievements:new', earnedAchievements: collection)) unless _.isEmpty(collection.models)
|
||||
error: ->
|
||||
console.error 'Miserably failed to fetch unnotified achievements', arguments
|
||||
cache: false
|
||||
|
||||
CocoModel.pollAchievements = _.debounce CocoModel.pollAchievements, 500
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ module.exports = class User extends CocoModel
|
|||
|
||||
@getUnconflictedName: (name, done) ->
|
||||
$.ajax "/auth/name/#{name}",
|
||||
cache: false
|
||||
success: (data) -> done data.name
|
||||
statusCode: 409: (data) ->
|
||||
response = JSON.parse data.responseText
|
||||
|
|
|
@ -10,9 +10,9 @@ module.exports = class PaymentsView extends RootView
|
|||
constructor: (options) ->
|
||||
super(options)
|
||||
@payments = new CocoCollection([], { url: '/db/payment', model: Payment, comparator:'_id' })
|
||||
@supermodel.loadCollection(@payments, 'payments')
|
||||
@supermodel.loadCollection(@payments, 'payments', {cache: false})
|
||||
|
||||
getRenderData: ->
|
||||
c = super()
|
||||
c.payments = @payments
|
||||
c
|
||||
c
|
||||
|
|
|
@ -20,11 +20,11 @@ module.exports = class SubscriptionView extends RootView
|
|||
constructor: (options) ->
|
||||
super(options)
|
||||
if me.get('stripe')
|
||||
options = { url: "/db/user/#{me.id}/stripe" }
|
||||
options = { cache: false, url: "/db/user/#{me.id}/stripe" }
|
||||
options.success = (@stripeInfo) =>
|
||||
@supermodel.addRequestResource('payment_info', options).load()
|
||||
@payments = new CocoCollection([], { url: '/db/payment', model: Payment, comparator:'_id' })
|
||||
@supermodel.loadCollection(@payments, 'payments')
|
||||
@supermodel.loadCollection(@payments, 'payments', {cache: false})
|
||||
|
||||
getRenderData: ->
|
||||
c = super()
|
||||
|
|
|
@ -25,11 +25,11 @@ module.exports = class UnsubscribeView extends RootView
|
|||
success = =>
|
||||
@$el.find('.progress').hide()
|
||||
@$el.find('#success-alert').show()
|
||||
me.fetch()
|
||||
me.fetch cache: false
|
||||
|
||||
error = =>
|
||||
@$el.find('.progress').hide()
|
||||
@$el.find('#fail-alert').show()
|
||||
@$el.find('#unsubscribe-button').show()
|
||||
|
||||
$.ajax { url: url, success: success, error: error }
|
||||
$.ajax { url: url, success: success, error: error, cache: false }
|
||||
|
|
|
@ -6,18 +6,18 @@ module.exports = class AdministerUserModal extends ModalView
|
|||
id: "administer-user-modal"
|
||||
template: template
|
||||
plain: true
|
||||
|
||||
|
||||
events:
|
||||
'click #save-changes': 'onSaveChanges'
|
||||
|
||||
|
||||
constructor: (options, @userHandle) ->
|
||||
super(options)
|
||||
@user = @supermodel.loadModel(new User({_id:@userHandle}), 'user').model
|
||||
options = {url: '/stripe/coupons'}
|
||||
options.success = (@coupons) =>
|
||||
@user = @supermodel.loadModel(new User({_id:@userHandle}), 'user', {cache: false}).model
|
||||
options = {cache: false, url: '/stripe/coupons'}
|
||||
options.success = (@coupons) =>
|
||||
@couponsResource = @supermodel.addRequestResource('coupon', options)
|
||||
@couponsResource.load()
|
||||
|
||||
|
||||
getRenderData: ->
|
||||
c = super()
|
||||
stripe = @user.get('stripe') or {}
|
||||
|
@ -40,12 +40,12 @@ module.exports = class AdministerUserModal extends ModalView
|
|||
c.none = not (c.free or c.freeUntil or c.coupon)
|
||||
c.user = @user
|
||||
c
|
||||
|
||||
|
||||
onSaveChanges: ->
|
||||
stripe = _.clone(@user.get('stripe') or {})
|
||||
delete stripe.free
|
||||
delete stripe.couponID
|
||||
|
||||
|
||||
selection = @$el.find('input[name="stripe-benefit"]:checked').val()
|
||||
dateVal = @$el.find('#free-until-date').val()
|
||||
couponVal = @$el.find('#coupon-select').val()
|
||||
|
@ -53,10 +53,8 @@ module.exports = class AdministerUserModal extends ModalView
|
|||
when 'free' then stripe.free = true
|
||||
when 'free-until' then stripe.free = dateVal
|
||||
when 'coupon' then stripe.couponID = couponVal
|
||||
|
||||
|
||||
@user.set('stripe', stripe)
|
||||
options = {}
|
||||
options.success = => @hide()
|
||||
@user.patch(options)
|
||||
|
||||
|
|
@ -18,7 +18,7 @@ module.exports = class CLAsView extends RootView
|
|||
|
||||
constructor: (options) ->
|
||||
super options
|
||||
@clas = @supermodel.loadCollection(new CLACollection(), 'clas').model
|
||||
@clas = @supermodel.loadCollection(new CLACollection(), 'clas', {cache: false}).model
|
||||
|
||||
getRenderData: ->
|
||||
c = super()
|
||||
|
|
|
@ -37,6 +37,7 @@ module.exports = class FilesView extends RootView
|
|||
$.ajax
|
||||
url: "/file/#{@currentFolder()}/"
|
||||
success: @onLoadedFiles
|
||||
cache: false
|
||||
|
||||
onLoadedFiles: (res) =>
|
||||
table = tableTemplate({files:res})
|
||||
|
|
|
@ -16,7 +16,7 @@ module.exports = class LevelSessionsView extends RootView
|
|||
@getLevelSessions()
|
||||
|
||||
getLevelSessions: ->
|
||||
@sessions = @supermodel.loadCollection(new LevelSessionCollection(), 'sessions').model
|
||||
@sessions = @supermodel.loadCollection(new LevelSessionCollection(), 'sessions', {cache: false}).model
|
||||
|
||||
getRenderData: =>
|
||||
c = super()
|
||||
|
|
|
@ -17,7 +17,7 @@ module.exports = class UserView extends RootView
|
|||
@user = me
|
||||
@onLoaded()
|
||||
@user = new User _id: @userID
|
||||
@supermodel.loadModel @user, 'user'
|
||||
@supermodel.loadModel @user, 'user', cache: false
|
||||
|
||||
getRenderData: ->
|
||||
context = super()
|
||||
|
|
|
@ -39,7 +39,7 @@ module.exports = class RootView extends CocoView
|
|||
earnedAchievement.set('notified', true)
|
||||
earnedAchievement.patch()
|
||||
return if achievement.get('collection') is 'level.sessions'
|
||||
return if @isIE() # Some bugs in IE right now, TODO fix soon!
|
||||
#return if @isIE() # Some bugs in IE right now, TODO fix soon! # Maybe working now with not caching achievement fetches in CocoModel?
|
||||
new AchievementPopup achievement: achievement, earnedAchievement: earnedAchievement
|
||||
|
||||
handleNewAchievements: (e) ->
|
||||
|
@ -47,6 +47,7 @@ module.exports = class RootView extends CocoView
|
|||
achievement = new Achievement(_id: earnedAchievement.get('achievement'))
|
||||
achievement.fetch
|
||||
success: (achievement) => @showNewAchievement?(achievement, earnedAchievement)
|
||||
cache: false
|
||||
|
||||
logoutAccount: ->
|
||||
Backbone.Mediator.publish("auth:logging-out", {})
|
||||
|
|
|
@ -23,7 +23,7 @@ module.exports = class PatchesView extends CocoView
|
|||
|
||||
load: ->
|
||||
@initPatches()
|
||||
@patches = @supermodel.loadCollection(@patches, 'patches').model
|
||||
@patches = @supermodel.loadCollection(@patches, 'patches', {cache: false}).model
|
||||
@listenTo @patches, 'sync', @onPatchesLoaded
|
||||
|
||||
onPatchesLoaded: ->
|
||||
|
|
|
@ -195,13 +195,13 @@ class ChallengersData
|
|||
_.extend @, Backbone.Events
|
||||
score = @session?.get('totalScore') or 25
|
||||
@easyPlayer = new LeaderboardCollection(@level, {order: 1, scoreOffset: score - 5, limit: 1, team: @otherTeam})
|
||||
@easyPlayer.fetch()
|
||||
@easyPlayer.fetch cache: false
|
||||
@listenToOnce(@easyPlayer, 'sync', @challengerLoaded)
|
||||
@mediumPlayer = new LeaderboardCollection(@level, {order: 1, scoreOffset: score, limit: 1, team: @otherTeam})
|
||||
@mediumPlayer.fetch()
|
||||
@mediumPlayer.fetch cache: false
|
||||
@listenToOnce(@mediumPlayer, 'sync', @challengerLoaded)
|
||||
@hardPlayer = new LeaderboardCollection(@level, {order: -1, scoreOffset: score + 5, limit: 1, team: @otherTeam})
|
||||
@hardPlayer.fetch()
|
||||
@hardPlayer.fetch cache: false
|
||||
@listenToOnce(@hardPlayer, 'sync', @challengerLoaded)
|
||||
|
||||
challengerLoaded: ->
|
||||
|
|
|
@ -154,7 +154,7 @@ module.exports = class LadderTabView extends CocoView
|
|||
oldLeaderboard.destroy()
|
||||
teamSession = _.find @sessions.models, (session) -> session.get('team') is team.id
|
||||
@leaderboards[team.id] = new LeaderboardData(@level, team.id, teamSession, @ladderLimit)
|
||||
@leaderboardRes = @supermodel.addModelResource(@leaderboards[team.id], 'leaderboard', {}, 3)
|
||||
@leaderboardRes = @supermodel.addModelResource(@leaderboards[team.id], 'leaderboard', {cache: false}, 3)
|
||||
@leaderboardRes.load()
|
||||
|
||||
render: ->
|
||||
|
@ -165,7 +165,7 @@ module.exports = class LadderTabView extends CocoView
|
|||
team = _.find @teams, name: histogramWrapper.data('team-name')
|
||||
histogramData = null
|
||||
$.when(
|
||||
$.get("/db/level/#{@level.get('slug')}/histogram_data?team=#{team.name.toLowerCase()}", (data) -> histogramData = data)
|
||||
$.get "/db/level/#{@level.get('slug')}/histogram_data?team=#{team.name.toLowerCase()}", {cache: false}, (data) -> histogramData = data
|
||||
).then =>
|
||||
@generateHistogram(histogramWrapper, histogramData, team.name.toLowerCase()) unless @destroyed
|
||||
|
||||
|
@ -294,17 +294,17 @@ module.exports.LeaderboardData = LeaderboardData = class LeaderboardData extends
|
|||
console.warn 'Already have top players on', @ if @topPlayers
|
||||
@topPlayers = new LeaderboardCollection(@level, {order: -1, scoreOffset: HIGHEST_SCORE, team: @team, limit: @limit})
|
||||
promises = []
|
||||
promises.push @topPlayers.fetch()
|
||||
promises.push @topPlayers.fetch cache: false
|
||||
|
||||
if @session
|
||||
score = @session.get('totalScore') or 10
|
||||
@playersAbove = new LeaderboardCollection(@level, {order: 1, scoreOffset: score, limit: 4, team: @team})
|
||||
promises.push @playersAbove.fetch()
|
||||
promises.push @playersAbove.fetch cache: false
|
||||
@playersBelow = new LeaderboardCollection(@level, {order: -1, scoreOffset: score, limit: 4, team: @team})
|
||||
promises.push @playersBelow.fetch()
|
||||
promises.push @playersBelow.fetch cache: false
|
||||
level = "#{@level.get('original')}.#{@level.get('version').major}"
|
||||
success = (@myRank) =>
|
||||
promises.push $.ajax "/db/level/#{level}/leaderboard_rank?scoreOffset=#{@session.get('totalScore')}&team=#{@team}", {success}
|
||||
promises.push $.ajax("/db/level/#{level}/leaderboard_rank?scoreOffset=#{@session.get('totalScore')}&team=#{@team}", cache: false, success: success)
|
||||
@promise = $.when(promises...)
|
||||
@promise.then @onLoad
|
||||
@promise.fail @onFail
|
||||
|
|
|
@ -37,7 +37,7 @@ module.exports = class LadderView extends RootView
|
|||
constructor: (options, @levelID) ->
|
||||
super(options)
|
||||
@level = @supermodel.loadModel(new Level(_id: @levelID), 'level').model
|
||||
@sessions = @supermodel.loadCollection(new LevelSessionsCollection(@levelID), 'your_sessions').model
|
||||
@sessions = @supermodel.loadCollection(new LevelSessionsCollection(@levelID), 'your_sessions', {cache: false}).model
|
||||
|
||||
@teams = []
|
||||
|
||||
|
@ -71,7 +71,7 @@ module.exports = class LadderView extends RootView
|
|||
|
||||
fetchSessionsAndRefreshViews: ->
|
||||
return if @destroyed or application.userIsIdle or (new Date() - 2000 < @lastRefreshTime) or not @supermodel.finished()
|
||||
@sessions.fetch({'success': @refreshViews})
|
||||
@sessions.fetch success: @refreshViews, cache: false
|
||||
|
||||
refreshViews: =>
|
||||
return if @destroyed or application.userIsIdle
|
||||
|
|
|
@ -19,7 +19,7 @@ module.exports = class LadderHomeView extends RootView
|
|||
super options
|
||||
@levelStatusMap = {}
|
||||
@levelPlayCountMap = {}
|
||||
@sessions = @supermodel.loadCollection(new LevelSessionsCollection(), 'your_sessions', null, 0).model
|
||||
@sessions = @supermodel.loadCollection(new LevelSessionsCollection(), 'your_sessions', {cache: false}, 0).model
|
||||
@listenToOnce @sessions, 'sync', @onSessionsLoaded
|
||||
@getLevelPlayCounts()
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ module.exports = class SimulateTabView extends CocoView
|
|||
constructor: (options) ->
|
||||
super(options)
|
||||
@simulatorsLeaderboardData = new SimulatorsLeaderboardData(me)
|
||||
@simulatorsLeaderboardDataRes = @supermodel.addModelResource(@simulatorsLeaderboardData, 'top_simulators')
|
||||
@simulatorsLeaderboardDataRes = @supermodel.addModelResource(@simulatorsLeaderboardData, 'top_simulators', {cache: false})
|
||||
@simulatorsLeaderboardDataRes.load()
|
||||
require 'vendor/aether-javascript'
|
||||
require 'vendor/aether-python'
|
||||
|
@ -77,7 +77,7 @@ module.exports = class SimulateTabView extends CocoView
|
|||
refresh: ->
|
||||
success = (numberOfGamesInQueue) ->
|
||||
$('#games-in-queue').text numberOfGamesInQueue
|
||||
$.ajax '/queue/messagesInQueueCount', {success}
|
||||
$.ajax '/queue/messagesInQueueCount', cache: false, success: success
|
||||
|
||||
updateSimulationStatus: (simulationStatus, sessions) ->
|
||||
if simulationStatus is 'Fetching simulation data!'
|
||||
|
@ -131,15 +131,14 @@ class SimulatorsLeaderboardData extends CocoClass
|
|||
unless @me.get('anonymous')
|
||||
score = @me.get('simulatedBy') or 0
|
||||
queueSuccess = (@numberOfGamesInQueue) =>
|
||||
promises.push $.ajax '/queue/messagesInQueueCount', {success: queueSuccess}
|
||||
promises.push $.ajax '/queue/messagesInQueueCount', {success: queueSuccess, cache: false}
|
||||
@playersAbove = new SimulatorsLeaderboardCollection({order: 1, scoreOffset: score, limit: 4})
|
||||
promises.push @playersAbove.fetch()
|
||||
if score
|
||||
@playersBelow = new SimulatorsLeaderboardCollection({order: -1, scoreOffset: score, limit: 4})
|
||||
promises.push @playersBelow.fetch()
|
||||
success = (@myRank) =>
|
||||
|
||||
promises.push $.ajax "/db/user/me/simulator_leaderboard_rank?scoreOffset=#{score}", {success}
|
||||
promises.push $.ajax("/db/user/me/simulator_leaderboard_rank?scoreOffset=#{score}", cache: false, success: success)
|
||||
|
||||
@promise = $.when(promises...)
|
||||
@promise.then @onLoad
|
||||
|
|
|
@ -75,7 +75,7 @@ module.exports = class EmployerSignupModal extends ModalView
|
|||
|
||||
handleAgreementSuccess: (result) ->
|
||||
window.tracker?.trackEvent 'Employer Agreed to Contract'
|
||||
me.fetch()
|
||||
me.fetch cache: false
|
||||
window.location.reload()
|
||||
|
||||
handleAgreementFailure: (error) ->
|
||||
|
@ -130,7 +130,7 @@ module.exports = class EmployerSignupModal extends ModalView
|
|||
@listenTo me, 'sync', =>
|
||||
@render()
|
||||
IN.parse()
|
||||
me.fetch()
|
||||
me.fetch cache: false
|
||||
|
||||
destroy: ->
|
||||
reloadWhenClosed = @reloadWhenClosed
|
||||
|
|
|
@ -14,7 +14,7 @@ module.exports = class ModelModal extends ModalView
|
|||
@models = options.models
|
||||
for model in @models when not model.loaded
|
||||
@supermodel.loadModel model, 'source_document'
|
||||
model.fetch()
|
||||
model.fetch cache: false
|
||||
|
||||
getRenderData: ->
|
||||
c = super()
|
||||
|
|
|
@ -62,7 +62,7 @@ module.exports = class CampaignView extends RootView
|
|||
@terrain ?= 'dungeon'
|
||||
@levelStatusMap = {}
|
||||
@levelPlayCountMap = {}
|
||||
@sessions = @supermodel.loadCollection(new LevelSessionsCollection(), 'your_sessions', null, 0).model
|
||||
@sessions = @supermodel.loadCollection(new LevelSessionsCollection(), 'your_sessions', {cache: false}, 0).model
|
||||
@listenToOnce @sessions, 'sync', @onSessionsLoaded
|
||||
unless @terrain
|
||||
@campaigns = @supermodel.loadCollection(new CampaignsCollection(), 'campaigns', null, 0).model
|
||||
|
@ -85,7 +85,7 @@ module.exports = class CampaignView extends RootView
|
|||
console.warn 'Filling in a gap for reward', group, reward
|
||||
earned[group].push(reward)
|
||||
|
||||
@supermodel.loadCollection(@earnedAchievements, 'achievements')
|
||||
@supermodel.loadCollection(@earnedAchievements, 'achievements', {cache: false})
|
||||
|
||||
@listenToOnce @campaign, 'sync', @getLevelPlayCounts
|
||||
$(window).on 'resize', @onWindowResize
|
||||
|
@ -375,7 +375,7 @@ module.exports = class CampaignView extends RootView
|
|||
sessionURL = "/db/level/#{levelSlug}/session"
|
||||
@preloadedSession = new LevelSession().setURL sessionURL
|
||||
@listenToOnce @preloadedSession, 'sync', @onSessionPreloaded
|
||||
@preloadedSession = @supermodel.loadModel(@preloadedSession, 'level_session').model
|
||||
@preloadedSession = @supermodel.loadModel(@preloadedSession, 'level_session', {cache: false}).model
|
||||
@preloadedSession.levelSlug = levelSlug
|
||||
|
||||
onSessionPreloaded: (session) ->
|
||||
|
|
|
@ -19,7 +19,7 @@ module.exports = class MainPlayView extends RootView
|
|||
super options
|
||||
@levelStatusMap = {}
|
||||
@levelPlayCountMap = {}
|
||||
@sessions = @supermodel.loadCollection(new LevelSessionsCollection(), 'your_sessions', null, 0).model
|
||||
@sessions = @supermodel.loadCollection(new LevelSessionsCollection(), 'your_sessions', {cache: false}, 0).model
|
||||
@listenToOnce @sessions, 'sync', @onSessionsLoaded
|
||||
@getLevelPlayCounts()
|
||||
|
||||
|
|
|
@ -294,6 +294,7 @@ module.exports = class SpectateLevelView extends RootView
|
|||
$.ajax
|
||||
url: randomSessionPairURL
|
||||
type: 'GET'
|
||||
cache: false
|
||||
complete: (jqxhr, textStatus) ->
|
||||
if textStatus isnt 'success'
|
||||
cb('error', jqxhr.statusText)
|
||||
|
|
|
@ -39,7 +39,7 @@ module.exports = class VictoryModal extends ModalView
|
|||
url = "/db/level/#{@level.id}/feedback"
|
||||
@feedback = new LevelFeedback()
|
||||
@feedback.setURL url
|
||||
@feedback.fetch()
|
||||
@feedback.fetch cache: false
|
||||
@listenToOnce(@feedback, 'sync', -> @onFeedbackLoaded())
|
||||
@listenToOnce(@feedback, 'error', -> @onFeedbackNotFound())
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ module.exports = class LeaderboardTabView extends CocoView
|
|||
return if @hasShown
|
||||
@hasShown = true
|
||||
topScores = new TopScoresCollection @level, @scoreType, @timespan
|
||||
@sessions = @supermodel.loadCollection(topScores, 'sessions', null, 0).model
|
||||
@sessions = @supermodel.loadCollection(topScores, 'sessions', {cache: false}, 0).model
|
||||
|
||||
onClickRow: (e) ->
|
||||
sessionID = $(e.target).closest('tr').data 'session-id'
|
||||
|
|
|
@ -36,9 +36,9 @@ module.exports = class PlayAchievementsModal extends ModalView
|
|||
earnedAchievementsFetcher.setProjection([ 'achievement' ])
|
||||
|
||||
achievementsFetcher.skip = 0
|
||||
achievementsFetcher.fetch({data: {skip: 0, limit: PAGE_SIZE}})
|
||||
achievementsFetcher.fetch cache: false, data: {skip: 0, limit: PAGE_SIZE}
|
||||
earnedAchievementsFetcher.skip = 0
|
||||
earnedAchievementsFetcher.fetch({data: {skip: 0, limit: PAGE_SIZE}})
|
||||
earnedAchievementsFetcher.fetch cache: false, data: {skip: 0, limit: PAGE_SIZE}
|
||||
|
||||
@listenTo achievementsFetcher, 'sync', @onAchievementsLoaded
|
||||
@listenTo earnedAchievementsFetcher, 'sync', @onEarnedAchievementsLoaded
|
||||
|
@ -53,7 +53,7 @@ module.exports = class PlayAchievementsModal extends ModalView
|
|||
@achievements.add(fetcher.models)
|
||||
if needMore
|
||||
fetcher.skip += PAGE_SIZE
|
||||
fetcher.fetch({data: {skip: fetcher.skip, limit: PAGE_SIZE}})
|
||||
fetcher.fetch cache: false, data: {skip: fetcher.skip, limit: PAGE_SIZE}
|
||||
else
|
||||
@stopListening(fetcher)
|
||||
@onEverythingLoaded()
|
||||
|
@ -64,7 +64,7 @@ module.exports = class PlayAchievementsModal extends ModalView
|
|||
@earnedMap[earned.get('achievement')] = earned
|
||||
if needMore
|
||||
fetcher.skip += PAGE_SIZE
|
||||
fetcher.fetch({data: {skip: fetcher.skip, limit: PAGE_SIZE}})
|
||||
fetcher.fetch cache: false, data: {skip: fetcher.skip, limit: PAGE_SIZE}
|
||||
else
|
||||
@stopListening(fetcher)
|
||||
@onEverythingLoaded()
|
||||
|
|
|
@ -85,7 +85,7 @@ module.exports = class JobProfileView extends UserView
|
|||
# Mimicking how the VictoryModal fetches LevelFeedback
|
||||
@remark = new UserRemark()
|
||||
@remark.setURL "/db/user/#{@userID}/remark"
|
||||
@remark.fetch()
|
||||
@remark.fetch cache: false
|
||||
@listenToOnce @remark, 'sync', @onRemarkLoaded
|
||||
@listenToOnce @remark, 'error', @onRemarkNotFound
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ class LevelSessionsCollection extends CocoCollection
|
|||
module.exports = class MainUserView extends UserView
|
||||
id: 'user-home'
|
||||
template: template
|
||||
|
||||
|
||||
events:
|
||||
'click .more-button': 'onClickMoreButton'
|
||||
|
||||
|
@ -54,11 +54,11 @@ module.exports = class MainUserView extends UserView
|
|||
@supermodel.resetProgress()
|
||||
@levelSessions = new LevelSessionsCollection @user.getSlugOrID()
|
||||
@earnedAchievements = new EarnedAchievementCollection @user.getSlugOrID()
|
||||
@supermodel.loadCollection @levelSessions, 'levelSessions'
|
||||
@supermodel.loadCollection @earnedAchievements, 'earnedAchievements'
|
||||
@supermodel.loadCollection @levelSessions, 'levelSessions', {cache: false}
|
||||
@supermodel.loadCollection @earnedAchievements, 'earnedAchievements', {cache: false}
|
||||
super()
|
||||
|
||||
onClickMoreButton: (e) ->
|
||||
panel = $(e.target).closest('.panel')
|
||||
panel.find('tr.hide').removeClass('hide')
|
||||
panel.find('.panel-footer').remove()
|
||||
panel.find('.panel-footer').remove()
|
||||
|
|
122
scripts/analytics/mixpanelABGemPrompt.py
Normal file
122
scripts/analytics/mixpanelABGemPrompt.py
Normal file
|
@ -0,0 +1,122 @@
|
|||
# Calculate gem prompt A/B test results
|
||||
|
||||
# TODO: Why is no-prompt group 50% larger?
|
||||
|
||||
import sys
|
||||
from mixpanel import Mixpanel
|
||||
|
||||
try:
|
||||
import json
|
||||
except ImportError:
|
||||
import simplejson as json
|
||||
|
||||
# NOTE: mixpanel dates are by day and inclusive
|
||||
# E.g. '2014-12-08' is any date that day, up to 2014-12-09 12am
|
||||
|
||||
if __name__ == '__main__':
|
||||
if not len(sys.argv) is 3:
|
||||
print "Script format: <script> <api_key> <api_secret>"
|
||||
else:
|
||||
api_key = sys.argv[1]
|
||||
api_secret = sys.argv[2]
|
||||
api = Mixpanel(
|
||||
api_key = api_key,
|
||||
api_secret = api_secret
|
||||
)
|
||||
|
||||
startDate = '2015-01-15'
|
||||
startDate = '2014-11-25'
|
||||
endDate = '2015-02-11'
|
||||
|
||||
print("Requesting data for {0} to {1}".format(startDate, endDate))
|
||||
data = api.request(['export'], {
|
||||
'event' : ['Started purchase', 'Finished gem purchase'],
|
||||
'from_date' : startDate,
|
||||
'to_date' : endDate
|
||||
})
|
||||
|
||||
userProgressionGroupA = {}
|
||||
userProgressionGroupB = {}
|
||||
|
||||
lines = data.split('\n')
|
||||
print "Received %d entries" % len(lines)
|
||||
for line in lines:
|
||||
try:
|
||||
if len(line) is 0: continue
|
||||
eventData = json.loads(line)
|
||||
eventName = eventData['event']
|
||||
properties = eventData['properties']
|
||||
if not eventName in ['Started purchase', 'Finished gem purchase']:
|
||||
print 'Unexpected event ' + eventName
|
||||
break
|
||||
if 'distinct_id' in properties and 'gemPromptGroup' in properties:
|
||||
userID = properties['distinct_id']
|
||||
if properties['gemPromptGroup'] == 'prompt':
|
||||
if not userID in userProgressionGroupA:
|
||||
userProgressionGroupA[userID] = {
|
||||
'Started purchase': 0,
|
||||
'Finished gem purchase': 0
|
||||
}
|
||||
userProgressionGroupA[userID][eventName] += 1
|
||||
elif properties['gemPromptGroup'] == 'no-prompt':
|
||||
if not userID in userProgressionGroupB:
|
||||
userProgressionGroupB[userID] = {
|
||||
'Started purchase': 0,
|
||||
'Finished gem purchase': 0
|
||||
}
|
||||
userProgressionGroupB[userID][eventName] += 1
|
||||
else:
|
||||
print "Unexpected group:", properties['gemPromptGroup']
|
||||
print properties
|
||||
print line
|
||||
break
|
||||
except:
|
||||
print "Unexpected error:", sys.exc_info()[0]
|
||||
print line
|
||||
break
|
||||
|
||||
try:
|
||||
started = converted = 0
|
||||
startedGroupA = convertedGroupA = 0
|
||||
startedGroupB = convertedGroupB = 0
|
||||
|
||||
# Group A
|
||||
print("Processing Group A")
|
||||
for key, item in userProgressionGroupA.iteritems():
|
||||
if item['Finished gem purchase'] > 0:
|
||||
converted += 1
|
||||
convertedGroupA += 1
|
||||
# TODO: is our distinct_id correct? We hit this at least once.
|
||||
# if item['Finished gem purchase'] > 1:
|
||||
# print "User multiple subcription purchases?"
|
||||
# print item
|
||||
elif item['Started purchase'] > 0:
|
||||
started += 1
|
||||
startedGroupA += 1
|
||||
else:
|
||||
print "User without any hits?"
|
||||
print item
|
||||
break
|
||||
|
||||
# Group B
|
||||
print("Processing Group B")
|
||||
for key, item in userProgressionGroupB.iteritems():
|
||||
if item['Finished gem purchase'] > 0:
|
||||
converted += 1
|
||||
convertedGroupB += 1
|
||||
elif item['Started purchase'] > 0:
|
||||
started += 1
|
||||
startedGroupB += 1
|
||||
else:
|
||||
print "User without any hits?"
|
||||
print item
|
||||
break
|
||||
|
||||
print("Overall")
|
||||
print("started {0} converted {1} rate {2}%".format(started, converted, float(converted) / started * 100))
|
||||
print("Group prompt")
|
||||
print("startedGroupA {0} convertedGroupA {1} rate {2}%".format(startedGroupA, convertedGroupA, float(convertedGroupA) / startedGroupA * 100))
|
||||
print("Group no-prompt")
|
||||
print("startedGroupB {0} convertedGroupB {1} rate {2}%".format(startedGroupB, convertedGroupB, float(convertedGroupB) / startedGroupB * 100))
|
||||
except:
|
||||
print "Unexpected error:", sys.exc_info()[0]
|
|
@ -4,11 +4,14 @@
|
|||
// Usage:
|
||||
// mongo <address>:<port>/<database> <script file> -u <username> -p <password>
|
||||
|
||||
// TODO: Why is no-prompt group 50% larger?
|
||||
|
||||
load('abTestHelpers.js');
|
||||
|
||||
var scriptStartTime = new Date();
|
||||
try {
|
||||
var startDay = '2014-11-24'
|
||||
// startDay = '2015-01-15'
|
||||
log("Today is " + new Date().toISOString().substr(0, 10));
|
||||
log("Start day is " + startDay);
|
||||
|
||||
|
|
|
@ -124,7 +124,8 @@ module.exports.getTwoGames = (req, res) ->
|
|||
#if userIsAnonymous req then return errors.unauthorized(res, 'You need to be logged in to get games.')
|
||||
humansGameID = req.body.humansGameID
|
||||
ogresGameID = req.body.ogresGameID
|
||||
ladderGameIDs = ['greed', 'criss-cross', 'brawlwood', 'dungeon-arena', 'gold-rush', 'sky-span', 'dueling-grounds', 'cavern-survival', 'multiplayer-treasure-grove']
|
||||
#ladderGameIDs = ['greed', 'criss-cross', 'brawlwood', 'dungeon-arena', 'gold-rush', 'sky-span'] # Let's not give any extra simulations to old ladders.
|
||||
ladderGameIDs = ['dueling-grounds', 'cavern-survival', 'multiplayer-treasure-grove']
|
||||
levelID = _.sample ladderGameIDs
|
||||
sortLimit = 200
|
||||
unless ogresGameID and humansGameID
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue