{"action":"created","comment":{"url":"https://api.github.com/repos/codecombat/codecombat/pulls/comments/89171766","pull_request_review_id":9720271,"id":89171766,"diff_hunk":"@@ -44,13 +45,74 @@ ClassroomSchema.pre('save', (next) ->\n     next()\n )\n \n-\n ClassroomSchema.methods.isOwner = (userID) ->\n   return userID.equals(@get('ownerID'))\n \n ClassroomSchema.methods.isMember = (userID) ->\n   return _.any @get('members') or [], (memberID) -> userID.equals(memberID)\n \n+ClassroomSchema.methods.generateCoursesData = co.wrap (isAdmin=false) ->\n+  # Helper function for generating the latest version of courses\n+  query = {}\n+  query = {releasePhase: 'released'} unless isAdmin\n+  courses = yield Course.find(query)\n+  courses = Course.sortCourses courses\n+  campaigns = yield Campaign.find({_id: {$in: (course.get('campaignID') for course in courses)}})\n+  campaignMap = {}\n+  campaignMap[campaign.id] = campaign for campaign in campaigns\n+  classLanguage = @get('aceConfig')?.language\n+  coursesData = []\n+  for course in courses\n+    courseData = { _id: course._id, levels: [] }\n+    campaign = campaignMap[course.get('campaignID').toString()]\n+    levels = _.values(campaign.get('levels'))\n+    levels = _.sortBy(levels, 'campaignIndex')\n+    for level in levels\n+      continue if classLanguage and level.primerLanguage is classLanguage\n+      levelData = { original: mongoose.Types.ObjectId(level.original) }\n+      _.extend(levelData, _.pick(level, 'type', 'slug', 'name', 'practice', 'practiceThresholdMinutes', 'primerLanguage', 'shareable'))\n+      courseData.levels.push(levelData)\n+    coursesData.push(courseData)\n+  coursesData\n+\n+ClassroomSchema.methods.generateCourseData = co.wrap (courseId) ->\n+  # Helper function for generating the latest version of a course\n+  course = yield Course.findById(courseId)\n+  campaign = yield Campaign.findById({_id: course.get('campaignID')})\n+  classLanguage = @get('aceConfig')?.language\n+  courseData = { _id: course._id, levels: [] }\n+  levels = _.values(campaign.get('levels'))\n+  levels = _.sortBy(levels, 'campaignIndex')\n+  for level in levels\n+    continue if classLanguage and level.primerLanguage is classLanguage\n+    levelData = { original: mongoose.Types.ObjectId(level.original) }\n+    _.extend(levelData, _.pick(level, 'type', 'slug', 'name', 'practice', 'practiceThresholdMinutes', 'primerLanguage', 'shareable'))\n+    courseData.levels.push(levelData)\n+  courseData\n+\n+ClassroomSchema.methods.setUpdatedCourse = co.wrap (courseId) ->\n+  # Update existing or add missing course\n+  latestCourse = yield @generateCourseData(courseId)\n+  updatedCourses = _.clone(@get('courses') or [])\n+  existingIndex = _.findIndex(updatedCourses, (c) -> c._id.equals(courseId))\n+  if existingIndex >= 0\n+    updatedCourses.splice(existingIndex, 1, latestCourse)\n+  else\n+    # TODO: does this need to be inserted in order?\n+    updatedCourses.push(latestCourse)\n+  @set('courses', updatedCourses)\n+\n+ClassroomSchema.methods.setUpdatedCourses = co.wrap (isAdmin=false, addNewCoursesOnly=true) ->","path":"server/models/Classroom.coffee","position":75,"original_position":75,"commit_id":"0104605ff4b4461bb6eb08f1f3f0cdf01b354350","original_commit_id":"0104605ff4b4461bb6eb08f1f3f0cdf01b354350","user":{"login":"differentmatt","id":2965172,"avatar_url":"https://avatars.githubusercontent.com/u/2965172?v=3","gravatar_id":"","url":"https://api.github.com/users/differentmatt","html_url":"https://github.com/differentmatt","followers_url":"https://api.github.com/users/differentmatt/followers","following_url":"https://api.github.com/users/differentmatt/following{/other_user}","gists_url":"https://api.github.com/users/differentmatt/gists{/gist_id}","starred_url":"https://api.github.com/users/differentmatt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/differentmatt/subscriptions","organizations_url":"https://api.github.com/users/differentmatt/orgs","repos_url":"https://api.github.com/users/differentmatt/repos","events_url":"https://api.github.com/users/differentmatt/events{/privacy}","received_events_url":"https://api.github.com/users/differentmatt/received_events","type":"User","site_admin":false},"body":"New courses only is a subset of the updates we might make, so I like the naming as is.  Feel free to rename/refactor if you're in this code later though ;)","created_at":"2016-11-22T17:46:56Z","updated_at":"2016-11-22T17:46:56Z","html_url":"https://github.com/codecombat/codecombat/pull/4057#discussion_r89171766","pull_request_url":"https://api.github.com/repos/codecombat/codecombat/pulls/4057","_links":{"self":{"href":"https://api.github.com/repos/codecombat/codecombat/pulls/comments/89171766"},"html":{"href":"https://github.com/codecombat/codecombat/pull/4057#discussion_r89171766"},"pull_request":{"href":"https://api.github.com/repos/codecombat/codecombat/pulls/4057"}}},"pull_request":{"url":"https://api.github.com/repos/codecombat/codecombat/pulls/4057","id":94618527,"html_url":"https://github.com/codecombat/codecombat/pull/4057","diff_url":"https://github.com/codecombat/codecombat/pull/4057.diff","patch_url":"https://github.com/codecombat/codecombat/pull/4057.patch","issue_url":"https://api.github.com/repos/codecombat/codecombat/issues/4057","number":4057,"state":"open","locked":false,"title":"Classroom automatic updating","user":{"login":"differentmatt","id":2965172,"avatar_url":"https://avatars.githubusercontent.com/u/2965172?v=3","gravatar_id":"","url":"https://api.github.com/users/differentmatt","html_url":"https://github.com/differentmatt","followers_url":"https://api.github.com/users/differentmatt/followers","following_url":"https://api.github.com/users/differentmatt/following{/other_user}","gists_url":"https://api.github.com/users/differentmatt/gists{/gist_id}","starred_url":"https://api.github.com/users/differentmatt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/differentmatt/subscriptions","organizations_url":"https://api.github.com/users/differentmatt/orgs","repos_url":"https://api.github.com/users/differentmatt/repos","events_url":"https://api.github.com/users/differentmatt/events{/privacy}","received_events_url":"https://api.github.com/users/differentmatt/received_events","type":"User","site_admin":false},"body":"Still a few client-side tests to fix.","created_at":"2016-11-21T13:50:42Z","updated_at":"2016-11-22T17:46:56Z","closed_at":null,"merged_at":null,"merge_commit_sha":"bf9a691364c69a1f92572f70bfbc2e1f30bddb57","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/codecombat/codecombat/pulls/4057/commits","review_comments_url":"https://api.github.com/repos/codecombat/codecombat/pulls/4057/comments","review_comment_url":"https://api.github.com/repos/codecombat/codecombat/pulls/comments{/number}","comments_url":"https://api.github.com/repos/codecombat/codecombat/issues/4057/comments","statuses_url":"https://api.github.com/repos/codecombat/codecombat/statuses/0104605ff4b4461bb6eb08f1f3f0cdf01b354350","head":{"label":"codecombat:classroom-autoupdate","ref":"classroom-autoupdate","sha":"0104605ff4b4461bb6eb08f1f3f0cdf01b354350","user":{"login":"codecombat","id":5795842,"avatar_url":"https://avatars.githubusercontent.com/u/5795842?v=3","gravatar_id":"","url":"https://api.github.com/users/codecombat","html_url":"https://github.com/codecombat","followers_url":"https://api.github.com/users/codecombat/followers","following_url":"https://api.github.com/users/codecombat/following{/other_user}","gists_url":"https://api.github.com/users/codecombat/gists{/gist_id}","starred_url":"https://api.github.com/users/codecombat/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/codecombat/subscriptions","organizations_url":"https://api.github.com/users/codecombat/orgs","repos_url":"https://api.github.com/users/codecombat/repos","events_url":"https://api.github.com/users/codecombat/events{/privacy}","received_events_url":"https://api.github.com/users/codecombat/received_events","type":"Organization","site_admin":false},"repo":{"id":15193430,"name":"codecombat","full_name":"codecombat/codecombat","owner":{"login":"codecombat","id":5795842,"avatar_url":"https://avatars.githubusercontent.com/u/5795842?v=3","gravatar_id":"","url":"https://api.github.com/users/codecombat","html_url":"https://github.com/codecombat","followers_url":"https://api.github.com/users/codecombat/followers","following_url":"https://api.github.com/users/codecombat/following{/other_user}","gists_url":"https://api.github.com/users/codecombat/gists{/gist_id}","starred_url":"https://api.github.com/users/codecombat/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/codecombat/subscriptions","organizations_url":"https://api.github.com/users/codecombat/orgs","repos_url":"https://api.github.com/users/codecombat/repos","events_url":"https://api.github.com/users/codecombat/events{/privacy}","received_events_url":"https://api.github.com/users/codecombat/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/codecombat/codecombat","description":"Game for learning how to code.","fork":false,"url":"https://api.github.com/repos/codecombat/codecombat","forks_url":"https://api.github.com/repos/codecombat/codecombat/forks","keys_url":"https://api.github.com/repos/codecombat/codecombat/keys{/key_id}","collaborators_url":"https://api.github.com/repos/codecombat/codecombat/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/codecombat/codecombat/teams","hooks_url":"https://api.github.com/repos/codecombat/codecombat/hooks","issue_events_url":"https://api.github.com/repos/codecombat/codecombat/issues/events{/number}","events_url":"https://api.github.com/repos/codecombat/codecombat/events","assignees_url":"https://api.github.com/repos/codecombat/codecombat/assignees{/user}","branches_url":"https://api.github.com/repos/codecombat/codecombat/branches{/branch}","tags_url":"https://api.github.com/repos/codecombat/codecombat/tags","blobs_url":"https://api.github.com/repos/codecombat/codecombat/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/codecombat/codecombat/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/codecombat/codecombat/git/refs{/sha}","trees_url":"https://api.github.com/repos/codecombat/codecombat/git/trees{/sha}","statuses_url":"https://api.github.com/repos/codecombat/codecombat/statuses/{sha}","languages_url":"https://api.github.com/repos/codecombat/codecombat/languages","stargazers_url":"https://api.github.com/repos/codecombat/codecombat/stargazers","contributors_url":"https://api.github.com/repos/codecombat/codecombat/contributors","subscribers_url":"https://api.github.com/repos/codecombat/codecombat/subscribers","subscription_url":"https://api.github.com/repos/codecombat/codecombat/subscription","commits_url":"https://api.github.com/repos/codecombat/codecombat/commits{/sha}","git_commits_url":"https://api.github.com/repos/codecombat/codecombat/git/commits{/sha}","comments_url":"https://api.github.com/repos/codecombat/codecombat/comments{/number}","issue_comment_url":"https://api.github.com/repos/codecombat/codecombat/issues/comments{/number}","contents_url":"https://api.github.com/repos/codecombat/codecombat/contents/{+path}","compare_url":"https://api.github.com/repos/codecombat/codecombat/compare/{base}...{head}","merges_url":"https://api.github.com/repos/codecombat/codecombat/merges","archive_url":"https://api.github.com/repos/codecombat/codecombat/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/codecombat/codecombat/downloads","issues_url":"https://api.github.com/repos/codecombat/codecombat/issues{/number}","pulls_url":"https://api.github.com/repos/codecombat/codecombat/pulls{/number}","milestones_url":"https://api.github.com/repos/codecombat/codecombat/milestones{/number}","notifications_url":"https://api.github.com/repos/codecombat/codecombat/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/codecombat/codecombat/labels{/name}","releases_url":"https://api.github.com/repos/codecombat/codecombat/releases{/id}","deployments_url":"https://api.github.com/repos/codecombat/codecombat/deployments","created_at":"2013-12-14T21:47:37Z","updated_at":"2016-11-22T13:13:02Z","pushed_at":"2016-11-22T17:23:34Z","git_url":"git://github.com/codecombat/codecombat.git","ssh_url":"git@github.com:codecombat/codecombat.git","clone_url":"https://github.com/codecombat/codecombat.git","svn_url":"https://github.com/codecombat/codecombat","homepage":"http://codecombat.com","size":154814,"stargazers_count":5312,"watchers_count":5312,"language":"CoffeeScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2607,"mirror_url":null,"open_issues_count":321,"forks":2607,"open_issues":321,"watchers":5312,"default_branch":"master"}},"base":{"label":"codecombat:master","ref":"master","sha":"1b17799bef905328e7d4cf546294b9c96c4b5f55","user":{"login":"codecombat","id":5795842,"avatar_url":"https://avatars.githubusercontent.com/u/5795842?v=3","gravatar_id":"","url":"https://api.github.com/users/codecombat","html_url":"https://github.com/codecombat","followers_url":"https://api.github.com/users/codecombat/followers","following_url":"https://api.github.com/users/codecombat/following{/other_user}","gists_url":"https://api.github.com/users/codecombat/gists{/gist_id}","starred_url":"https://api.github.com/users/codecombat/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/codecombat/subscriptions","organizations_url":"https://api.github.com/users/codecombat/orgs","repos_url":"https://api.github.com/users/codecombat/repos","events_url":"https://api.github.com/users/codecombat/events{/privacy}","received_events_url":"https://api.github.com/users/codecombat/received_events","type":"Organization","site_admin":false},"repo":{"id":15193430,"name":"codecombat","full_name":"codecombat/codecombat","owner":{"login":"codecombat","id":5795842,"avatar_url":"https://avatars.githubusercontent.com/u/5795842?v=3","gravatar_id":"","url":"https://api.github.com/users/codecombat","html_url":"https://github.com/codecombat","followers_url":"https://api.github.com/users/codecombat/followers","following_url":"https://api.github.com/users/codecombat/following{/other_user}","gists_url":"https://api.github.com/users/codecombat/gists{/gist_id}","starred_url":"https://api.github.com/users/codecombat/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/codecombat/subscriptions","organizations_url":"https://api.github.com/users/codecombat/orgs","repos_url":"https://api.github.com/users/codecombat/repos","events_url":"https://api.github.com/users/codecombat/events{/privacy}","received_events_url":"https://api.github.com/users/codecombat/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/codecombat/codecombat","description":"Game for learning how to code.","fork":false,"url":"https://api.github.com/repos/codecombat/codecombat","forks_url":"https://api.github.com/repos/codecombat/codecombat/forks","keys_url":"https://api.github.com/repos/codecombat/codecombat/keys{/key_id}","collaborators_url":"https://api.github.com/repos/codecombat/codecombat/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/codecombat/codecombat/teams","hooks_url":"https://api.github.com/repos/codecombat/codecombat/hooks","issue_events_url":"https://api.github.com/repos/codecombat/codecombat/issues/events{/number}","events_url":"https://api.github.com/repos/codecombat/codecombat/events","assignees_url":"https://api.github.com/repos/codecombat/codecombat/assignees{/user}","branches_url":"https://api.github.com/repos/codecombat/codecombat/branches{/branch}","tags_url":"https://api.github.com/repos/codecombat/codecombat/tags","blobs_url":"https://api.github.com/repos/codecombat/codecombat/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/codecombat/codecombat/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/codecombat/codecombat/git/refs{/sha}","trees_url":"https://api.github.com/repos/codecombat/codecombat/git/trees{/sha}","statuses_url":"https://api.github.com/repos/codecombat/codecombat/statuses/{sha}","languages_url":"https://api.github.com/repos/codecombat/codecombat/languages","stargazers_url":"https://api.github.com/repos/codecombat/codecombat/stargazers","contributors_url":"https://api.github.com/repos/codecombat/codecombat/contributors","subscribers_url":"https://api.github.com/repos/codecombat/codecombat/subscribers","subscription_url":"https://api.github.com/repos/codecombat/codecombat/subscription","commits_url":"https://api.github.com/repos/codecombat/codecombat/commits{/sha}","git_commits_url":"https://api.github.com/repos/codecombat/codecombat/git/commits{/sha}","comments_url":"https://api.github.com/repos/codecombat/codecombat/comments{/number}","issue_comment_url":"https://api.github.com/repos/codecombat/codecombat/issues/comments{/number}","contents_url":"https://api.github.com/repos/codecombat/codecombat/contents/{+path}","compare_url":"https://api.github.com/repos/codecombat/codecombat/compare/{base}...{head}","merges_url":"https://api.github.com/repos/codecombat/codecombat/merges","archive_url":"https://api.github.com/repos/codecombat/codecombat/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/codecombat/codecombat/downloads","issues_url":"https://api.github.com/repos/codecombat/codecombat/issues{/number}","pulls_url":"https://api.github.com/repos/codecombat/codecombat/pulls{/number}","milestones_url":"https://api.github.com/repos/codecombat/codecombat/milestones{/number}","notifications_url":"https://api.github.com/repos/codecombat/codecombat/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/codecombat/codecombat/labels{/name}","releases_url":"https://api.github.com/repos/codecombat/codecombat/releases{/id}","deployments_url":"https://api.github.com/repos/codecombat/codecombat/deployments","created_at":"2013-12-14T21:47:37Z","updated_at":"2016-11-22T13:13:02Z","pushed_at":"2016-11-22T17:23:34Z","git_url":"git://github.com/codecombat/codecombat.git","ssh_url":"git@github.com:codecombat/codecombat.git","clone_url":"https://github.com/codecombat/codecombat.git","svn_url":"https://github.com/codecombat/codecombat","homepage":"http://codecombat.com","size":154814,"stargazers_count":5312,"watchers_count":5312,"language":"CoffeeScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2607,"mirror_url":null,"open_issues_count":321,"forks":2607,"open_issues":321,"watchers":5312,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/codecombat/codecombat/pulls/4057"},"html":{"href":"https://github.com/codecombat/codecombat/pull/4057"},"issue":{"href":"https://api.github.com/repos/codecombat/codecombat/issues/4057"},"comments":{"href":"https://api.github.com/repos/codecombat/codecombat/issues/4057/comments"},"review_comments":{"href":"https://api.github.com/repos/codecombat/codecombat/pulls/4057/comments"},"review_comment":{"href":"https://api.github.com/repos/codecombat/codecombat/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/codecombat/codecombat/pulls/4057/commits"},"statuses":{"href":"https://api.github.com/repos/codecombat/codecombat/statuses/0104605ff4b4461bb6eb08f1f3f0cdf01b354350"}}}}
{"actor":{"display_login":"differentmatt"}}