コード例 #1
0
ファイル: tasks.py プロジェクト: kureck/edx-platform
def _has_database_updated_with_new_score(
    user_id,
    scored_block_usage_key,
    expected_modified_time,
    score_deleted,
):
    """
    Returns whether the database has been updated with the
    expected new score values for the given problem and user.
    """
    score = get_score(user_id, scored_block_usage_key)

    if score is None:
        # score should be None only if it was deleted.
        # Otherwise, it hasn't yet been saved.
        return score_deleted
    elif score.module_type == 'openassessment':
        anon_id = anonymous_id_for_user(User.objects.get(id=user_id),
                                        scored_block_usage_key.course_key)
        course_id = unicode(scored_block_usage_key.course_key)
        item_id = unicode(scored_block_usage_key)

        api_score = sub_api.get_score({
            "student_id": anon_id,
            "course_id": course_id,
            "item_id": item_id,
            "item_type": "openassessment"
        })
        reported_modified_time = api_score.created_at
    else:
        reported_modified_time = score.modified

    return reported_modified_time >= expected_modified_time
コード例 #2
0
ファイル: tasks.py プロジェクト: CredoReference/edx-platform
def _has_database_updated_with_new_score(
        user_id, scored_block_usage_key, expected_modified_time, score_deleted,
):
    """
    Returns whether the database has been updated with the
    expected new score values for the given problem and user.
    """
    score = get_score(user_id, scored_block_usage_key)

    if score is None:
        # score should be None only if it was deleted.
        # Otherwise, it hasn't yet been saved.
        return score_deleted
    elif score.module_type == 'openassessment':
        anon_id = anonymous_id_for_user(User.objects.get(id=user_id), scored_block_usage_key.course_key)
        course_id = unicode(scored_block_usage_key.course_key)
        item_id = unicode(scored_block_usage_key)

        api_score = sub_api.get_score(
            {
                "student_id": anon_id,
                "course_id": course_id,
                "item_id": item_id,
                "item_type": "openassessment"
            }
        )
        reported_modified_time = api_score.created_at
    else:
        reported_modified_time = score.modified

    return reported_modified_time >= expected_modified_time
コード例 #3
0
ファイル: handlers.py プロジェクト: CUCWD/edx-platform
def score_published_handler(sender, block, user, raw_earned, raw_possible, only_if_higher, **kwargs):  # pylint: disable=unused-argument
    """
    Handles whenever a block's score is published.
    Returns whether the score was actually updated.
    """
    update_score = True
    if only_if_higher:
        previous_score = get_score(user.id, block.location)

        if previous_score is not None:
            prev_raw_earned, prev_raw_possible = previous_score  # pylint: disable=unpacking-non-sequence

            if not is_score_higher(prev_raw_earned, prev_raw_possible, raw_earned, raw_possible):
                update_score = False
                log.warning(
                    u"Grades: Rescore is not higher than previous: "
                    u"user: {}, block: {}, previous: {}/{}, new: {}/{} ".format(
                        user, block.location, prev_raw_earned, prev_raw_possible, raw_earned, raw_possible,
                    )
                )

    if update_score:
        set_score(user.id, block.location, raw_earned, raw_possible)
        PROBLEM_SCORE_CHANGED.send(
            sender=None,
            points_earned=raw_earned,
            points_possible=raw_possible,
            user_id=user.id,
            course_id=unicode(block.location.course_key),
            usage_id=unicode(block.location),
            only_if_higher=only_if_higher,
        )
    return update_score
