errors = require '../commons/errors' log = require 'winston' wrap = require 'co-express' database = require '../commons/database' mongoose = require 'mongoose' Campaign = require '../models/Campaign' CourseInstance = require '../models/CourseInstance' Classroom = require '../models/Classroom' Course = require '../models/Course' User = require '../models/User' Level = require '../models/Level' parse = require '../commons/parse' module.exports = fetchLevelSolutions: wrap (req, res) -> unless req.user?.isTeacher() or req.user?.isAdmin() log.debug "courses.fetchLevelSolutions: level solutions only for teachers, (#{req.user?.id})" throw new errors.Forbidden() course = yield database.getDocFromHandle(req, Course) throw new errors.NotFound('Course not found.') unless course campaign = yield Campaign.findById course.get('campaignID') throw new errors.NotFound('Campaign not found.') unless campaign # TODO: why does campaign.get('levels') return opposite order from direct db query? sortedLevelIDs = _.keys campaign.get('levels') sortedLevelIDs.reverse() levelOriginals = (mongoose.Types.ObjectId(levelID) for levelID in sortedLevelIDs) query = { original: { $in: levelOriginals }, slug: { $exists: true }} select = {documentation: 1, intro: 1, name: 1, original: 1, practice: 1, slug: 1, thangs: 1, i18n: 1} levels = yield Level.find(query).select(select).lean() levels.sort((a, b) -> sortedLevelIDs.indexOf(a.original + '') - sortedLevelIDs.indexOf(b.original + '')) res.status(200).send(levels) fetchNextLevel: wrap (req, res) -> levelOriginal = req.params.levelOriginal if not database.isID(levelOriginal) throw new errors.UnprocessableEntity('Invalid level original ObjectId') course = yield database.getDocFromHandle(req, Course) if not course throw new errors.NotFound('Course not found.') campaign = yield Campaign.findById course.get('campaignID') if not campaign throw new errors.NotFound('Campaign not found.') levels = _.values(campaign.get('levels')) levels = _.sortBy(levels, 'campaignIndex') nextLevelOriginal = null foundLevelOriginal = false for level, index in levels if level.original.toString() is levelOriginal foundLevelOriginal = true nextLevelOriginal = levels[index+1]?.original break if not foundLevelOriginal throw new errors.NotFound('Level original ObjectId not found in that course') if not nextLevelOriginal return res.status(200).send({}) dbq = Level.findOne({original: mongoose.Types.ObjectId(nextLevelOriginal)}) dbq.sort({ 'version.major': -1, 'version.minor': -1 }) dbq.select(parse.getProjectFromReq(req)) level = yield dbq level = level.toObject({req: req}) res.status(200).send(level) get: (Model, options={}) -> wrap (req, res) -> query = {} if req.query.releasePhase query.releasePhase = req.query.releasePhase dbq = Model.find(query) dbq.select(parse.getProjectFromReq(req)) results = yield database.viewSearch(dbq, req) results = Course.sortCourses results res.send(results)