Merge branch 'master' into production

This commit is contained in:
Scott Erickson 2014-04-19 10:28:57 -07:00
commit 6641e60f2d
4 changed files with 147 additions and 45 deletions

View file

@ -73,7 +73,7 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
creating: "账户创建中……"
sign_up: "注册"
log_in: "登录"
# social_signup: "Or, you can sign up through Facebook or G+:"
social_signup: "或者你可以通过Facebook或G+注册:"
home:
slogan: "通过游戏学习 Javascript"
@ -114,7 +114,7 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
forum_page: "我们的论坛"
forum_suffix: ""
send: "反馈意见"
# contact_candidate: "Contact Candidate"
contact_candidate: "联系参选人"
# recruitment_reminder: "Use this form to reach out to candidates you are interested in interviewing. Remember that CodeCombat charges 18% of first-year salary. The fee is due upon hiring the employee and is refundable for 90 days if the employee does not remain employed. Part time, remote, and contract employees are free, as are interns."
diplomat_suggestion:
@ -128,13 +128,13 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
wizard_settings:
title: "设置向导"
customize_avatar: "设置你的头像"
# active: "Active"
# color: "Color"
# group: "Group"
active: "启用"
color: "颜色"
group: "类别"
clothes: "衣服"
trim: "条纹"
cloud: ""
# team: "Team"
team: "队伍"
spell: "魔法球"
boots: "鞋子"
hue: "颜色"
@ -177,27 +177,27 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
profile_for_suffix: ""
# approved: "Approved"
# not_approved: "Not Approved"
# looking_for: "Looking for:"
# last_updated: "Last updated:"
# contact: "Contact"
# work_experience: "Work Experience"
# education: "Education"
looking_for: "寻找"
last_updated: "最后一次更新:"
contact: "联系"
work_experience: "工作经验"
education: "教育程度"
# our_notes: "Our Notes"
# projects: "Projects"
projects: "项目"
# employers:
# want_to_hire_our_players: "Want to hire expert CodeCombat players?"
want_to_hire_our_players: "想要雇用CodeCombat上的专业玩家"
# contact_george: "Contact George to see our candidates"
# candidates_count_prefix: "We currently have "
# candidates_count_many: "many"
candidates_count_prefix: "我们当前有 "
candidates_count_many: "很多"
# candidates_count_suffix: "highly skilled and vetted developers looking for work."
# candidate_name: "Name"
# candidate_location: "Location"
# candidate_looking_for: "Looking For"
# candidate_role: "Role"
# candidate_top_skills: "Top Skills"
# candidate_years_experience: "Yrs Exp"
# candidate_last_updated: "Last Updated"
candidate_name: "姓名"
candidate_location: "地点"
candidate_looking_for: "寻找"
candidate_role: "角色"
candidate_top_skills: "高级技能"
candidate_years_experience: "多年工作经验"
candidate_last_updated: "最后一次更新"
play_level:
level_load_error: "关卡不能载入: "
@ -250,17 +250,17 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
editor_config_title: "编辑器配置"
editor_config_language_label: "编程语言"
editor_config_language_description: "请输入你想写的编程语言."
# editor_config_keybindings_label: "Key Bindings"
# editor_config_keybindings_default: "Default (Ace)"
editor_config_keybindings_label: "按键设置s"
editor_config_keybindings_default: "默认 (Ace)"
# editor_config_keybindings_description: "Adds additional shortcuts known from the common editors."
# editor_config_invisibles_label: "Show Invisibles"
# editor_config_invisibles_description: "Displays invisibles such as spaces or tabs."
# editor_config_indentguides_label: "Show Indent Guides"
# editor_config_indentguides_description: "Displays vertical lines to see indentation better."
editor_config_invisibles_label: "显示隐藏的"
editor_config_invisibles_description: "显示诸如空格或TAB键。"
editor_config_indentguides_label: "显示缩进提示"
editor_config_indentguides_description: "显示一条竖线以使缩进更明显。"
# editor_config_behaviors_label: "Smart Behaviors"
# editor_config_behaviors_description: "Autocompletes brackets, braces, and quotes."
loading_ready: "载入完成!"
# tip_insert_positions: "Shift+Click a point on the map to insert it into the spell editor."
tip_insert_positions: "使用Shift+左键来插入拼写编辑器。"
tip_toggle_play: "用 Ctrl+P 来暂停或继续"
tip_scrub_shortcut: "用 Ctrl+[ 和 Ctrl+] 来倒退和快进."
tip_guide_exists: "点击页面上方的指南, 可以获得更多有用信息."
@ -285,15 +285,15 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
tip_no_try: "做. 或是不做. 这世上不存在'尝试'这种东西. - 尤达大师"
# tip_patience: "Patience you must have, young Padawan. - Yoda"
tip_documented_bug: "一个写在文档里的漏洞不算漏洞, 那是个功能."
tip_impossible: "It always seems impossible until it's done. - Nelson Mandela"
tip_impossible: "在事情未完成之前,一切都看似不可能. - 纳尔逊·曼德拉"
tip_talk_is_cheap: "多说无用, 亮出你的代码. - Linus Torvalds"
# tip_first_language: "The most disastrous thing that you can ever learn is your first programming language. - Alan Kay"
time_current: "现在:"
time_total: "最大:"
time_goto: "跳到:"
# infinite_loop_try_again: "Try Again"
# infinite_loop_reset_level: "Reset Level"
# infinite_loop_comment_out: "Comment Out My Code"
infinite_loop_try_again: "请重试"
infinite_loop_reset_level: "重置等级"
infinite_loop_comment_out: "为我的代码添加注释"
admin:
av_title: "管理员视图"
@ -361,7 +361,7 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
thang_search_title: "在这里搜索物品类型"
level_search_title: "在这里搜索关卡"
signup_to_create: "注册之后就可以创建一个新的关卡"
# read_only_warning2: "Note: you can't save any edits here, because you're not logged in."
read_only_warning2: "提示:你不能保存任何编辑,因为你没有登陆"
article:
edit_btn_preview: "预览"
@ -373,13 +373,13 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
body: "正文"
version: "版本"
commit_msg: "提交信息"
# version_history: "Version History"
version_history: "版本历史"
version_history_for: "版本历史: "
result: "结果"
results: "结果"
description: "描述"
or: ""
# subject: "Subject"
subject: "主题"
email: "邮件"
password: "密码"
message: "信息"
@ -395,7 +395,7 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
easy: "容易"
medium: "中等"
hard: "困难"
# player: "Player"
player: "玩家"
about:
who_is_codecombat: "什么是 CodeCombat?"
@ -538,7 +538,7 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
scribe_introduction_url_mozilla: "Mozilla 开发者社区"
# scribe_introduction_suf: " has built. If your idea of fun is articulating the concepts of programming in Markdown form, then this class might be for you."
# scribe_attribute_1: "Skill in words is pretty much all you need. Not only grammar and spelling, but able to convey complicated ideas to others."
# contact_us_url: "Contact us"
contact_us_url: "联系我们"
scribe_join_description: "介绍一下你自己, 比如你的编程经历和你喜欢写什么东西, 我们将从这里开始了解你!!"
more_about_scribe: "了解如何成为一名文书"
scribe_subscribe_desc: "通过电子邮件获得写作新文档的通知。"
@ -610,7 +610,7 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
summary_wins: " 胜利, "
summary_losses: " 失败"
rank_no_code: "没有新代码可供评分"
# rank_my_game: "Rank My Game!"
rank_my_game: "为我的游戏评分!"
rank_submitting: "正在提交..."
# rank_submitted: "Submitted for Ranking"
rank_failed: "评分失败"
@ -665,7 +665,7 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
gplus_friends: "G+ 朋友"
# gplus_friend_sessions: "G+ Friend Sessions"
leaderboard: "排行榜"
# user_schema: "User Schema"
# user_profile: "User Profile"
# patches: "Patches"
user_schema: "用户模式"
user_profile: "User Profile"
patches: "补丁"
# model: "Model"

