def send_to_grader(self, submission, system):
        """
        Send a given submission to the grader, via the xqueue
        @param submission: The student submission to send to the grader
        @param system: Modulesystem
        @return: Boolean true (not useful right now)
        """

        # Prepare xqueue request
        #------------------------------------------------------------

        xqueue = system.get('xqueue')
        if xqueue is None:
            return False
        qinterface = xqueue['interface']
        qtime = datetime.strftime(datetime.now(), xqueue_interface.dateformat)

        anonymous_student_id = system.anonymous_student_id

        # Generate header
        queuekey = xqueue_interface.make_hashkey(str(system.seed) + qtime +
                                                 anonymous_student_id +
                                                 str(len(self.child_history)))

        xheader = xqueue_interface.make_xheader(
            lms_callback_url=xqueue['construct_callback'](),
            lms_key=queuekey,
            queue_name=self.queue_name
        )

        contents = self.payload.copy()

        # Metadata related to the student submission revealed to the external
        # grader
        student_info = {
            'anonymous_student_id': anonymous_student_id,
            'submission_time': qtime,
        }

        # Update contents with student response and student info
        contents.update({
            'student_info': json.dumps(student_info),
            'student_response': submission,
            'max_score': self.max_score(),
        })

        # Submit request. When successful, 'msg' is the prior length of the
        # queue
        qinterface.send_to_queue(
            header=xheader,
            body=json.dumps(contents)
        )

        # State associated with the queueing request
        queuestate = {
            'key': queuekey,
            'time': qtime,
        }
        return True
    def send_to_grader(self, submission, system):
        """
        Send a given submission to the grader, via the xqueue
        @param submission: The student submission to send to the grader
        @param system: Modulesystem
        @return: Boolean true (not useful right now)
        """

        # Prepare xqueue request
        #------------------------------------------------------------

        xqueue = system.get('xqueue')
        if xqueue is None:
            return False
        qinterface = xqueue['interface']
        qtime = datetime.strftime(datetime.now(UTC), xqueue_interface.dateformat)

        anonymous_student_id = system.anonymous_student_id

        # Generate header
        queuekey = xqueue_interface.make_hashkey(str(system.seed) + qtime +
                                                 anonymous_student_id +
                                                 str(len(self.child_history)))

        xheader = xqueue_interface.make_xheader(
            lms_callback_url=xqueue['construct_callback'](),
            lms_key=queuekey,
            queue_name=self.queue_name
        )

        contents = self.payload.copy()

        # Metadata related to the student submission revealed to the external grader
        student_info = {
            'anonymous_student_id': anonymous_student_id,
            'submission_time': qtime,
        }

        # Update contents with student response and student info
        contents.update({
            'student_info': json.dumps(student_info),
            'student_response': submission,
            'max_score': self.max_score(),
        })

        # Submit request. When successful, 'msg' is the prior length of the queue
        qinterface.send_to_queue(
            header=xheader,
            body=json.dumps(contents)
        )

        # State associated with the queueing request
        queuestate = {
            'key': queuekey,
            'time': qtime,
        }
        return True
Esempio n. 3
0
    def _send_to_xqueue(self, contents, key):

        xheader = make_xheader(
            "https://{0}/update_certificate?{1}".format(settings.SITE_NAME, key), key, settings.CERT_QUEUE
        )

        (error, msg) = self.xqueue_interface.send_to_queue(header=xheader, body=json.dumps(contents))
        if error:
            logger.critical("Unable to add a request to the queue: {} {}".format(error, msg))
            raise Exception("Unable to send queue message")
Esempio n. 4
0
    def _send_to_xqueue(self, contents, key):

        xheader = make_xheader(
            'https://{0}/update_certificate?{1}'.format(
                settings.SITE_NAME, key), key, settings.CERT_QUEUE)

        (error, msg) = self.xqueue_interface.send_to_queue(
            header=xheader, body=json.dumps(contents))
        if error:
            logger.critical('Unable to add a request to the queue')
            raise Exception('Unable to send queue message')
