Merge branch 'master' into production

This commit is contained in:
phoenixeliot 2016-06-15 15:08:55 -07:00
commit b4f67a71e6
9 changed files with 69 additions and 28 deletions

View file

@ -69,8 +69,8 @@ module.exports = class CocoRouter extends Backbone.Router
'contribute/diplomat': go('contribute/DiplomatView')
'contribute/scribe': go('contribute/ScribeView')
'courses': go('courses/CoursesView', { studentsOnly: true })
'Courses': go('courses/CoursesView', { studentsOnly: true })
'courses': go('courses/CoursesView')
'Courses': go('courses/CoursesView')
'courses/students': redirect('/courses')
'courses/teachers': redirect('/teachers/classes')
'courses/purchase': redirect('/teachers/licenses')

View file

@ -364,8 +364,8 @@ module.exports = class World
endFrame = @frames.length
#console.log "... world serializing frames from", startFrame, "to", endFrame, "of", @totalFrames
[transferableObjects, nontransferableObjects] = [0, 0]
delete flag.processed for flag in @flagHistory
o = {totalFrames: @totalFrames, maxTotalFrames: @maxTotalFrames, frameRate: @frameRate, dt: @dt, victory: @victory, userCodeMap: {}, trackedProperties: {}, flagHistory: @flagHistory, difficulty: @difficulty, scores: @getScores(), randomSeed: @randomSeed, picoCTFFlag: @picoCTFFlag}
serializedFlagHistory = (_.omit(_.clone(flag), 'processed') for flag in @flagHistory)
o = {totalFrames: @totalFrames, maxTotalFrames: @maxTotalFrames, frameRate: @frameRate, dt: @dt, victory: @victory, userCodeMap: {}, trackedProperties: {}, flagHistory: serializedFlagHistory, difficulty: @difficulty, scores: @getScores(), randomSeed: @randomSeed, picoCTFFlag: @picoCTFFlag}
o.trackedProperties[prop] = @[prop] for prop in @trackedProperties or []
for thangID, methods of @userCodeMap

View file

@ -5,19 +5,21 @@ block page_nav
block content
if me.isAnonymous() || (!me.isTeacher() && !view.classrooms.size())
.access-restricted.container.text-center.m-y-3
h5(data-i18n='teacher.access_restricted')
p(data-i18n='teacher.teacher_account_required')
if me.isAnonymous()
.login-button.btn.btn-lg.btn-primary(data-i18n='login.log_in')
a.btn.btn-lg.btn-primary-alt(href="/teachers/signup" data-i18n='teacher.create_teacher_account')
else
a.btn.btn-lg.btn-primary(href="/teachers/update-account" data-i18n="teachers_quote.convert_account_title")
button#logout-button.btn.btn-lg.btn-primary-alt(data-i18n="login.log_out")
.container
.access-restricted.container.text-center.m-y-3
h5(data-i18n='teacher.access_restricted')
p(data-i18n='teacher.teacher_account_required')
if me.isAnonymous()
.login-button.btn.btn-lg.btn-primary(data-i18n='login.log_in')
a.btn.btn-lg.btn-primary-alt(href="/teachers/signup" data-i18n='teacher.create_teacher_account')
else
a.btn.btn-lg.btn-primary(href="/teachers/update-account" data-i18n="teachers_quote.convert_account_title")
button#logout-button.btn.btn-lg.btn-primary-alt(data-i18n="login.log_out")
.teacher-account-blurb.text-center.col-xs-6.col-xs-offset-3.m-y-3
h5(data-i18n='teacher.what_is_a_teacher_account')
p(data-i18n='teacher.teacher_account_explanation')
.container
.teacher-account-blurb.text-center.col-xs-6.col-xs-offset-3.m-y-3
h5(data-i18n='teacher.what_is_a_teacher_account')
p(data-i18n='teacher.teacher_account_explanation')
else
if !me.isTeacher()

View file

@ -17,6 +17,7 @@ block content
button#logout-button.btn.btn-lg.btn-primary-alt(data-i18n="login.log_out")
if me.isTeacher()
.teacher-account-blurb.text-center.col-xs-6.col-xs-offset-3.m-y-3
h5(data-i18n='teacher.what_is_a_teacher_account')
p(data-i18n='teacher.teacher_account_explanation')
.container
.teacher-account-blurb.text-center.col-xs-6.col-xs-offset-3.m-y-3
h5(data-i18n='teacher.what_is_a_teacher_account')
p(data-i18n='teacher.teacher_account_explanation')

View file

@ -15,9 +15,10 @@ block content
button.btn.btn-lg.btn-primary.update-teacher-btn(data-event-action="Teachers Classes Convert Teacher Account", data-i18n="teachers_quote.convert_account_title")
button#logout-button.btn.btn-lg.btn-primary-alt(data-i18n="login.log_out")
.teacher-account-blurb.text-center.col-xs-6.col-xs-offset-3.m-y-3
h5(data-i18n='teacher.what_is_a_teacher_account')
p(data-i18n='teacher.teacher_account_explanation')
.container
.teacher-account-blurb.text-center.col-xs-6.col-xs-offset-3.m-y-3
h5(data-i18n='teacher.what_is_a_teacher_account')
p(data-i18n='teacher.teacher_account_explanation')
else
if !me.isTeacher()

