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/diplomat': go('contribute/DiplomatView')
'contribute/scribe': go('contribute/ScribeView') 'contribute/scribe': go('contribute/ScribeView')
'courses': go('courses/CoursesView', { studentsOnly: true }) 'courses': go('courses/CoursesView')
'Courses': go('courses/CoursesView', { studentsOnly: true }) 'Courses': go('courses/CoursesView')
'courses/students': redirect('/courses') 'courses/students': redirect('/courses')
'courses/teachers': redirect('/teachers/classes') 'courses/teachers': redirect('/teachers/classes')
'courses/purchase': redirect('/teachers/licenses') 'courses/purchase': redirect('/teachers/licenses')

View file

@ -364,8 +364,8 @@ module.exports = class World
endFrame = @frames.length endFrame = @frames.length
#console.log "... world serializing frames from", startFrame, "to", endFrame, "of", @totalFrames #console.log "... world serializing frames from", startFrame, "to", endFrame, "of", @totalFrames
[transferableObjects, nontransferableObjects] = [0, 0] [transferableObjects, nontransferableObjects] = [0, 0]
delete flag.processed for flag in @flagHistory serializedFlagHistory = (_.omit(_.clone(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} 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 [] o.trackedProperties[prop] = @[prop] for prop in @trackedProperties or []
for thangID, methods of @userCodeMap for thangID, methods of @userCodeMap

View file

@ -5,19 +5,21 @@ block page_nav
block content block content
if me.isAnonymous() || (!me.isTeacher() && !view.classrooms.size()) if me.isAnonymous() || (!me.isTeacher() && !view.classrooms.size())
.access-restricted.container.text-center.m-y-3 .container
h5(data-i18n='teacher.access_restricted') .access-restricted.container.text-center.m-y-3
p(data-i18n='teacher.teacher_account_required') h5(data-i18n='teacher.access_restricted')
if me.isAnonymous() p(data-i18n='teacher.teacher_account_required')
.login-button.btn.btn-lg.btn-primary(data-i18n='login.log_in') if me.isAnonymous()
a.btn.btn-lg.btn-primary-alt(href="/teachers/signup" data-i18n='teacher.create_teacher_account') .login-button.btn.btn-lg.btn-primary(data-i18n='login.log_in')
else a.btn.btn-lg.btn-primary-alt(href="/teachers/signup" data-i18n='teacher.create_teacher_account')
a.btn.btn-lg.btn-primary(href="/teachers/update-account" data-i18n="teachers_quote.convert_account_title") else
button#logout-button.btn.btn-lg.btn-primary-alt(data-i18n="login.log_out") 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 .container
h5(data-i18n='teacher.what_is_a_teacher_account') .teacher-account-blurb.text-center.col-xs-6.col-xs-offset-3.m-y-3
p(data-i18n='teacher.teacher_account_explanation') h5(data-i18n='teacher.what_is_a_teacher_account')
p(data-i18n='teacher.teacher_account_explanation')
else else
if !me.isTeacher() 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") button#logout-button.btn.btn-lg.btn-primary-alt(data-i18n="login.log_out")
if me.isTeacher() if me.isTeacher()
.teacher-account-blurb.text-center.col-xs-6.col-xs-offset-3.m-y-3 .container
h5(data-i18n='teacher.what_is_a_teacher_account') .teacher-account-blurb.text-center.col-xs-6.col-xs-offset-3.m-y-3
p(data-i18n='teacher.teacher_account_explanation') 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.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") 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 .container
h5(data-i18n='teacher.what_is_a_teacher_account') .teacher-account-blurb.text-center.col-xs-6.col-xs-offset-3.m-y-3
p(data-i18n='teacher.teacher_account_explanation') h5(data-i18n='teacher.what_is_a_teacher_account')
p(data-i18n='teacher.teacher_account_explanation')
else else
if !me.isTeacher() 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") 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") 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 .container
h5(data-i18n='teacher.what_is_a_teacher_account') .teacher-account-blurb.text-center.col-xs-6.col-xs-offset-3.m-y-3
p(data-i18n='teacher.teacher_account_explanation') 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 = new CocoCollection([], { url: "/db/user/#{me.id}/course_instances", model: CourseInstance})
@courseInstances.comparator = (ci) -> return ci.get('classroomID') + ci.get('courseID') @courseInstances.comparator = (ci) -> return ci.get('classroomID') + ci.get('courseID')
@listenToOnce @courseInstances, 'sync', @onCourseInstancesLoaded @listenToOnce @courseInstances, 'sync', @onCourseInstancesLoaded
@supermodel.loadCollection(@courseInstances) @supermodel.loadCollection(@courseInstances, { cache: false })
@classrooms = new CocoCollection([], { url: "/db/classroom", model: Classroom }) @classrooms = new CocoCollection([], { url: "/db/classroom", model: Classroom })
@supermodel.loadCollection(@classrooms, { data: {memberID: me.id}, cache: false }) @supermodel.loadCollection(@classrooms, { data: {memberID: me.id}, cache: false })
@ownedClassrooms = new Classrooms() @ownedClassrooms = new Classrooms()
@ -59,6 +59,11 @@ module.exports = class CoursesView extends RootView
@listenTo @hero, 'all', -> @listenTo @hero, 'all', ->
@render() @render()
window.tracker?.trackEvent 'Students Loaded', category: 'Students', ['Mixpanel'] window.tracker?.trackEvent 'Students Loaded', category: 'Students', ['Mixpanel']
afterInsert: ->
super()
unless me.isStudent() or (@classCodeQueryVar and not me.isTeacher())
@onClassLoadError()
onCourseInstancesLoaded: -> onCourseInstancesLoaded: ->
map = {} map = {}
@ -135,12 +140,21 @@ module.exports = class CoursesView extends RootView
else else
modal = new JoinClassModal({ @classCode }) modal = new JoinClassModal({ @classCode })
@openModalView modal @openModalView modal
@listenTo modal, 'error', @onClassLoadError
@listenTo modal, 'join:success', @onJoinClassroomSuccess @listenTo modal, 'join:success', @onJoinClassroomSuccess
@listenTo modal, 'join:error', @onJoinClassroomError @listenTo modal, 'join:error', @onJoinClassroomError
@listenToOnce modal, 'hidden', ->
unless me.isStudent()
@onClassLoadError()
@listenTo modal, 'hidden', -> @listenTo modal, 'hidden', ->
@state = null @state = null
@renderSelectors '#join-class-form' @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) -> onJoinClassroomError: (classroom, jqxhr, options) ->
@state = null @state = null
if jqxhr.status is 422 if jqxhr.status is 422

View file

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

View file

@ -57,7 +57,20 @@ const emailDelayMinutes = 27;
const scriptStartTime = new Date(); const scriptStartTime = new Date();
const closeIoApiKey = process.argv[2]; const closeIoApiKey = process.argv[2];
// Automatic mails sent as API owners, first key assumed to be primary and gets 50% of the leads // 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 closeIoEuMailApiKey = process.argv[6];
const intercomAppIdApiKey = process.argv[7]; const intercomAppIdApiKey = process.argv[7];
const intercomAppId = intercomAppIdApiKey.split(':')[0]; const intercomAppId = intercomAppIdApiKey.split(':')[0];
@ -238,7 +251,14 @@ function isUSSchoolStatus(status) {
function getEmailApiKey(leadStatus) { function getEmailApiKey(leadStatus) {
if (leadStatus === defaultEuLeadStatus) return closeIoEuMailApiKey; if (leadStatus === defaultEuLeadStatus) return closeIoEuMailApiKey;
if (closeIoMailApiKeys.length < 0) return; 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) { function getRandomEmailTemplate(templates) {