Esempio n. 5
0
    def _send_to_xqueue(self, contents, key, task_identifier=None, callback_url_path='/update_certificate'):
        """Create a new task on the XQueue.

        Arguments:
            contents (dict): The contents of the XQueue task.
            key (str): An access key for the task.  This will be sent
                to the callback end-point once the task completes,
                so that we can validate that the sender is the same
                entity that received the task.

        Keyword Arguments:
            callback_url_path (str): The path of the callback URL.
                If not provided, use the default end-point for student-generated
                certificates.

        """
        callback_url = u'{protocol}://{base_url}{path}'.format(
            protocol=("https" if self.use_https else "http"),
            base_url=settings.SITE_NAME,
            path=callback_url_path
        )

        # Append the key to the URL
        # This is necessary because XQueue assumes that only one
        # submission is active for a particular URL.
        # If it receives a second submission with the same callback URL,
        # it "retires" any other submission with the same URL.
        # This was a hack that depended on the URL containing the user ID
        # and courseware location; an assumption that does not apply
        # to certificate generation.
        # XQueue also truncates the callback URL to 128 characters,
        # but since our key lengths are shorter than that, this should
        # not affect us.
        callback_url += "?key={key}".format(
            key=(
                task_identifier
                if task_identifier is not None
                else key
            )
        )

        xheader = make_xheader(callback_url, key, settings.CERT_QUEUE)

        (error, msg) = self.xqueue_interface.send_to_queue(
            header=xheader, body=json.dumps(contents))
        if error:
            exc = XQueueAddToQueueError(error, msg)
            LOGGER.critical(unicode(exc))
            raise exc
Esempio n. 6
0
    def _send_to_xqueue(self, contents, key):

        if self.use_https:
            proto = "https"
        else:
            proto = "http"

        xheader = make_xheader(
            '{0}://{1}/update_certificate?{2}'.format(
                proto, settings.SITE_NAME, key), key, settings.CERT_QUEUE)

        (error, msg) = self.xqueue_interface.send_to_queue(
            header=xheader, body=json.dumps(contents))
        if error:
            logger.critical('Unable to add a request to the queue: {} {}'.format(error, msg))
            raise Exception('Unable to send queue message')
Esempio n. 7
0
    def _send_to_xqueue(self, contents, key):
        """Create a new task on the XQueue. """

        if self.use_https:
            proto = "https"
        else:
            proto = "http"

        xheader = make_xheader(
            '{0}://{1}/update_certificate?{2}'.format(
                proto, settings.SITE_NAME, key), key, settings.CERT_QUEUE)

        (error, msg) = self.xqueue_interface.send_to_queue(
            header=xheader, body=json.dumps(contents))
        if error:
            LOGGER.critical(u'Unable to add a request to the queue: %s %s', unicode(error), msg)
            raise Exception('Unable to send queue message')
Esempio n. 8
0
    def _send_to_xqueue(self, contents, key):
        """Create a new task on the XQueue. """

        if self.use_https:
            proto = "https"
        else:
            proto = "http"

        xheader = make_xheader(
            '{0}://{1}/update_certificate?{2}'.format(proto,
                                                      settings.SITE_NAME, key),
            key, settings.CERT_QUEUE)

        (error,
         msg) = self.xqueue_interface.send_to_queue(header=xheader,
                                                    body=json.dumps(contents))
        if error:
            LOGGER.critical(u'Unable to add a request to the queue: %s %s',
                            unicode(error), msg)
            raise Exception('Unable to send queue message')