View file

@ -14,6 +14,7 @@ block content
a.btn.btn-lg.btn-primary(href="/teachers/update-account" data-i18n="teachers_quote.convert_account_title")
button#logout-button.btn.btn-lg.btn-primary-alt(data-i18n="login.log_out")
.teacher-account-blurb.text-center.col-xs-6.col-xs-offset-3.m-y-3
h5(data-i18n='teacher.what_is_a_teacher_account')
p(data-i18n='teacher.teacher_account_explanation')
.container
.teacher-account-blurb.text-center.col-xs-6.col-xs-offset-3.m-y-3
h5(data-i18n='teacher.what_is_a_teacher_account')
p(data-i18n='teacher.teacher_account_explanation')

View file

@ -40,7 +40,7 @@ module.exports = class CoursesView extends RootView
@courseInstances = new CocoCollection([], { url: "/db/user/#{me.id}/course_instances", model: CourseInstance})
@courseInstances.comparator = (ci) -> return ci.get('classroomID') + ci.get('courseID')
@listenToOnce @courseInstances, 'sync', @onCourseInstancesLoaded
@supermodel.loadCollection(@courseInstances)
@supermodel.loadCollection(@courseInstances, { cache: false })
@classrooms = new CocoCollection([], { url: "/db/classroom", model: Classroom })
@supermodel.loadCollection(@classrooms, { data: {memberID: me.id}, cache: false })
@ownedClassrooms = new Classrooms()
@ -59,6 +59,11 @@ module.exports = class CoursesView extends RootView
@listenTo @hero, 'all', ->
@render()
window.tracker?.trackEvent 'Students Loaded', category: 'Students', ['Mixpanel']
afterInsert: ->
super()
unless me.isStudent() or (@classCodeQueryVar and not me.isTeacher())
@onClassLoadError()
onCourseInstancesLoaded: ->
map = {}
@ -135,12 +140,21 @@ module.exports = class CoursesView extends RootView
else
modal = new JoinClassModal({ @classCode })
@openModalView modal
@listenTo modal, 'error', @onClassLoadError
@listenTo modal, 'join:success', @onJoinClassroomSuccess
@listenTo modal, 'join:error', @onJoinClassroomError
@listenToOnce modal, 'hidden', ->
unless me.isStudent()
@onClassLoadError()
@listenTo modal, 'hidden', ->
@state = null
@renderSelectors '#join-class-form'
# Super hacky way to patch users being able to join class while hiding /courses from others
onClassLoadError: ->
_.defer ->
application.router.routeDirectly('courses/RestrictedToStudentsView')
onJoinClassroomError: (classroom, jqxhr, options) ->
@state = null
if jqxhr.status is 422

View file

@ -16,6 +16,8 @@ module.exports = class JoinClassModal extends ModalView
jqxhr = @supermodel.trackRequest @classroom.fetchByCode(@classCode)
unless me.get('emailVerified')
@supermodel.trackRequest $.post("/db/user/#{me.id}/request-verify-email")
@listenTo @classroom, 'error', ->
@trigger('error')
@listenTo @classroom, 'sync', ->
@render
@listenTo @classroom, 'join:success', ->

View file

@ -57,7 +57,20 @@ const emailDelayMinutes = 27;
const scriptStartTime = new Date();
const closeIoApiKey = process.argv[2];
// Automatic mails sent as API owners, first key assumed to be primary and gets 50% of the leads
const closeIoMailApiKeys = [process.argv[3], process.argv[3], process.argv[4], process.argv[5]];
const closeIoMailApiKeys = [
{
apiKey: process.argv[3],
weight: .7
},
{
apiKey: process.argv[4],
weight: .25
},
{
apiKey: process.argv[5],
weight: .05
},
];
const closeIoEuMailApiKey = process.argv[6];
const intercomAppIdApiKey = process.argv[7];
const intercomAppId = intercomAppIdApiKey.split(':')[0];
@ -238,7 +251,14 @@ function isUSSchoolStatus(status) {
function getEmailApiKey(leadStatus) {
if (leadStatus === defaultEuLeadStatus) return closeIoEuMailApiKey;
if (closeIoMailApiKeys.length < 0) return;
return closeIoMailApiKeys[Math.floor(Math.random() * closeIoMailApiKeys.length)];
const weightedList = [];
for (let closeIoMailApiKey of closeIoMailApiKeys) {
const multiples = closeIoMailApiKey.weight * 100;
for (let i = 0; i < multiples; i++) {
weightedList.push(closeIoMailApiKey.apiKey);
}
}
return weightedList[Math.floor(Math.random() * weightedList.length)];
}
function getRandomEmailTemplate(templates) {