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')
Beispiel #2
0
        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()
Beispiel #7
0
    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()
Beispiel #9
0
    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()
Beispiel #10
0
    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_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
Beispiel #12
0
    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))
Beispiel #13
0
    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()
Beispiel #14
0
    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()
    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()
    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()
    # 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))
    
Beispiel #18
0
 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
Beispiel #19
0
    # 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)
Beispiel #20
0
 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