View file

@ -255,7 +255,7 @@ module.exports = class ThangsTabView extends View
# @thangsTreema.deselectAll()
selectAddThang: (e) =>
return unless e? and $(e.target).closest('.editor-level-thangs-tab-view').length
return unless e? and $(e.target).closest('#editor-level-thangs-tab-view').length
if e then target = $(e.target) else target = @$el.find('.add-thangs-palette') # pretend to click on background if no event
return true if target.attr('id') is 'surface'
target = target.closest('.add-thang-palette-icon')

103
scripts/mail.coffee Normal file
View file

@ -0,0 +1,103 @@
do (setupLodash = this) ->
GLOBAL._ = require 'lodash'
_.str = require 'underscore.string'
_.mixin _.str.exports()
async = require 'async'
serverSetup = require '../server_setup'
sendwithus = require '../server/sendwithus'
User = require '../server/users/User.coffee'
Level = require '../server/levels/Level.coffee'
LevelSession = require '../server/levels/sessions/LevelSession.coffee'
alreadyEmailed = []
DEBUGGING = true
sendInitialRecruitingEmail = ->
leaderboards = [
{slug: 'brawlwood', team: 'humans', limit: 55, name: "Brawlwood", original: "52d97ecd32362bc86e004e87", majorVersion: 0}
{slug: 'brawlwood', team: 'ogres', limit: 40, name: "Brawlwood", original: "52d97ecd32362bc86e004e87", majorVersion: 0}
{slug: 'dungeon-arena', team: 'humans', limit: 200, name: "Dungeon Arena", original: "53173f76c269d400000543c2", majorVersion: 0}
{slug: 'dungeon-arena', team: 'ogres', limit: 150, name: "Dungeon Arena", original: "53173f76c269d400000543c2", majorVersion: 0}
]
async.waterfall [
(callback) -> async.map leaderboards, grabSessions, callback
(sessionLists, callback) -> async.map collapseSessions(sessionLists), grabUser, callback
(users, callback) -> async.map users, emailUser, callback
], (err, results) ->
return console.log "Error:", err if err
console.log "Looked at sending to #{results.length} users; sent to #{_.filter(results).length}."
console.log "Sent to: ['#{(user.email for user in results when user).join('\', \'')}']"
grabSessions = (levelInfo, callback) ->
queryParameters =
level: {original: levelInfo.original, majorVersion: levelInfo.majorVersion}
team: levelInfo.team
submitted: true
sortParameters = totalScore: -1
selectString = 'totalScore creator'
query = LevelSession
.find(queryParameters)
.limit(levelInfo.limit)
.sort(sortParameters)
.select(selectString)
.lean()
query.exec (err, sessions) ->
return callback err if err
for session, rank in sessions
session.levelInfo = levelInfo
session.rank = rank + 1
callback null, sessions
collapseSessions = (sessionLists) ->
userRanks = {}
for sessionList in sessionLists
for session in sessionList
ranks = userRanks[session.creator] ? []
ranks.push session
userRanks[session.creator] = _.sortBy ranks, 'rank'
topSessions = []
for userID, ranks of userRanks
topSessions.push ranks[0]
topSessions
grabUser = (session, callback) ->
findParameters = _id: session.creator
selectString = 'email emailSubscriptions name jobProfile'
query = User
.findOne(findParameters)
.select(selectString)
.lean()
query.exec (err, user) ->
return callback err if err
user.session = session
callback null, user
totalEmailsSent = 0
emailUser = (user, callback) ->
return callback null, false if user.emails?.recruiting?.enabled is false # TODO: later, obey also "announcements" when that's untangled
return callback null, false if user.email in alreadyEmailed
return callback null, false if DEBUGGING and (totalEmailsSent > 1 or Math.random() > 0.1)
++totalEmailsSent
name = if user.firstName and user.lastName then "#{user.firstName}" else user.name
name = "Wizard" if not name or name is "Anoner"
team = user.session.levelInfo.team
team = team.substr(0, team.length - 1)
context =
email_id: sendwithus.templates.one_time_recruiting_email
recipient:
address: if DEBUGGING then 'nick@codecombat.com' else user.email
name: name
email_data:
name: name
level_name: user.session.levelInfo.name
place: "##{user.session.rank}" # like "#31"
level_race: team
sendwithus.api.send context, (err, result) ->
return callback err if err
callback null, user
serverSetup.connectToDatabase()
sendInitialRecruitingEmail()

View file

@ -1,12 +1,10 @@
config = require '../server_config'
sendwithusAPI = require 'sendwithus'
swuAPIKey = config.mail.sendwithusAPIKey
queues = require './commons/queue'
module.exports.setupRoutes = (app) ->
return
debug = not config.isProduction
module.exports.api = new sendwithusAPI swuAPIKey, debug
if config.unittest
@ -16,3 +14,4 @@ module.exports.templates =
ladder_update_email: 'JzaZxf39A4cKMxpPZUfWy4'
patch_created: 'tem_xhxuNosLALsizTNojBjNcL'
change_made_notify_watcher: 'tem_7KVkfmv9SZETb25dtHbUtG'
one_time_recruiting_email: 'tem_mdFMgtcczHKYu94Jmq68j8'