def handle_hint_feedback(self, args): """Handler for 'hint_feedback' args ---- * hintbox_id * feedback """ try: # read args hintbox_id = args['hintbox_id'] feedback = args['feedback'] # shorthand ss = self.student_session # extract assigned hint id and post the feedback assigned_hint_id = int(hintbox_id[-5:]) HintRestAPI.post_hint_feedback(ss.course_id, assigned_hint_id, feedback) logger.info("%s updated feedback for %s to %s"%( ss.student_id, hintbox_id, feedback)) except: logger.exception('Exception in hint_feedback handler')
def handle_hint_feedback(self, args): """Handler for 'hint_feedback' args ---- * hintbox_id * feedback """ try: # read args hintbox_id = args['hintbox_id'] feedback = args['feedback'] # shorthand ss = self.student_session # extract assigned hint id and post the feedback assigned_hint_id = int(hintbox_id[-5:]) HintRestAPI.post_hint_feedback(ss.course_id, assigned_hint_id, feedback) logger.info("%s updated feedback for %s to %s" % (ss.student_id, hintbox_id, feedback)) except: logger.exception('Exception in hint_feedback handler')
def _perform_checkanswer(self, boxname, value, callback=None): ss = self.student_session answer_status = {} # check problem answer if boxname.startswith('AnSwEr'): answer_status = HintRestAPI.checkanswer(ss.pg_file, ss.pg_seed, ss.psvn, boxname, value) # check hint answer elif boxname.startswith('AssignedHint'): # get hint pg assigned_hint_id = int(boxname[-5:]) hint = HintRestAPI.hint(ss.course_id, ss.set_id, ss.problem_id, assigned_hint_id) pg_file = base64.b64encode( hint['pg_header'] + '\n' + hint['pg_text'] + '\n' + hint['pg_footer']) # check using temporary boxname 'AnSwEr0001' answer_status = HintRestAPI.checkanswer(pg_file, ss.pg_seed, ss.psvn, 'AnSwEr0001', value) # set boxname to the hint boxname answer_status['boxname'] = boxname # unknown box name else: raise ValueError('Boxname must begin with AnSwEr or AssignedHint') # post-process the answer status if len(answer_status) > 0: # update the database ss.update_answer(boxname, answer_status) # send the status to client self.send_answer_status([answer_status,]) # notify the teachers for ts in TeacherSession.active_sessions: ts.notify_answer_update(ss) # done callback()
def hints(self): if self._hints is None: self._hints = HintRestAPI.get_user_problem_hints(self.student_id, self.course_id, self.set_id, self.problem_id) return self._hints
def answers(self): if self._answers is None: self._answers = HintRestAPI.get_realtime_answers(self.student_id, self.course_id, self.set_id, self.problem_id) return self._answers
def _perform_assign_hint(self, location, hint_id, hint_html_template, callback=None): # shorthand ts = self.teacher_session # get the student_id and other info if ts.student_hashkey is not None: (student_id, course_id, set_id, problem_id) = ts.student_hashkey # Call the rest api assigned_hintbox_id = HintRestAPI.assign_hint(student_id, course_id, set_id, problem_id, location, hint_id, hint_html_template) # Find the student session and update its view ss = StudentSession.get_student_session(student_id, course_id, set_id, problem_id) if ss is not None: ss.update_hints() # Update teacher's view ts.update_hints() # done callback()
def _perform_assign_hint(self, location, hint_id, hint_html_template, callback=None, student_data=None): # shorthand ts = self.teacher_session logger.info('In assign hint') # get the student_id and other info if student_data is not None: (student_id, course_id, set_id, problem_id) = student_data elif ts.student_hashkey is not None: logger.info('OK, we have a hashkey') (student_id, course_id, set_id, problem_id) = ts.student_hashkey if student_id: # Call the rest api assigned_hintbox_id = HintRestAPI.assign_hint( student_id, course_id, set_id, problem_id, location, hint_id, hint_html_template) # Find the student session and update its view ss = StudentSession.get_student_session(student_id, course_id, set_id, problem_id) if ss is not None: ss.update_hints() else: logger.warn('Couldnt update hints') # Update teacher's view ts.update_hints() else: logger.warn('Dont seem to have a student') # done callback()
def _perform_student_join(self, session_id, student_id, course_id, set_id, problem_id, callback=None): # create an instance of StudentSession self.student_session = StudentSession(session_id, student_id, course_id, set_id, problem_id, self) # shorthand ss = self.student_session # get PG file path if ss.pg_file is None: ss.pg_file = HintRestAPI.pg_path(ss.course_id, ss.set_id, ss.problem_id) # get problem seed if ss.pg_seed is None: ss.pg_seed = HintRestAPI.problem_seed(ss.student_id, ss.course_id, ss.set_id, ss.problem_id) # get problem seed if ss.psvn is None: ss.psvn = HintRestAPI.set_psvn(ss.student_id, ss.course_id, ss.set_id) # update the student session mapping. StudentSession.update_student_session(ss) # send assigned hints. self.send_hints(ss.hints) # send previously entered answers. self.send_answer_status(ss.current_answers) # notify the teachers that a student has joined. for ts in TeacherSession.active_sessions: ts.notify_student_join(ss) # done callback()
def _perform_checkanswer(self, boxname, value, callback=None): ss = self.student_session answer_status = {} # check problem answer if boxname.startswith('AnSwEr'): answer_status = HintRestAPI.checkanswer(ss.pg_file, ss.pg_seed, ss.psvn, boxname, value) # check hint answer elif boxname.startswith('AssignedHint'): # get hint pg assigned_hint_id = int(boxname[-5:]) hint = HintRestAPI.hint(ss.course_id, ss.set_id, ss.problem_id, assigned_hint_id) pg_file = base64.b64encode(hint['pg_header'] + '\n' + hint['pg_text'] + '\n' + hint['pg_footer']) # check using temporary boxname 'AnSwEr0001' answer_status = HintRestAPI.checkanswer(pg_file, ss.pg_seed, ss.psvn, 'AnSwEr0001', value) # set boxname to the hint boxname answer_status['boxname'] = boxname # unknown box name else: raise ValueError('Boxname must begin with AnSwEr or AssignedHint') # post-process the answer status if len(answer_status) > 0: # update the database ss.update_answer(boxname, answer_status) # send the status to client self.send_answer_status([ answer_status, ]) # notify the teachers for ts in TeacherSession.active_sessions: ts.notify_answer_update(ss) # done callback()
def _perform_run_filters(self, part_id, answer_string): ''' Runs all assigned filter functions on the given student's answer. If a filter returns True, render that hint and assign it to the student. If a filter returns PGML text, render that instead, and assign it to the hint. HintRestAPI.apply_hint_filters, HintRestAPI.render_html_assign_hint ''' hint = HintRestAPI.apply_filter_functions(self.student_id, self.course_id, self.set_id, self.problem_id, part_id, answer_string) if hint['hint_html'] == "": return hint hint['hint_html'] = HintRestAPI.render_html_assign_hint(self.student_id, self.course_id, self.set_id, self.problem_id, 0, 0, hint['hint_html']) HintRestAPI.assign_hint(self.student_id, self.course_id, self.set_id, self.problem_id, hint['location'], 0, hint['hint_html'], hint['assigned'], answer_string, hint['filter_name']) return hint
def _perform_run_filters(self, user_id, course, set_id, problem_id, part_id, answer_string, callback=None): ''' Runs all assigned filter functions on the given student's answer. If a filter returns True, render that hint and assign it to the student. If a filter returns PGML text, render that instead, and assign it to the hint. HintRestAPI.apply_hint_filters, HintRestAPI.render_html_assign_hint ''' return callback(HintRestAPI.apply_filter_functions(user_id, course, set_id, problem_id, part_id, answer_string))
def _perform_unassign_hint(self, location, hintbox_id, callback=None): # shorthand ts = self.teacher_session if ts.student_hashkey is not None: (student_id, course_id, set_id, problem_id) = ts.student_hashkey HintRestAPI.unassign_hint(course_id, hintbox_id) # Find the student session and update its view ss = StudentSession.get_student_session(student_id, course_id, set_id, problem_id) if ss is not None: ss.update_hints() # Update teacher's view ts.update_hints() # done callback()
def update_answer(self, boxname, answer_status): """Update an answer box """ # update current answer HintRestAPI.post_realtime_answer(self.student_id, self.course_id, self.set_id, self.problem_id, answer_status) # hint_ids = HintRestAPI.apply_hint_filters(self.student_id, # self.course_id, # self.set_id, # self.problem_id, # boxname) # if len(hint_ids) > 0: # self.update_hints() # invalidate internal cache self._answers = None # update summary in another thread Thread(target=self.update_summary).start()
# set up the root logger logger = logging.getLogger() logger.setLevel(logging.INFO) formatter = logging.Formatter('%(asctime)s - %(name)s - ' '%(levelname)s - %(message)s') log_filename = LOG_PATH + "/sockjs-%d.log"%args.port handler = logging.handlers.RotatingFileHandler(log_filename, maxBytes=2000000, backupCount=5) handler.setFormatter(formatter) logger.addHandler(handler) # Set the location of the ReSTful services HintRestAPI.setBaseUrl("%s:%d"%(REST_SERVER, args.rest_port)) # Create routers StudentRouter = sockjs.tornado.SockJSRouter(StudentSockJSHandler, '/student') TeacherRouter = sockjs.tornado.SockJSRouter(TeacherSockJSHandler, '/teacher') # Create Tornado application app = tornado.web.Application(StudentRouter.urls + TeacherRouter.urls) # Make Tornado app listen on the specific port app.listen(args.port, address=BIND_IP) logging.info(" [*] Listening on %s:%d"%(BIND_IP, args.port))
def hints(self): if self._hints is None: self._hints = HintRestAPI.get_user_problem_hints( self.student_id, self.course_id, self.set_id, self.problem_id) return self._hints
# set up the root logger logger = logging.getLogger() logger.setLevel(logging.INFO) formatter = logging.Formatter('%(asctime)s - %(name)s - ' '%(levelname)s - %(message)s') log_filename = LOG_PATH + "/sockjs-%d.log" % args.port handler = logging.handlers.RotatingFileHandler(log_filename, maxBytes=2000000, backupCount=5) handler.setFormatter(formatter) logger.addHandler(handler) # Set the location of the ReSTful services HintRestAPI.setBaseUrl("%s:%d" % (REST_SERVER, args.rest_port)) # Create routers StudentRouter = sockjs.tornado.SockJSRouter(StudentSockJSHandler, '/student') TeacherRouter = sockjs.tornado.SockJSRouter(TeacherSockJSHandler, '/teacher') DaemonRouter = sockjs.tornado.SockJSRouter(DaemonSockJSHandler, '/daemon') # Create Tornado application app = tornado.web.Application(StudentRouter.urls + TeacherRouter.urls + DaemonRouter.urls, debug=args.debug) # Make Tornado app listen on the specific port app.listen(args.port, address=BIND_IP)
def answers(self): if self._answers is None: self._answers = HintRestAPI.get_realtime_answers( self.student_id, self.course_id, self.set_id, self.problem_id) return self._answers