Beispiel #1
0
    def test_generate_xml(self):
        """
        Generated post XML is valid
        """
        xml = generate_request_xml('message_identifier_id', 'operation',
                                   'lis_result_sourcedid', 'score')
        self.assertEqual(
            xml, """<?xml version='1.0' encoding='utf-8'?>
<imsx_POXEnvelopeRequest xmlns="http://www.imsglobal.org/services/ltiv1p1/xsd/\
imsoms_v1p0"><imsx_POXHeader><imsx_POXRequestHeaderInfo><imsx_version>V1.0\
</imsx_version><imsx_messageIdentifier>message_identifier_id\
</imsx_messageIdentifier></imsx_POXRequestHeaderInfo></imsx_POXHeader>\
<imsx_POXBody><operationRequest><resultRecord><sourcedGUID><sourcedId>\
lis_result_sourcedid</sourcedId></sourcedGUID><result><resultScore>\
<language>en</language><textString>score</textString></resultScore>\
</result></resultRecord></operationRequest></imsx_POXBody>\
</imsx_POXEnvelopeRequest>""")
        xml = generate_request_xml('message_identifier_id', 'operation',
                                   'lis_result_sourcedid', None)
        self.assertEqual(
            xml, """<?xml version='1.0' encoding='utf-8'?>
<imsx_POXEnvelopeRequest xmlns="http://www.imsglobal.org/services/ltiv1p1/xsd/\
imsoms_v1p0"><imsx_POXHeader><imsx_POXRequestHeaderInfo><imsx_version>V1.0\
</imsx_version><imsx_messageIdentifier>message_identifier_id\
</imsx_messageIdentifier></imsx_POXRequestHeaderInfo></imsx_POXHeader>\
<imsx_POXBody><operationRequest><resultRecord><sourcedGUID><sourcedId>\
lis_result_sourcedid</sourcedId></sourcedGUID></resultRecord></operationRequest>\
</imsx_POXBody></imsx_POXEnvelopeRequest>""")
Beispiel #2
0
    def test_generate_xml(self):
        """
        Generated post XML is valid
        """
        xml = generate_request_xml('message_identifier_id', 'operation',
                                   'lis_result_sourcedid', 'score')
        self.assertEqual(xml, """<?xml version='1.0' encoding='utf-8'?>
<imsx_POXEnvelopeRequest xmlns="http://www.imsglobal.org/services/ltiv1p1/xsd/\
imsoms_v1p0"><imsx_POXHeader><imsx_POXRequestHeaderInfo><imsx_version>V1.0\
</imsx_version><imsx_messageIdentifier>message_identifier_id\
</imsx_messageIdentifier></imsx_POXRequestHeaderInfo></imsx_POXHeader>\
<imsx_POXBody><operationRequest><resultRecord><sourcedGUID><sourcedId>\
lis_result_sourcedid</sourcedId></sourcedGUID><result><resultScore>\
<language>en</language><textString>score</textString></resultScore>\
</result></resultRecord></operationRequest></imsx_POXBody>\
</imsx_POXEnvelopeRequest>""")
        xml = generate_request_xml('message_identifier_id', 'operation',
                                   'lis_result_sourcedid', None)
        self.assertEqual(xml, """<?xml version='1.0' encoding='utf-8'?>
<imsx_POXEnvelopeRequest xmlns="http://www.imsglobal.org/services/ltiv1p1/xsd/\
imsoms_v1p0"><imsx_POXHeader><imsx_POXRequestHeaderInfo><imsx_version>V1.0\
</imsx_version><imsx_messageIdentifier>message_identifier_id\
</imsx_messageIdentifier></imsx_POXRequestHeaderInfo></imsx_POXHeader>\
<imsx_POXBody><operationRequest><resultRecord><sourcedGUID><sourcedId>\
lis_result_sourcedid</sourcedId></sourcedGUID></resultRecord></operationRequest>\
</imsx_POXBody></imsx_POXEnvelopeRequest>""")
Beispiel #3
0
    def test_post_response_valid_xml(self):
        """
        Test post grade with valid XML response
        """
        uri = 'https://localhost:8000/dev_stack'

        def request_callback(request, cburi, headers):
            # pylint: disable=unused-argument,
            """
            Mock expected response.
            """
            return 200, headers, self.expected_response

        httpretty.register_uri(httpretty.POST, uri, body=request_callback)
        consumers = {
            "__consumer_key__": {
                "secret": "__lti_secret__",
                "cert": TEST_CLIENT_CERT,
            },
        }
        body = generate_request_xml('message_identifier_id', 'operation',
                                    'lis_result_sourcedid', '1.0')
        ret = post_message(consumers, "__consumer_key__", uri, body)
        self.assertTrue(ret)

        ret = post_message2(consumers, "__consumer_key__", uri, body)
        self.assertTrue(ret)
Beispiel #4
0
    def test_post_response_valid_xml(self):
        """
        Test post grade with valid XML response
        """
        uri = 'https://localhost:8000/dev_stack'

        def request_callback(request, cburi, headers):
            # pylint: disable=unused-argument,
            """
            Mock expected response.
            """
            return 200, headers, self.expected_response

        httpretty.register_uri(httpretty.POST, uri, body=request_callback)
        consumers = {
            "__consumer_key__": {
                "secret": "__lti_secret__",
                "cert": TEST_CLIENT_CERT,
            },
        }
        body = generate_request_xml('message_identifier_id', 'operation',
                                    'lis_result_sourcedid', '1.0')
        ret = post_message(consumers, "__consumer_key__", uri, body)
        self.assertTrue(ret)

        ret = post_message2(consumers, "__consumer_key__", uri, body)
        self.assertTrue(ret)
