mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-04-13 21:44:40 -04:00
Improved my-matches rank history and name fetching, ladder update emails, ladder update unsubscribes.
This commit is contained in:
parent
c393ecd51a
commit
32baf2ae79
4 changed files with 55 additions and 39 deletions
app
server/routes
|
@ -21,9 +21,10 @@ div#columns.row
|
|||
span.ranked.hidden Submitted for Ranking
|
||||
span.failed.hidden Failed to Rank
|
||||
|
||||
tr
|
||||
th(colspan=4, style="color: #{team.primaryColor}")
|
||||
img(src="https://chart.googleapis.com/chart?chs=450x125&cht=lxy&chco=#{team.chartColor}&chtt=Score+History&chts=#{team.chartColor},16,c&chf=a,s,000000FF&chls=2&chm=o,#{team.chartColor},0,4&chd=t:#{team.chartData}")
|
||||
if team.chartData
|
||||
tr
|
||||
th(colspan=4, style="color: #{team.primaryColor}")
|
||||
img(src="https://chart.googleapis.com/chart?chs=450x125&cht=lxy&chco=#{team.chartColor}&chtt=Score+History&chts=#{team.chartColor},16,c&chf=a,s,000000FF&chls=2&chm=o,#{team.chartColor},0,4&chd=t:#{team.chartData}")
|
||||
|
||||
tr
|
||||
th Result
|
||||
|
|
|
@ -35,7 +35,7 @@ module.exports = class MyMatchesTabView extends CocoView
|
|||
for session in @sessions.models
|
||||
for match in session.get('matches') or []
|
||||
opponent = match.opponents[0]
|
||||
@nameMap[opponent.userID] = nameMap[opponent.userID]
|
||||
@nameMap[opponent.userID] ?= nameMap[opponent.userID]
|
||||
@finishRendering()
|
||||
|
||||
$.ajax('/db/user/-/names', {
|
||||
|
@ -76,15 +76,16 @@ module.exports = class MyMatchesTabView extends CocoView
|
|||
team.wins = _.filter(team.matches, {state: 'win'}).length
|
||||
team.ties = _.filter(team.matches, {state: 'tie'}).length
|
||||
team.losses = _.filter(team.matches, {state: 'loss'}).length
|
||||
team.scoreHistory = team.session.get('scoreHistory')
|
||||
team.chartColor = team.primaryColor.replace '#', ''
|
||||
times = (s[0] for s in team.scoreHistory)
|
||||
times = (100 * (t - times[0]) / (times[times.length - 1] - times[0]) for t in times)
|
||||
scores = (s[1] for s in team.scoreHistory)
|
||||
lowest = _.min scores
|
||||
highest = _.max scores
|
||||
scores = (100 * (s - lowest) / highest for s in scores)
|
||||
team.chartData = times.join(',') + '|' + scores.join(',')
|
||||
team.scoreHistory = team.session?.get('scoreHistory')
|
||||
if team.scoreHistory?.length > 1
|
||||
team.chartColor = team.primaryColor.replace '#', ''
|
||||
times = (s[0] for s in team.scoreHistory)
|
||||
times = ((100 * (t - times[0]) / (times[times.length - 1] - times[0])).toFixed(1) for t in times)
|
||||
scores = (s[1] for s in team.scoreHistory)
|
||||
lowest = _.min scores
|
||||
highest = _.max scores
|
||||
scores = (Math.round(100 * (s - lowest) / (highest - lowest)) for s in scores)
|
||||
team.chartData = times.join(',') + '|' + scores.join(',')
|
||||
|
||||
ctx
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ authentication = require('passport')
|
|||
LocalStrategy = require('passport-local').Strategy
|
||||
User = require('../users/User')
|
||||
UserHandler = require('../users/user_handler')
|
||||
LevelSession = require '../levels/sessions/LevelSession'
|
||||
config = require '../../server_config'
|
||||
errors = require '../commons/errors'
|
||||
mail = require '../commons/mail'
|
||||
|
@ -21,16 +22,16 @@ module.exports.setup = (app) ->
|
|||
if passwordReset and password.toLowerCase() is passwordReset
|
||||
User.update {_id: user.get('_id')}, {passwordReset: ''}, {}, ->
|
||||
return done(null, user)
|
||||
|
||||
|
||||
hash = User.hashPassword(password)
|
||||
unless user.get('passwordHash') is hash
|
||||
return done(null, false, {message:'is wrong, wrong, wrong', property:'password'})
|
||||
return done(null, false, {message:'is wrong, wrong, wrong', property:'password'})
|
||||
return done(null, user)
|
||||
)
|
||||
))
|
||||
app.post '/auth/spy', (req, res, next) ->
|
||||
if req?.user?.isAdmin()
|
||||
|
||||
|
||||
username = req.body.usernameLower
|
||||
emailLower = req.body.emailLower
|
||||
if emailLower
|
||||
|
@ -39,19 +40,19 @@ module.exports.setup = (app) ->
|
|||
query = {"nameLower":username}
|
||||
else
|
||||
return errors.badInput res, "You need to supply one of emailLower or username"
|
||||
|
||||
|
||||
User.findOne query, (err, user) ->
|
||||
if err? then return errors.serverError res, "There was an error finding the specified user"
|
||||
|
||||
|
||||
unless user then return errors.badInput res, "The specified user couldn't be found"
|
||||
|
||||
|
||||
req.logIn user, (err) ->
|
||||
if err? then return errors.serverError res, "There was an error logging in with the specified"
|
||||
res.send(UserHandler.formatEntity(req, user))
|
||||
return res.end()
|
||||
else
|
||||
return errors.unauthorized res, "You must be an admin to enter espionage mode"
|
||||
|
||||
|
||||
app.post('/auth/login', (req, res, next) ->
|
||||
authentication.authenticate('local', (err, user, info) ->
|
||||
return next(err) if err
|
||||
|
@ -87,11 +88,11 @@ module.exports.setup = (app) ->
|
|||
user.save((err) ->
|
||||
if err
|
||||
return @sendDatabaseError(res, err)
|
||||
|
||||
|
||||
req.logIn(user, (err) ->
|
||||
if err
|
||||
return @sendDatabaseError(res, err)
|
||||
|
||||
|
||||
if send
|
||||
return @sendSuccess(res, user)
|
||||
next() if next
|
||||
|
@ -110,7 +111,7 @@ module.exports.setup = (app) ->
|
|||
User.findOne({emailLower:req.body.email.toLowerCase()}).exec((err, user) ->
|
||||
if not user
|
||||
return errors.notFound(res, [{message:'not found.', property:'email'}])
|
||||
|
||||
|
||||
user.set('passwordReset', Math.random().toString(36).slice(2,7).toUpperCase())
|
||||
user.save (err) =>
|
||||
return errors.serverError(res) if err
|
||||
|
@ -127,12 +128,22 @@ module.exports.setup = (app) ->
|
|||
return res.end()
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
app.get '/auth/unsubscribe', (req, res) ->
|
||||
email = req.query.email
|
||||
unless req.query.email
|
||||
return errors.badInput res, 'No email provided to unsubscribe.'
|
||||
|
||||
|
||||
if req.query.session
|
||||
# Unsubscribe from just one session's notifications instead.
|
||||
return LevelSession.findOne({_id: req.query.session}).exec (err, session) ->
|
||||
return errors.serverError res, 'Could not unsubscribe: #{req.query.session}, #{req.query.email}: #{err}' if err
|
||||
session.set 'unsubscribed', true
|
||||
session.save (err) ->
|
||||
return errors.serverError res, 'Database failure.' if err
|
||||
res.send "Unsubscribed #{req.query.email} from CodeCombat emails for #{session.levelName} #{session.team} ladder updates. Sorry to see you go! <p><a href='/play/ladder/#{session.levelID}#my-matches'>Ladder preferences</a></p>"
|
||||
res.end()
|
||||
|
||||
User.findOne({emailLower:req.query.email.toLowerCase()}).exec (err, user) ->
|
||||
if not user
|
||||
return errors.notFound res, "No user found with email '#{req.query.email}'"
|
||||
|
@ -152,4 +163,4 @@ createMailOptions = (receiver, password) ->
|
|||
replyTo: config.mail.username
|
||||
subject: "[CodeCombat] Password Reset"
|
||||
text: "You can log into your account with: #{password}"
|
||||
#
|
||||
#
|
||||
|
|
|
@ -46,7 +46,7 @@ handleLadderUpdate = (req, res) ->
|
|||
#endTime = startTime + 1.5 * 60 * 60 * 1000 # Debugging: make sure there's something to send
|
||||
findParameters = {submitted: true, submitDate: {$gt: new Date(startTime), $lte: new Date(endTime)}}
|
||||
# TODO: think about putting screenshots in the email
|
||||
selectString = "creator team levelName levelID totalScore matches submitted submitDate numberOfWinsAndTies numberOfLosses"
|
||||
selectString = "creator team levelName levelID totalScore matches submitted submitDate"
|
||||
query = LevelSession.find(findParameters)
|
||||
.select(selectString)
|
||||
.lean()
|
||||
|
@ -63,8 +63,8 @@ sendLadderUpdateEmail = (session, daysAgo) ->
|
|||
if err
|
||||
log.error "Couldn't find user for #{session.creator} from session #{session._id}"
|
||||
return
|
||||
unless user.email and ('notification' in user.emailSubscriptions)
|
||||
log.info "Not sending email to #{user.email} #{user.name} because they only want emails about #{user.emailSubscriptions}"
|
||||
unless user.email and ('notification' in user.emailSubscriptions) and not session.unsubscribed
|
||||
log.info "Not sending email to #{user.email} #{user.name} because they only want emails about #{user.emailSubscriptions} - session unsubscribed: #{session.unsubscribed}"
|
||||
return
|
||||
unless session.levelName
|
||||
log.info "Not sending email to #{user.email} #{user.name} because the session had no levelName in it."
|
||||
|
@ -72,23 +72,32 @@ sendLadderUpdateEmail = (session, daysAgo) ->
|
|||
name = if user.firstName and user.lastName then "#{user.firstName} #{user.lastName}" else user.name
|
||||
name = "Wizard" if not name or name is "Anoner"
|
||||
|
||||
# Fetch the most recent defeat and victory, if there are any.
|
||||
# (We could look at strongest/weakest, but we'd have to fetch everyone, or denormalize more.)
|
||||
matches = _.filter session.matches, (match) -> match.date >= (new Date() - 86400 * 1000 * daysAgo)
|
||||
defeats = _.filter matches, (match) -> match.metrics.rank is 1 and match.opponents[0].metrics.rank is 0
|
||||
victories = _.filter matches, (match) -> match.metrics.rank is 0
|
||||
defeat = _.last defeats
|
||||
victory = _.last victories
|
||||
|
||||
sendEmail = (defeatContext, victoryContext) ->
|
||||
# TODO: do something with the preferredLanguage?
|
||||
context =
|
||||
email_id: sendwithus.templates.ladder_update_email
|
||||
recipient:
|
||||
#address: user.email
|
||||
address: 'nick@codecombat.com' # Debugging
|
||||
address: user.email
|
||||
#address: 'nick@codecombat.com' # Debugging
|
||||
name: name
|
||||
email_data:
|
||||
name: name
|
||||
days_ago: daysAgo
|
||||
wins: session.numberOfWinsAndTies
|
||||
losses: session.numberOfLosses
|
||||
wins: victories.length
|
||||
losses: defeats.length
|
||||
total_score: Math.round(session.totalScore * 100)
|
||||
team: session.team
|
||||
team_name: session.team[0].toUpperCase() + session.team.substr(1)
|
||||
level_name: session.levelName
|
||||
session_id: session._id
|
||||
ladder_url: "http://codecombat.com/play/ladder/#{session.levelID}#my-matches"
|
||||
defeat: defeatContext
|
||||
victory: victoryContext
|
||||
|
@ -96,12 +105,6 @@ sendLadderUpdateEmail = (session, daysAgo) ->
|
|||
sendwithus.api.send context, (err, result) ->
|
||||
log.error "Error sending ladder update email: #{err} with result #{result}" if err
|
||||
|
||||
# Fetch the most recent defeat and victory, if there are any.
|
||||
# (We could look at strongest/weakest, but we'd have to fetch everyone, or denormalize more.)
|
||||
defeats = _.filter session.matches, (match) -> match.metrics.rank is 1 and match.opponents[0].metrics.rank is 0
|
||||
victories = _.filter session.matches, (match) -> match.metrics.rank is 0
|
||||
defeat = _.last defeats
|
||||
victory = _.last victories
|
||||
urlForMatch = (match) ->
|
||||
"http://codecombat.com/play/level/#{session.levelID}?team=#{session.team}&session=#{session._id}&opponent=#{match.opponents[0].sessionID}"
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue