コード例 #1
0
ファイル: handlers.py プロジェクト: sliva/edx-platform
def enqueue_subsection_update(sender, **kwargs):  # pylint: disable=unused-argument
    """
    Handles the PROBLEM_WEIGHTED_SCORE_CHANGED or SUBSECTION_OVERRIDE_CHANGED signals by
    enqueueing a subsection update operation to occur asynchronously.
    """
    events.grade_updated(**kwargs)
    context_key = LearningContextKey.from_string(kwargs['course_id'])
    if not context_key.is_course:
        return  # If it's not a course, it has no subsections, so skip the subsection grading update
    recalculate_subsection_grade_v3.apply_async(
        kwargs=dict(
            user_id=kwargs['user_id'],
            anonymous_user_id=kwargs.get('anonymous_user_id'),
            course_id=kwargs['course_id'],
            usage_id=kwargs['usage_id'],
            only_if_higher=kwargs.get('only_if_higher'),
            expected_modified_time=to_timestamp(kwargs['modified']),
            score_deleted=kwargs.get('score_deleted', False),
            event_transaction_id=six.text_type(get_event_transaction_id()),
            event_transaction_type=six.text_type(get_event_transaction_type()),
            score_db_table=kwargs['score_db_table'],
            force_update_subsections=kwargs.get('force_update_subsections', False),
        ),
        countdown=RECALCULATE_GRADE_DELAY_SECONDS,
    )
コード例 #2
0
def subsection_grade_calculated(subsection_grade):
    """
    Emits an edx.grades.subsection.grade_calculated event
    with data from the passed subsection_grade.
    """
    event_name = SUBSECTION_GRADE_CALCULATED
    context = contexts.course_context_from_course_id(subsection_grade.course_id)
    # TODO (AN-6134): remove this context manager
    with tracker.get_tracker().context(event_name, context):
        tracker.emit(
            event_name,
            {
                'user_id': str(subsection_grade.user_id),
                'course_id': str(subsection_grade.course_id),
                'block_id': str(subsection_grade.usage_key),
                'course_version': str(subsection_grade.course_version),
                'weighted_total_earned': subsection_grade.earned_all,
                'weighted_total_possible': subsection_grade.possible_all,
                'weighted_graded_earned': subsection_grade.earned_graded,
                'weighted_graded_possible': subsection_grade.possible_graded,
                'first_attempted': str(subsection_grade.first_attempted),
                'subtree_edited_timestamp': str(subsection_grade.subtree_edited_timestamp),
                'event_transaction_id': str(get_event_transaction_id()),
                'event_transaction_type': str(get_event_transaction_type()),
                'visible_blocks_hash': str(subsection_grade.visible_blocks_id),
            }
        )
コード例 #3
0
    def _create_override(self, request_user, subsection_grade_model,
                         **override_data):
        """
        Helper method to create a `PersistentSubsectionGradeOverride` object
        and send a `SUBSECTION_OVERRIDE_CHANGED` signal.
        """
        override_data[
            'system'] = grades_constants.GradeOverrideFeatureEnum.gradebook
        override = PersistentSubsectionGradeOverride.update_or_create_override(
            requesting_user=request_user,
            subsection_grade_model=subsection_grade_model,
            feature=grades_constants.GradeOverrideFeatureEnum.gradebook,
            **override_data)

        set_event_transaction_type(grades_events.SUBSECTION_GRADE_CALCULATED)
        create_new_event_transaction_id()

        recalculate_subsection_grade_v3.apply(kwargs=dict(
            user_id=subsection_grade_model.user_id,
            anonymous_user_id=None,
            course_id=text_type(subsection_grade_model.course_id),
            usage_id=text_type(subsection_grade_model.usage_key),
            only_if_higher=False,
            expected_modified_time=to_timestamp(override.modified),
            score_deleted=False,
            event_transaction_id=six.text_type(get_event_transaction_id()),
            event_transaction_type=six.text_type(get_event_transaction_type()),
            score_db_table=grades_constants.ScoreDatabaseTableEnum.overrides,
            force_update_subsections=True,
        ))
        # Emit events to let our tracking system to know we updated subsection grade
        grades_events.subsection_grade_calculated(subsection_grade_model)
        return override