コード例 #4
0
ファイル: handlers.py プロジェクト: gopinath81/vmss
def score_published_handler(sender, block, user, raw_earned, raw_possible, only_if_higher, **kwargs):  # pylint: disable=unused-argument
    """
    Handles whenever a block's score is published.
    Returns whether the score was actually updated.
    """
    update_score = True
    if only_if_higher:
        previous_score = get_score(user.id, block.location)

        if previous_score is not None:
            prev_raw_earned, prev_raw_possible = (previous_score.grade, previous_score.max_grade)

            if not is_score_higher(prev_raw_earned, prev_raw_possible, raw_earned, raw_possible):
                update_score = False
                log.warning(
                    u"Grades: Rescore is not higher than previous: "
                    u"user: {}, block: {}, previous: {}/{}, new: {}/{} ".format(
                        user, block.location, prev_raw_earned, prev_raw_possible, raw_earned, raw_possible,
                    )
                )

    if update_score:
        score_modified_time = set_score(user.id, block.location, raw_earned, raw_possible)
        PROBLEM_RAW_SCORE_CHANGED.send(
            sender=None,
            raw_earned=raw_earned,
            raw_possible=raw_possible,
            weight=getattr(block, 'weight', None),
            user_id=user.id,
            course_id=unicode(block.location.course_key),
            usage_id=unicode(block.location),
            only_if_higher=only_if_higher,
            modified=score_modified_time,
        )
    return update_score
コード例 #5
0
ファイル: tasks.py プロジェクト: gunjanmodi/edx-platform
def recalculate_subsection_grade(user_id, course_id, usage_id, only_if_higher, raw_earned, raw_possible):
    """
    Updates a saved subsection grade.
    This method expects the following parameters:
        - user_id: serialized id of applicable User object
        - course_id: Unicode string identifying the course
        - usage_id: Unicode string identifying the course block
        - only_if_higher: boolean indicating whether grades should
        be updated only if the new raw_earned is higher than the previous
        value.
        - raw_earned: the raw points the learner earned on the problem that
        triggered the update
        - raw_possible: the max raw points the leaner could have earned
        on the problem
    """
    course_key = CourseLocator.from_string(course_id)
    if not PersistentGradesEnabledFlag.feature_enabled(course_key):
        return

    scored_block_usage_key = UsageKey.from_string(usage_id).replace(course_key=course_key)
    score = get_score(user_id, scored_block_usage_key)

    # If the score is None, it has not been saved at all yet
    # and we need to retry until it has been saved.
    if score is None:
        raise _retry_recalculate_subsection_grade(
            user_id, course_id, usage_id, only_if_higher, raw_earned, raw_possible,
        )
    else:
        module_raw_earned, module_raw_possible = score  # pylint: disable=unpacking-non-sequence

    # Validate that the retrieved scores match the scores when the task was created.
    # This race condition occurs if the transaction in the task creator's process hasn't
    # committed before the task initiates in the worker process.
    grades_match = module_raw_earned == raw_earned and module_raw_possible == raw_possible

    # We have to account for the situation where a student's state
    # has been deleted- in this case, get_score returns (None, None), but
    # the score change signal will contain 0 for raw_earned.
    state_deleted = module_raw_earned is None and module_raw_possible is None and raw_earned == 0

    if not (state_deleted or grades_match):
        raise _retry_recalculate_subsection_grade(
            user_id, course_id, usage_id, only_if_higher, raw_earned, raw_possible,
        )

    _update_subsection_grades(
        course_key,
        scored_block_usage_key,
        only_if_higher,
        course_id,
        user_id,
        usage_id,
        raw_earned,
        raw_possible,
    )