Esempio n. 9
0
    def send_to_grader(self, submission, system):
        """
        Send a given submission to the grader, via the xqueue
        @param submission: The student submission to send to the grader
        @param system: Modulesystem
        @return: Boolean true (not useful right now)
        """

        # Prepare xqueue request
        #------------------------------------------------------------

        xqueue = system.get('xqueue')
        if xqueue is None:
            return False
        qinterface = xqueue['interface']
        qtime = datetime.strftime(datetime.now(UTC), xqueue_interface.dateformat)

        anonymous_student_id = system.anonymous_student_id

        # Generate header
        queuekey = xqueue_interface.make_hashkey(str(system.seed) + qtime +
                                                 anonymous_student_id +
                                                 str(len(self.child_history)))

        xheader = xqueue_interface.make_xheader(
            lms_callback_url=xqueue['construct_callback'](),
            lms_key=queuekey,
            queue_name=self.queue_name
        )

        contents = self.payload.copy()

        # Metadata related to the student submission revealed to the external grader
        student_info = {
            'anonymous_student_id': anonymous_student_id,
            'submission_time': qtime,
        }

        # Update contents with student response and student info
        contents.update({
            'student_info': json.dumps(student_info),
            'student_response': submission,
            'max_score': self.max_score(),
        })

        # Submit request. When successful, 'msg' is the prior length of the queue
        error, error_message = qinterface.send_to_queue(
            header=xheader,
            body=json.dumps(contents)
        )

        # State associated with the queueing request
        queuestate = {
            'key': queuekey,
            'time': qtime,
        }
        _ = self.system.service(self, "i18n").ugettext
        success = True
        message = _("Successfully saved your submission.")
        if error:
            success = False
            # Translators: the `grader` refers to the grading service open response problems
            # are sent to, either to be machine-graded, peer-graded, or instructor-graded.
            message = _('Unable to submit your submission to the grader. Please try again later.')
            log.error("Unable to submit to grader. location: {0}, error_message: {1}".format(
                self.location_string, error_message
            ))

        return (success, message)