Beispiel #5
0
    def post(self, request):
        """
        Post grade to LTI consumer using XML
        :param: score: 0 <= score <= 1. (Score MUST be between 0 and 1)
        :return: True if post successful and score valid
        :exception: LTIPostMessageException if call failed
        """
        try:
            lti_session = ltiSession.objects.get(
                id=request.data["ltisession"]["id"])
        except ltiSession.DoesNotExist:
            return Response(data={
                "error": "No LTI session exists for this ID"
            }, status=status.HTTP_400_BAD_REQUEST)
        consumer = lticonsumer.objects.get(id=lti_session.lti_consumer.id)
        schematic = StateSave.objects.get(save_id=request.data["schematic"])
        schematic.shared = True
        schematic.save()
        submission_data = {
            "project": consumer,
            "student": schematic.owner,
            "score": consumer.score,
            "ltisession": lti_session,
            "schematic": schematic
        }
        submission = Submission.objects.create(**submission_data)
        xml = generate_request_xml(
            message_identifier(), 'replaceResult',
            lti_session.lis_result_sourcedid, submission.score)
        msg = ""
        try:
            post = post_message(
                consumers(), lti_session.oauth_consumer_key,
                lti_session.lis_outcome_service_url, xml)
            if not post:
                msg = 'An error occurred while saving your score.\
                     Please try again.'
                raise LTIPostMessageException('Post grade failed')
            else:
                submission.lms_success = True
                submission.save()
                msg = 'Your score was submitted. Great job!'
                return Response(data={"message": msg},
                                status=status.HTTP_200_OK)

        except LTIException:
            submission.lms_success = False
            submission.save()
            return Response(data={"message": msg},
                            status=status.HTTP_400_BAD_REQUEST)
Beispiel #6
0
def send_grade_to_lms(request, attempt):
    """
    Sends the grade to lms using xml.
    :param request: django request object
    :param attempt: the Response object whose data is to be sent
    :return: None if quiz is not graded.
    """
    quiz = db.get_quiz(request)
    quiz_settings = db.get_quiz_settings(quiz)
    student = db.get_user(request)
    if not quiz_settings.graded:
        return None
    outcome_service_url = lti.get_outcome_service_url(request)
    result_sourcedid = lti.get_result_sourced_id(request)
    # if outcome_service_url or result_sourcedid is not available in this request, search the database
    # It is very unlikely (or maybe impossible) that outcome_service_url will not be in the request itself,
    # but there is no harm in searching database if we can't find it in the current request ( or is there? )
    if not (outcome_service_url or result_sourcedid):
        try:
            outcome_service_data = OutcomeServiceData.objects.get(user=student,
                                                                  quiz=quiz)
            outcome_service_url = outcome_service_data.lis_outcome_service_url
            result_sourcedid = outcome_service_data.lis_result_sourcedid
        except OutcomeServiceData.DoesNotExists:
            return  # cannot send the grade as outcome_service_url is not available

    consumer_key = lti.get_oauth_consumer_key(request)
    message_identifier_id = "iquiz_grade"  # TODO: Is this correct?
    operation = "replaceResult"
    score = get_grade(attempt, quiz)
    xml = generate_request_xml(message_identifier_id=message_identifier_id,
                               operation=operation,
                               lis_result_sourcedid=result_sourcedid,
                               score=score)

    if not post_message(CONSUMERS, consumer_key, outcome_service_url, xml):
        raise Exception("Some error occurred while sending grade to the lms.")

    # add the last successfully sent response id and time to the outcome_service_data
    outcome_service_data = OutcomeServiceData.objects.get_or_create(
        user=student, quiz=quiz)
    outcome_service_data.response = attempt
    outcome_service_data.outcome_send_time = datetime.datetime.utcnow()
Beispiel #7
0
    def get(self, request, submissionid, grade):
        user = request.user
        submitted_assignment = SubmittedAssignments.objects.get(
            id=submissionid)
        lis_result_sourcedid = submitted_assignment.lis_result_sourcedid
        if lis_result_sourcedid:
            xml = generate_request_xml('{:.0f}'.format(time.time()),
                                       'replaceResult', lis_result_sourcedid,
                                       grade)
            config = getattr(settings, 'PYLTI_CONFIG', dict())
            consumers = config.get('consumers', dict())
            print(consumers)
            print(submitted_assignment.consumer_key)
            if not post_message(consumers, submitted_assignment.consumer_key,
                                submitted_assignment.lis_outcome_service_url,
                                xml):

                # Something went wrong, display an error.
                # Is 500 the right thing to do here?
                print("Scoring not successful")
            else:
                print('Your score was submitted. Great job!')

        submitted_assignment_serializer = SubmittedAssignmentsSerializer(
            submitted_assignment,
            data={
                'grade': grade,
                'graded': True
            },
            partial=True)
        if submitted_assignment_serializer.is_valid():
            submitted_assignment_serializer.save()
        else:
            return Response({'error': submitted_assignment_serializer.errors},
                            status=500)
        return Response(
            {'submitted_assignment': submitted_assignment_serializer.data},
            status=200)