コード例 #6
0
ファイル: handlers.py プロジェクト: song0606/edx-platform
def score_published_handler(sender, block, user, raw_earned, raw_possible,
                            only_if_higher, **kwargs):  # pylint: disable=unused-argument
    """
    Handles whenever a block's score is published.
    Returns whether the score was actually updated.
    """
    update_score = True
    if only_if_higher:
        previous_score = get_score(user.id, block.location)

        if previous_score is not None:
            prev_raw_earned, prev_raw_possible = (previous_score.grade,
                                                  previous_score.max_grade)

            if not is_score_higher_or_equal(prev_raw_earned, prev_raw_possible,
                                            raw_earned, raw_possible):
                update_score = False
                log.warning(
                    u"Grades: Rescore is not higher than previous: "
                    u"user: {}, block: {}, previous: {}/{}, new: {}/{} ".
                    format(
                        user,
                        block.location,
                        prev_raw_earned,
                        prev_raw_possible,
                        raw_earned,
                        raw_possible,
                    ))

    if update_score:
        # Set the problem score in CSM.
        score_modified_time = set_score(user.id, block.location, raw_earned,
                                        raw_possible)

        # Set the problem score on the xblock.
        if isinstance(block, ScorableXBlockMixin):
            block.set_score(
                Score(raw_earned=raw_earned, raw_possible=raw_possible))

        # Fire a signal (consumed by enqueue_subsection_update, below)
        PROBLEM_RAW_SCORE_CHANGED.send(
            sender=None,
            raw_earned=raw_earned,
            raw_possible=raw_possible,
            weight=getattr(block, 'weight', None),
            user_id=user.id,
            course_id=unicode(block.location.course_key),
            usage_id=unicode(block.location),
            only_if_higher=only_if_higher,
            modified=score_modified_time,
            score_db_table=ScoreDatabaseTableEnum.courseware_student_module,
            score_deleted=kwargs.get('score_deleted', False),
        )
    return update_score
コード例 #7
0
def _has_db_updated_with_new_score(self, scored_block_usage_key, **kwargs):
    """
    Returns whether the database has been updated with the
    expected new score values for the given problem and user.
    """
    if kwargs[
            'score_db_table'] == ScoreDatabaseTableEnum.courseware_student_module:
        score = get_score(kwargs['user_id'], scored_block_usage_key)
        found_modified_time = score.modified if score is not None else None

    elif kwargs['score_db_table'] == ScoreDatabaseTableEnum.submissions:
        score = sub_api.get_score({
            "student_id":
            kwargs['anonymous_user_id'],
            "course_id":
            six.text_type(scored_block_usage_key.course_key),
            "item_id":
            six.text_type(scored_block_usage_key),
            "item_type":
            scored_block_usage_key.block_type,
        })
        found_modified_time = score['created_at'] if score is not None else None
    else:
        assert kwargs['score_db_table'] == ScoreDatabaseTableEnum.overrides
        from . import api
        score = api.get_subsection_grade_override(
            user_id=kwargs['user_id'],
            course_key_or_id=kwargs['course_id'],
            usage_key_or_id=kwargs['usage_id'])
        found_modified_time = score.modified if score is not None else None

    if score is None:
        # score should be None only if it was deleted.
        # Otherwise, it hasn't yet been saved.
        db_is_updated = kwargs['score_deleted']
    else:
        db_is_updated = found_modified_time >= from_timestamp(
            kwargs['expected_modified_time'])

    if not db_is_updated:
        log.info(
            u"Grades: tasks._has_database_updated_with_new_score is False. Task ID: {}. Kwargs: {}. Found "
            u"modified time: {}".format(
                self.request.id,
                kwargs,
                found_modified_time,
            ))

    return db_is_updated