コード例 #4
0
ファイル: test_models.py プロジェクト: sliva/edx-platform
 def _assert_tracker_emitted_event(self, tracker_mock, grade):
     """
     Helper function to ensure that the mocked event tracker
     was called with the expected info based on the passed grade.
     """
     tracker_mock.emit.assert_called_with(
         u'edx.grades.course.grade_calculated', {
             'user_id':
             six.text_type(grade.user_id),
             'course_id':
             six.text_type(grade.course_id),
             'course_version':
             six.text_type(grade.course_version),
             'percent_grade':
             grade.percent_grade,
             'letter_grade':
             six.text_type(grade.letter_grade),
             'course_edited_timestamp':
             six.text_type(grade.course_edited_timestamp),
             'event_transaction_id':
             six.text_type(get_event_transaction_id()),
             'event_transaction_type':
             six.text_type(get_event_transaction_type()),
             'grading_policy_hash':
             six.text_type(grade.grading_policy_hash),
         })
コード例 #5
0
def grade_updated(**kwargs):
    """
    Emits the appropriate grade-related event after checking for which
    event-transaction is active.

    Emits a problem.submitted event only if there is no current event
    transaction type, i.e. we have not reached this point in the code via
    an outer event type (such as problem.rescored or score_overridden).
    """
    root_type = get_event_transaction_type()

    if not root_type:
        root_id = get_event_transaction_id()
        if not root_id:
            root_id = create_new_event_transaction_id()
        set_event_transaction_type(PROBLEM_SUBMITTED_EVENT_TYPE)
        tracker.emit(
            str(PROBLEM_SUBMITTED_EVENT_TYPE),
            {
                'user_id': str(kwargs['user_id']),
                'course_id': str(kwargs['course_id']),
                'problem_id': str(kwargs['usage_id']),
                'event_transaction_id': str(root_id),
                'event_transaction_type': str(PROBLEM_SUBMITTED_EVENT_TYPE),
                'weighted_earned': kwargs.get('weighted_earned'),
                'weighted_possible': kwargs.get('weighted_possible'),
            }
        )

    elif root_type in [GRADES_RESCORE_EVENT_TYPE, GRADES_OVERRIDE_EVENT_TYPE]:
        current_user = get_current_user()
        instructor_id = getattr(current_user, 'id', None)
        tracker.emit(
            str(root_type),
            {
                'course_id': str(kwargs['course_id']),
                'user_id': str(kwargs['user_id']),
                'problem_id': str(kwargs['usage_id']),
                'new_weighted_earned': kwargs.get('weighted_earned'),
                'new_weighted_possible': kwargs.get('weighted_possible'),
                'only_if_higher': kwargs.get('only_if_higher'),
                'instructor_id': str(instructor_id),
                'event_transaction_id': str(get_event_transaction_id()),
                'event_transaction_type': str(root_type),
            }
        )

    elif root_type in [SUBSECTION_OVERRIDE_EVENT_TYPE]:
        tracker.emit(
            str(root_type),
            {
                'course_id': str(kwargs['course_id']),
                'user_id': str(kwargs['user_id']),
                'problem_id': str(kwargs['usage_id']),
                'only_if_higher': kwargs.get('only_if_higher'),
                'override_deleted': kwargs.get('score_deleted', False),
                'event_transaction_id': str(get_event_transaction_id()),
                'event_transaction_type': str(root_type),
            }
        )
コード例 #6
0
ファイル: test_models.py プロジェクト: sliva/edx-platform
 def _assert_tracker_emitted_event(self, tracker_mock, grade):
     """
     Helper function to ensure that the mocked event tracker
     was called with the expected info based on the passed grade.
     """
     tracker_mock.emit.assert_called_with(
         u'edx.grades.subsection.grade_calculated', {
             'user_id':
             six.text_type(grade.user_id),
             'course_id':
             six.text_type(grade.course_id),
             'block_id':
             six.text_type(grade.usage_key),
             'course_version':
             six.text_type(grade.course_version),
             'weighted_total_earned':
             grade.earned_all,
             'weighted_total_possible':
             grade.possible_all,
             'weighted_graded_earned':
             grade.earned_graded,
             'weighted_graded_possible':
             grade.possible_graded,
             'first_attempted':
             six.text_type(grade.first_attempted),
             'subtree_edited_timestamp':
             six.text_type(grade.subtree_edited_timestamp),
             'event_transaction_id':
             six.text_type(get_event_transaction_id()),
             'event_transaction_type':
             six.text_type(get_event_transaction_type()),
             'visible_blocks_hash':
             six.text_type(grade.visible_blocks_id),
         })
