2016-05-09 18:16:54 -04:00
|
|
|
wrap = require 'co-express'
|
|
|
|
errors = require '../commons/errors'
|
|
|
|
Level = require '../models/Level'
|
|
|
|
LevelSession = require '../models/LevelSession'
|
|
|
|
CourseInstance = require '../models/CourseInstance'
|
|
|
|
Classroom = require '../models/Classroom'
|
|
|
|
Course = require '../models/Course'
|
|
|
|
database = require '../commons/database'
|
|
|
|
|
|
|
|
module.exports =
|
|
|
|
upsertSession: wrap (req, res) ->
|
|
|
|
level = yield database.getDocFromHandle(req, Level)
|
|
|
|
if not level
|
|
|
|
throw new errors.NotFound('Level not found.')
|
|
|
|
|
|
|
|
sessionQuery =
|
|
|
|
level:
|
|
|
|
original: level.get('original').toString()
|
|
|
|
majorVersion: level.get('version').major
|
|
|
|
creator: req.user.id
|
|
|
|
|
|
|
|
if req.query.team?
|
|
|
|
sessionQuery.team = req.query.team
|
|
|
|
|
|
|
|
session = yield LevelSession.findOne(sessionQuery)
|
|
|
|
if session
|
|
|
|
return res.send(session.toObject({req: req}))
|
|
|
|
|
|
|
|
attrs = sessionQuery
|
|
|
|
_.extend(attrs, {
|
|
|
|
state:
|
|
|
|
complete: false
|
|
|
|
scripts:
|
|
|
|
currentScript: null # will not save empty objects
|
|
|
|
permissions: [
|
|
|
|
{target: req.user.id, access: 'owner'}
|
|
|
|
{target: 'public', access: 'write'}
|
|
|
|
]
|
|
|
|
codeLanguage: req.user.get('aceConfig')?.language ? 'python'
|
|
|
|
})
|
|
|
|
|
|
|
|
if level.get('type') in ['course', 'course-ladder'] or req.query.course?
|
|
|
|
|
|
|
|
# Find the course and classroom that has assigned this level, verify access
|
|
|
|
courseInstances = yield CourseInstance.find({members: req.user._id})
|
|
|
|
classroomIDs = (courseInstance.get('classroomID') for courseInstance in courseInstances)
|
|
|
|
classroomIDs = _.filter _.uniq classroomIDs, false, (objectID='') -> objectID.toString()
|
|
|
|
classrooms = yield Classroom.find({ _id: { $in: classroomIDs }})
|
|
|
|
classroomWithLevel = null
|
|
|
|
courseID = null
|
|
|
|
classroomMap = {}
|
|
|
|
classroomMap[classroom.id] = classroom for classroom in classrooms
|
2016-05-23 13:26:34 -04:00
|
|
|
levelOriginal = level.get('original')
|
2016-05-09 18:16:54 -04:00
|
|
|
for courseInstance in courseInstances
|
2016-05-25 13:26:03 -04:00
|
|
|
classroomID = courseInstance.get('classroomID')
|
|
|
|
continue unless classroomID
|
|
|
|
classroom = classroomMap[classroomID.toString()]
|
2016-06-26 16:51:14 -04:00
|
|
|
continue unless classroom
|
2016-05-09 18:16:54 -04:00
|
|
|
courseID = courseInstance.get('courseID')
|
|
|
|
classroomCourse = _.find(classroom.get('courses'), (c) -> c._id.equals(courseID))
|
|
|
|
for courseLevel in classroomCourse.levels
|
2016-05-23 13:26:34 -04:00
|
|
|
if courseLevel.original.equals(levelOriginal)
|
2016-05-09 18:16:54 -04:00
|
|
|
classroomWithLevel = classroom
|
|
|
|
break
|
|
|
|
break if classroomWithLevel
|
|
|
|
|
|
|
|
unless classroomWithLevel
|
|
|
|
throw new errors.PaymentRequired('You must be in a course which includes this level to play it')
|
|
|
|
|
|
|
|
course = yield Course.findById(courseID).select('free')
|
|
|
|
unless course.get('free') or req.user.isEnrolled()
|
|
|
|
throw new errors.PaymentRequired('You must be enrolled to access this content')
|
|
|
|
|
2016-05-23 13:26:34 -04:00
|
|
|
lang = classroomWithLevel.get('aceConfig')?.language
|
2016-05-09 18:16:54 -04:00
|
|
|
attrs.codeLanguage = lang if lang
|
|
|
|
|
|
|
|
else
|
|
|
|
requiresSubscription = level.get('requiresSubscription') or (req.user.isOnPremiumServer() and level.get('campaign') and not (level.slug in ['dungeons-of-kithgard', 'gems-in-the-deep', 'shadow-guard', 'forgetful-gemsmith', 'signs-and-portents', 'true-names']))
|
|
|
|
canPlayAnyway = req.user.isPremium() or level.get 'adventurer'
|
|
|
|
if requiresSubscription and not canPlayAnyway
|
|
|
|
throw new errors.PaymentRequired('This level requires a subscription to play')
|
|
|
|
|
|
|
|
session = new LevelSession(attrs)
|
|
|
|
yield session.save()
|
|
|
|
res.send(session.toObject({req: req}))
|