コード例 #8
0
ファイル: tasks.py プロジェクト: cmscom/edx-platform
def _has_db_updated_with_new_score(self, scored_block_usage_key, **kwargs):
    """
    Returns whether the database has been updated with the
    expected new score values for the given problem and user.
    """
    if kwargs['score_db_table'] == ScoreDatabaseTableEnum.courseware_student_module:
        score = get_score(kwargs['user_id'], scored_block_usage_key)
        found_modified_time = score.modified if score is not None else None

    elif kwargs['score_db_table'] == ScoreDatabaseTableEnum.submissions:
        score = sub_api.get_score(
            {
                "student_id": kwargs['anonymous_user_id'],
                "course_id": unicode(scored_block_usage_key.course_key),
                "item_id": unicode(scored_block_usage_key),
                "item_type": scored_block_usage_key.block_type,
            }
        )
        found_modified_time = score['created_at'] if score is not None else None
    else:
        assert kwargs['score_db_table'] == ScoreDatabaseTableEnum.overrides
        score = GradesService().get_subsection_grade_override(
            user_id=kwargs['user_id'],
            course_key_or_id=kwargs['course_id'],
            usage_key_or_id=kwargs['usage_id']
        )
        found_modified_time = score.modified if score is not None else None

    if score is None:
        # score should be None only if it was deleted.
        # Otherwise, it hasn't yet been saved.
        db_is_updated = kwargs['score_deleted']
    else:
        db_is_updated = found_modified_time >= from_timestamp(kwargs['expected_modified_time'])

    if not db_is_updated:
        log.info(
            u"Grades: tasks._has_database_updated_with_new_score is False. Task ID: {}. Kwargs: {}. Found "
            u"modified time: {}".format(
                self.request.id,
                kwargs,
                found_modified_time,
            )
        )

    return db_is_updated
コード例 #9
0
ファイル: handlers.py プロジェクト: edx/edx-platform
def score_published_handler(sender, block, user, raw_earned, raw_possible, only_if_higher, **kwargs):  # pylint: disable=unused-argument
    """
    Handles whenever a block's score is published.
    Returns whether the score was actually updated.
    """
    update_score = True
    if only_if_higher:
        previous_score = get_score(user.id, block.location)

        if previous_score is not None:
            prev_raw_earned, prev_raw_possible = (previous_score.grade, previous_score.max_grade)

            if not is_score_higher_or_equal(prev_raw_earned, prev_raw_possible, raw_earned, raw_possible):
                update_score = False
                log.warning(
                    u"Grades: Rescore is not higher than previous: "
                    u"user: {}, block: {}, previous: {}/{}, new: {}/{} ".format(
                        user, block.location, prev_raw_earned, prev_raw_possible, raw_earned, raw_possible,
                    )
                )

    if update_score:
        # Set the problem score in CSM.
        score_modified_time = set_score(user.id, block.location, raw_earned, raw_possible)

        # Set the problem score on the xblock.
        if isinstance(block, ScorableXBlockMixin):
            block.set_score(Score(raw_earned=raw_earned, raw_possible=raw_possible))

        # Fire a signal (consumed by enqueue_subsection_update, below)
        PROBLEM_RAW_SCORE_CHANGED.send(
            sender=None,
            raw_earned=raw_earned,
            raw_possible=raw_possible,
            weight=getattr(block, 'weight', None),
            user_id=user.id,
            course_id=six.text_type(block.location.course_key),
            usage_id=six.text_type(block.location),
            only_if_higher=only_if_higher,
            modified=score_modified_time,
            score_db_table=ScoreDatabaseTableEnum.courseware_student_module,
            score_deleted=kwargs.get('score_deleted', False),
            grader_response=kwargs.get('grader_response', False)
        )
    return update_score
コード例 #10
0
def _has_database_updated_with_new_score(
        user_id, scored_block_usage_key, expected_raw_earned, expected_raw_possible, score_deleted,
):
    """
    Returns whether the database has been updated with the
    expected new score values for the given problem and user.
    """
    score = get_score(user_id, scored_block_usage_key)

    if score is None:
        # score should be None only if it was deleted.
        # Otherwise, it hasn't yet been saved.
        return score_deleted

    found_raw_earned, found_raw_possible = score  # pylint: disable=unpacking-non-sequence
    return (
        found_raw_earned == expected_raw_earned and
        found_raw_possible == expected_raw_possible
    )