コード例 #7
0
def course_grade_calculated(course_grade):
    """
    Emits an edx.grades.course.grade_calculated event
    with data from the passed course_grade.
    """
    event_name = COURSE_GRADE_CALCULATED
    context = contexts.course_context_from_course_id(course_grade.course_id)
    # TODO (AN-6134): remove this context manager
    with tracker.get_tracker().context(event_name, context):
        tracker.emit(
            event_name, {
                'user_id':
                str(course_grade.user_id),
                'course_id':
                str(course_grade.course_id),
                'course_version':
                str(course_grade.course_version),
                'percent_grade':
                course_grade.percent_grade,
                'letter_grade':
                str(course_grade.letter_grade),
                'course_edited_timestamp':
                str(course_grade.course_edited_timestamp),
                'event_transaction_id':
                str(get_event_transaction_id()),
                'event_transaction_type':
                str(get_event_transaction_type()),
                'grading_policy_hash':
                str(course_grade.grading_policy_hash),
            })
コード例 #8
0
 def _assert_tracker_emitted_course_now_failed_event(
         self, tracker_mock, user, course_id):
     """
     Helper function to ensure that the mocked event tracker
     was called with the expected info based on failed course.
     """
     tracker_mock.emit.assert_called_with(
         'edx.course.grade.now_failed', {
             'user_id': str(user.id),
             'course_id': str(course_id),
             'event_transaction_id': str(get_event_transaction_id()),
             'event_transaction_type': str(get_event_transaction_type()),
         })
コード例 #9
0
 def _assert_tracker_emitted_course_grade_passed_first_time_event(
         self, tracker_mock, user_id, course_id):
     """
     Helper function to ensure that the mocked event tracker
     was called with the expected info based on the course grade passed first time.
     """
     tracker_mock.emit.assert_called_with(
         'edx.course.grade.passed.first_time', {
             'user_id': str(user_id),
             'course_id': str(course_id),
             'event_transaction_id': str(get_event_transaction_id()),
             'event_transaction_type': str(get_event_transaction_type()),
         })
コード例 #10
0
def course_grade_now_failed(user, course_id):
    """
    Emits an edx.course.grade.now_failed event
    with data from the course and user failed now .
    """
    event_name = COURSE_GRADE_NOW_FAILED_EVENT_TYPE
    context = contexts.course_context_from_course_id(course_id)
    with tracker.get_tracker().context(event_name, context):
        tracker.emit(
            event_name,
            {
                'user_id': str(user.id),
                'course_id': str(course_id),
                'event_transaction_id': str(get_event_transaction_id()),
                'event_transaction_type': str(get_event_transaction_type())
            }
        )
コード例 #11
0
ファイル: handlers.py プロジェクト: yrchen/edx-platform
def handle_grading_policy_changed(sender, **kwargs):
    # pylint: disable=unused-argument
    """
    Receives signal and kicks off celery task to recalculate grades
    """
    kwargs = {
        'course_key': str(kwargs.get('course_key')),
        'grading_policy_hash': str(kwargs.get('grading_policy_hash')),
        'event_transaction_id': str(get_event_transaction_id()),
        'event_transaction_type': str(get_event_transaction_type()),
    }
    result = task_compute_all_grades_for_course.apply_async(kwargs=kwargs, countdown=GRADING_POLICY_COUNTDOWN_SECONDS)
    log.info("Grades: Created {task_name}[{task_id}] with arguments {kwargs}".format(
        task_name=task_compute_all_grades_for_course.name,
        task_id=result.task_id,
        kwargs=kwargs,
    ))
コード例 #12
0
def course_grade_passed_first_time(user_id, course_id):
    """
    Emits an event edx.course.grade.passed.first_time
    with data from the passed course_grade.
    """
    event_name = COURSE_GRADE_PASSED_FIRST_TIME_EVENT_TYPE
    context = contexts.course_context_from_course_id(course_id)
    # TODO (AN-6134): remove this context manager
    with tracker.get_tracker().context(event_name, context):
        tracker.emit(
            event_name,
            {
                'user_id': str(user_id),
                'course_id': str(course_id),
                'event_transaction_id': str(get_event_transaction_id()),
                'event_transaction_type': str(get_event_transaction_type())
            }
        )