2016-05-09 15:16:54 -07: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 10:26:34 -07:00
levelOriginal = level . get ( ' original ' )
2016-05-09 15:16:54 -07:00
for courseInstance in courseInstances
2016-05-25 10:26:03 -07:00
classroomID = courseInstance . get ( ' classroomID ' )
continue unless classroomID
classroom = classroomMap [ classroomID . toString ( ) ]
2016-05-09 15:16:54 -07:00
courseID = courseInstance . get ( ' courseID ' )
classroomCourse = _ . find ( classroom . get ( ' courses ' ) , (c) -> c . _id . equals ( courseID ) )
for courseLevel in classroomCourse . levels
2016-05-23 10:26:34 -07:00
if courseLevel . original . equals ( levelOriginal )
2016-05-09 15:16:54 -07: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 10:26:34 -07:00
lang = classroomWithLevel . get ( ' aceConfig ' ) ? . language
2016-05-09 15:16:54 -07: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 } ) )