Esempio n. 10
0
    def message_post(self, data, system):
        """
        Handles a student message post (a reaction to the grade they received from an open ended grader type)
        Returns a boolean success/fail and an error message
        """

        event_info = dict()
        event_info['problem_id'] = self.location_string
        event_info['student_id'] = system.anonymous_student_id
        event_info['survey_responses'] = data
        _ = self.system.service(self, "i18n").ugettext

        survey_responses = event_info['survey_responses']
        for tag in ['feedback', 'submission_id', 'grader_id', 'score']:
            if tag not in survey_responses:
                # This is a student_facing_error
                return {
                    'success': False,
                    # Translators: 'tag' is one of 'feedback', 'submission_id',
                    # 'grader_id', or 'score'. They are categories that a student
                    # responds to when filling out a post-assessment survey
                    # of his or her grade from an openended problem.
                    'msg': _("Could not find needed tag {tag_name} in the "
                             "survey responses. Please try submitting "
                             "again.").format(tag_name=tag)
                }
        try:
            submission_id = int(survey_responses['submission_id'])
            grader_id = int(survey_responses['grader_id'])
            feedback = str(survey_responses['feedback'].encode('ascii', 'ignore'))
            score = int(survey_responses['score'])
        except:
            # This is a dev_facing_error
            error_message = (
                "Could not parse submission id, grader id, "
                "or feedback from message_post ajax call.  "
                "Here is the message data: {0}".format(survey_responses)
            )
            log.exception(error_message)
            # This is a student_facing_error
            return {
                'success': False,
                'msg': _(
                    "There was an error saving your feedback. Please "
                    "contact course staff."
                )
            }

        xqueue = system.get('xqueue')
        if xqueue is None:
            return {'success': False, 'msg': _("Couldn't submit feedback.")}
        qinterface = xqueue['interface']
        qtime = datetime.strftime(datetime.now(UTC), xqueue_interface.dateformat)
        anonymous_student_id = system.anonymous_student_id
        queuekey = xqueue_interface.make_hashkey(str(system.seed) + qtime +
                                                 anonymous_student_id +
                                                 str(len(self.child_history)))

        xheader = xqueue_interface.make_xheader(
            lms_callback_url=xqueue['construct_callback'](),
            lms_key=queuekey,
            queue_name=self.message_queue_name
        )

        student_info = {
            'anonymous_student_id': anonymous_student_id,
            'submission_time': qtime,
        }
        contents = {
            'feedback': feedback,
            'submission_id': submission_id,
            'grader_id': grader_id,
            'score': score,
            'student_info': json.dumps(student_info),
        }

        error, error_message = qinterface.send_to_queue(
            header=xheader,
            body=json.dumps(contents)
        )

        # Convert error to a success value
        success = True
        message = _("Successfully saved your feedback.")
        if error:
            success = False
            message = _("Unable to save your feedback. Please try again later.")
            log.error("Unable to send feedback to grader. location: {0}, error_message: {1}".format(
                self.location_string, error_message
            ))
        else:
            self.child_state = self.DONE

        # This is a student_facing_message
        return {'success': success, 'msg': message}
    def message_post(self, data, system):
        """
        Handles a student message post (a reaction to the grade they received from an open ended grader type)
        Returns a boolean success/fail and an error message
        """

        event_info = dict()
        event_info['problem_id'] = self.location_string
        event_info['student_id'] = system.anonymous_student_id
        event_info['survey_responses'] = data

        survey_responses = event_info['survey_responses']
        for tag in ['feedback', 'submission_id', 'grader_id', 'score']:
            if tag not in survey_responses:
                # This is a student_facing_error
                return {'success': False,
                        'msg': "Could not find needed tag {0} in the survey responses.  Please try submitting again.".format(
                            tag)}
        try:
            submission_id = int(survey_responses['submission_id'])
            grader_id = int(survey_responses['grader_id'])
            feedback = str(survey_responses['feedback'].encode('ascii', 'ignore'))
            score = int(survey_responses['score'])
        except:
            # This is a dev_facing_error
            error_message = (
                "Could not parse submission id, grader id, "
                "or feedback from message_post ajax call.  "
                "Here is the message data: {0}".format(survey_responses)
            )
            log.exception(error_message)
            # This is a student_facing_error
            return {'success': False, 'msg': "There was an error saving your feedback.  Please contact course staff."}

        xqueue = system.get('xqueue')
        if xqueue is None:
            return {'success': False, 'msg': "Couldn't submit feedback."}
        qinterface = xqueue['interface']
        qtime = datetime.strftime(datetime.now(UTC), xqueue_interface.dateformat)
        anonymous_student_id = system.anonymous_student_id
        queuekey = xqueue_interface.make_hashkey(str(system.seed) + qtime +
                                                 anonymous_student_id +
                                                 str(len(self.child_history)))

        xheader = xqueue_interface.make_xheader(
            lms_callback_url=xqueue['construct_callback'](),
            lms_key=queuekey,
            queue_name=self.message_queue_name
        )

        student_info = {
            'anonymous_student_id': anonymous_student_id,
            'submission_time': qtime,
        }
        contents = {
            'feedback': feedback,
            'submission_id': submission_id,
            'grader_id': grader_id,
            'score': score,
            'student_info': json.dumps(student_info),
        }

        (error, msg) = qinterface.send_to_queue(
            header=xheader,
            body=json.dumps(contents)
        )

        # Convert error to a success value
        success = True
        if error:
            success = False

        self.child_state = self.DONE

        # This is a student_facing_message
        return {'success': success, 'msg': "Successfully submitted your feedback."}
    def send_to_grader(self, submission, system):
        """
        Send a given submission to the grader, via the xqueue
        @param submission: The student submission to send to the grader
        @param system: Modulesystem
        @return: Boolean true (not useful right now)
        """

        # Prepare xqueue request
        #------------------------------------------------------------

        xqueue = system.get('xqueue')
        if xqueue is None:
            return False
        qinterface = xqueue['interface']
        qtime = datetime.strftime(datetime.now(UTC),
                                  xqueue_interface.dateformat)

        anonymous_student_id = system.anonymous_student_id

        # Generate header
        queuekey = xqueue_interface.make_hashkey(
            str(system.seed) + qtime + anonymous_student_id +
            str(len(self.child_history)))

        xheader = xqueue_interface.make_xheader(
            lms_callback_url=xqueue['construct_callback'](),
            lms_key=queuekey,
            queue_name=self.queue_name)

        contents = self.payload.copy()

        # Metadata related to the student submission revealed to the external grader
        student_info = {
            'anonymous_student_id': anonymous_student_id,
            'submission_time': qtime,
        }

        # Update contents with student response and student info
        contents.update({
            'student_info': json.dumps(student_info),
            'student_response': submission,
            'max_score': self.max_score(),
        })

        # Submit request. When successful, 'msg' is the prior length of the queue
        error, error_message = qinterface.send_to_queue(
            header=xheader, body=json.dumps(contents))

        # State associated with the queueing request
        queuestate = {
            'key': queuekey,
            'time': qtime,
        }
        _ = self.system.service(self, "i18n").ugettext
        success = True
        message = _("Successfully saved your submission.")
        if error:
            success = False
            # Translators: the `grader` refers to the grading service open response problems
            # are sent to, either to be machine-graded, peer-graded, or instructor-graded.
            message = _(
                'Unable to submit your submission to the grader. Please try again later.'
            )
            log.error(
                "Unable to submit to grader. location: {0}, error_message: {1}"
                .format(self.location_string, error_message))

        return (success, message)
    def message_post(self, data, system):
        """
        Handles a student message post (a reaction to the grade they received from an open ended grader type)
        Returns a boolean success/fail and an error message
        """

        event_info = dict()
        event_info['problem_id'] = self.location_string
        event_info['student_id'] = system.anonymous_student_id
        event_info['survey_responses'] = data
        _ = self.system.service(self, "i18n").ugettext

        survey_responses = event_info['survey_responses']
        for tag in ['feedback', 'submission_id', 'grader_id', 'score']:
            if tag not in survey_responses:
                # This is a student_facing_error
                return {
                    'success':
                    False,
                    # Translators: 'tag' is one of 'feedback', 'submission_id',
                    # 'grader_id', or 'score'. They are categories that a student
                    # responds to when filling out a post-assessment survey
                    # of his or her grade from an openended problem.
                    'msg':
                    _("Could not find needed tag {tag_name} in the "
                      "survey responses. Please try submitting "
                      "again.").format(tag_name=tag)
                }
        try:
            submission_id = int(survey_responses['submission_id'])
            grader_id = int(survey_responses['grader_id'])
            feedback = str(survey_responses['feedback'].encode(
                'ascii', 'ignore'))
            score = int(survey_responses['score'])
        except:
            # This is a dev_facing_error
            error_message = (
                "Could not parse submission id, grader id, "
                "or feedback from message_post ajax call.  "
                "Here is the message data: {0}".format(survey_responses))
            log.exception(error_message)
            # This is a student_facing_error
            return {
                'success':
                False,
                'msg':
                _("There was an error saving your feedback. Please "
                  "contact course staff.")
            }

        xqueue = system.get('xqueue')
        if xqueue is None:
            return {'success': False, 'msg': _("Couldn't submit feedback.")}
        qinterface = xqueue['interface']
        qtime = datetime.strftime(datetime.now(UTC),
                                  xqueue_interface.dateformat)
        anonymous_student_id = system.anonymous_student_id
        queuekey = xqueue_interface.make_hashkey(
            str(system.seed) + qtime + anonymous_student_id +
            str(len(self.child_history)))

        xheader = xqueue_interface.make_xheader(
            lms_callback_url=xqueue['construct_callback'](),
            lms_key=queuekey,
            queue_name=self.message_queue_name)

        student_info = {
            'anonymous_student_id': anonymous_student_id,
            'submission_time': qtime,
        }
        contents = {
            'feedback': feedback,
            'submission_id': submission_id,
            'grader_id': grader_id,
            'score': score,
            'student_info': json.dumps(student_info),
        }

        error, error_message = qinterface.send_to_queue(
            header=xheader, body=json.dumps(contents))

        # Convert error to a success value
        success = True
        message = _("Successfully saved your feedback.")
        if error:
            success = False
            message = _(
                "Unable to save your feedback. Please try again later.")
            log.error(
                "Unable to send feedback to grader. location: {0}, error_message: {1}"
                .format(self.location_string, error_message))
        else:
            self.child_state = self.DONE

        # This is a student_facing_message
        return {'success': success, 'msg': message}