コード例 #11
0
def score_published_handler(sender, block, user, raw_earned, raw_possible,
                            only_if_higher, **kwargs):  # pylint: disable=unused-argument
    """
    Handles whenever a block's score is published.
    Returns whether the score was actually updated.
    """
    update_score = True
    if only_if_higher:
        previous_score = get_score(user.id, block.location)

        if previous_score:
            prev_raw_earned, prev_raw_possible = previous_score  # pylint: disable=unpacking-non-sequence

            if not is_score_higher(prev_raw_earned, prev_raw_possible,
                                   raw_earned, raw_possible):
                update_score = False
                log.warning(
                    u"Grades: Rescore is not higher than previous: "
                    u"user: {}, block: {}, previous: {}/{}, new: {}/{} ".
                    format(
                        user,
                        block.location,
                        prev_raw_earned,
                        prev_raw_possible,
                        raw_earned,
                        raw_possible,
                    ))

    if update_score:
        set_score(user.id, block.location, raw_earned, raw_possible)

        SCORE_CHANGED.send(
            sender=None,
            points_earned=raw_earned,
            points_possible=raw_possible,
            user_id=user.id,
            course_id=unicode(block.location.course_key),
            usage_id=unicode(block.location),
            only_if_higher=only_if_higher,
        )
    return update_score
コード例 #12
0
def _has_database_updated_with_new_score(
    user_id,
    scored_block_usage_key,
    expected_raw_earned,
    expected_raw_possible,
    score_deleted,
):
    """
    Returns whether the database has been updated with the
    expected new score values for the given problem and user.
    """
    score = get_score(user_id, scored_block_usage_key)

    if score is None:
        # score should be None only if it was deleted.
        # Otherwise, it hasn't yet been saved.
        return score_deleted

    found_raw_earned, found_raw_possible = score  # pylint: disable=unpacking-non-sequence
    return (found_raw_earned == expected_raw_earned
            and found_raw_possible == expected_raw_possible)
コード例 #13
0
ファイル: tasks.py プロジェクト: foamsand/edx-platform
def recalculate_subsection_grade(user_id, course_id, usage_id, only_if_higher,
                                 raw_earned, raw_possible):
    """
    Updates a saved subsection grade.
    This method expects the following parameters:
        - user_id: serialized id of applicable User object
        - course_id: Unicode string identifying the course
        - usage_id: Unicode string identifying the course block
        - only_if_higher: boolean indicating whether grades should
        be updated only if the new raw_earned is higher than the previous
        value.
        - raw_earned: the raw points the learner earned on the problem that
        triggered the update
        - raw_possible: the max raw points the leaner could have earned
        on the problem
    """
    course_key = CourseLocator.from_string(course_id)
    if not PersistentGradesEnabledFlag.feature_enabled(course_key):
        return

    scored_block_usage_key = UsageKey.from_string(usage_id).replace(
        course_key=course_key)
    score = get_score(user_id, scored_block_usage_key)

    # If the score is None, it has not been saved at all yet
    # and we need to retry until it has been saved.
    if score is None:
        raise _retry_recalculate_subsection_grade(
            user_id,
            course_id,
            usage_id,
            only_if_higher,
            raw_earned,
            raw_possible,
        )
    else:
        module_raw_earned, module_raw_possible = score  # pylint: disable=unpacking-non-sequence

    # Validate that the retrieved scores match the scores when the task was created.
    # This race condition occurs if the transaction in the task creator's process hasn't
    # committed before the task initiates in the worker process.
    grades_match = module_raw_earned == raw_earned and module_raw_possible == raw_possible

    # We have to account for the situation where a student's state
    # has been deleted- in this case, get_score returns (None, None), but
    # the score change signal will contain 0 for raw_earned.
    state_deleted = module_raw_earned is None and module_raw_possible is None and raw_earned == 0

    if not (state_deleted or grades_match):
        raise _retry_recalculate_subsection_grade(
            user_id,
            course_id,
            usage_id,
            only_if_higher,
            raw_earned,
            raw_possible,
        )

    _update_subsection_grades(
        course_key,
        scored_block_usage_key,
        only_if_higher,
        course_id,
        user_id,
        usage_id,
        raw_earned,
        raw_possible,
    )