예제 #1
0
    def test_get_value_for_org_2(self):
        """
        Test that get_value_for_org returns correct value for any given key.
        """
        test_org = test_config['course_org_filter']
        with with_site_configuration_context(configuration=test_config):

            # Make sure if ORG is not present in site configuration then microsite configuration is used instead
            self.assertEqual(
                configuration_helpers.get_value_for_org(
                    "TestSiteX", "email_from_address"), "*****@*****.**")
            # Make sure 'default' is returned if org is present but key is not
            self.assertEqual(
                configuration_helpers.get_value_for_org(
                    test_org, "email_from_address"), None)
            # Make sure if ORG is not present in site configuration then microsite configuration is used instead
            self.assertEqual(
                configuration_helpers.get_value_for_org(
                    "LogistrationX", "email_from_address"),
                "*****@*****.**")

        # This test must come after the above test
        with with_site_configuration_context(configuration={
                "course_org_filter": "TestSiteX",
                "university": "Test"
        }):
            # Make sure site configuration gets preference over microsite configuration
            self.assertEqual(
                configuration_helpers.get_value_for_org(
                    "TestSiteX", "university"), "Test")
예제 #2
0
    def test_get_value_for_org_2(self):
        """
        Test that get_value_for_org returns correct value for any given key.
        """
        test_org = test_config['course_org_filter']
        with with_site_configuration_context(configuration=test_config):

            # Make sure if ORG is not present in site configuration then microsite configuration is used instead
            self.assertEqual(
                configuration_helpers.get_value_for_org("TestSiteX", "email_from_address"),
                "*****@*****.**"
            )
            # Make sure 'default' is returned if org is present but key is not
            self.assertEqual(
                configuration_helpers.get_value_for_org(test_org, "email_from_address"),
                None
            )
            # Make sure if ORG is not present in site configuration then microsite configuration is used instead
            self.assertEqual(
                configuration_helpers.get_value_for_org("LogistrationX", "email_from_address"),
                "*****@*****.**"
            )

        # This test must come after the above test
        with with_site_configuration_context(configuration={"course_org_filter": "TestSiteX", "university": "Test"}):
            # Make sure site configuration gets preference over microsite configuration
            self.assertEqual(
                configuration_helpers.get_value_for_org("TestSiteX", "university"),
                "Test"
            )
예제 #3
0
    def test_get_value_for_org_2(self):
        """
        Test that get_value_for_org returns correct value for any given key.
        """
        test_org = test_config['course_org_filter']
        with with_site_configuration_context(configuration=test_config):

            # Make sure if ORG is not present in site configuration then default is used instead
            assert configuration_helpers.get_value_for_org(
                'TestSiteX', 'email_from_address') is None
            # Make sure 'default' is returned if org is present but key is not
            assert configuration_helpers.get_value_for_org(
                test_org, 'email_from_address') is None
예제 #4
0
def get_course_authoring_url(course_locator):
    """
    Gets course authoring microfrontend URL
    """
    return configuration_helpers.get_value_for_org(
        course_locator.org, 'COURSE_AUTHORING_MICROFRONTEND_URL',
        settings.COURSE_AUTHORING_MICROFRONTEND_URL)
예제 #5
0
 def get_internal_api_url_for_org(org):
     """
     Internally-accessible API URL root, looked up by org rather than the current request.
     """
     root = helpers.get_value_for_org(org, 'CREDENTIALS_INTERNAL_SERVICE_URL',
                                      settings.CREDENTIALS_INTERNAL_SERVICE_URL)
     return urljoin(root, '/api/{}/'.format(API_VERSION))
예제 #6
0
 def get_internal_api_url_for_org(org):
     """
     Internally-accessible API URL root, looked up by org rather than the current request.
     """
     root = helpers.get_value_for_org(org, 'CREDENTIALS_INTERNAL_SERVICE_URL',
                                      settings.CREDENTIALS_INTERNAL_SERVICE_URL)
     return urljoin(root, '/api/{}/'.format(API_VERSION))
예제 #7
0
파일: utils.py 프로젝트: CUCWD/edx-platform
def site_prefix(org):
    """
    Get the prefix for the site URL-- protocol and server name.
    """
    scheme = u"https" if settings.HTTPS == "on" else u"http"
    return u'{}://{}'.format(
        scheme,
        configuration_helpers.get_value_for_org(org, "SITE_NAME",
                                                settings.SITE_NAME))
예제 #8
0
def get_proctored_exam_settings_url(course_module):
    """
    Gets course authoring microfrontend URL for links to proctored exam settings page
    """
    course_authoring_microfrontend_url = ''

    if settings.FEATURES.get('ENABLE_EXAM_SETTINGS_HTML_VIEW'):
        course_authoring_microfrontend_url = configuration_helpers.get_value_for_org(
            course_module.location.org, 'COURSE_AUTHORING_MICROFRONTEND_URL',
            settings.COURSE_AUTHORING_MICROFRONTEND_URL)
    return course_authoring_microfrontend_url
예제 #9
0
def get_edflex_configuration_for_org(org):
    client_id = configuration_helpers.get_value_for_org(
        org, 'EDFLEX_CLIENT_ID')
    client_secret = configuration_helpers.get_value_for_org(
        org, 'EDFLEX_CLIENT_SECRET')
    locale = configuration_helpers.get_value_for_org(org, 'EDFLEX_LOCALE',
                                                     EDFLEX_LOCALE)
    base_api_url = configuration_helpers.get_value_for_org(
        org, 'EDFLEX_BASE_API_URL')

    if not (client_id and client_secret and base_api_url):
        configuration = get_edflex_configuration()
        return configuration

    return {
        'client_id': client_id,
        'client_secret': client_secret,
        'locale': locale,
        'base_api_url': base_api_url
    }
예제 #10
0
    def test_get_value_for_org(self):
        """
        Test that get_value_for_org returns correct value for any given key.
        """
        test_org = test_config['course_org_filter']
        with with_site_configuration_context(configuration=test_config):
            self.assertEqual(
                configuration_helpers.get_value_for_org(test_org, "university"),
                test_config['university']
            )
            self.assertEqual(
                configuration_helpers.get_value_for_org(test_org, "css_overrides_file"),
                test_config['css_overrides_file']
            )

            self.assertItemsEqual(
                configuration_helpers.get_value_for_org(test_org, "REGISTRATION_EXTRA_FIELDS"),
                test_config['REGISTRATION_EXTRA_FIELDS']
            )

            # Test default value of key is not present in configuration
            self.assertEqual(
                configuration_helpers.get_value_for_org(test_org, "non_existent_key"),
                None
            )
            self.assertEqual(
                configuration_helpers.get_value_for_org(test_org, "non_existent_key", "default for non existent"),
                "default for non existent"
            )
            self.assertEqual(
                configuration_helpers.get_value_for_org("missing_org", "university", "default for non existent"),
                "default for non existent"
            )
예제 #11
0
    def test_get_value_for_org(self):
        """
        Test that get_value_for_org returns correct value for any given key.
        """
        test_org = test_config['course_org_filter']
        with with_site_configuration_context(configuration=test_config):
            self.assertEqual(
                configuration_helpers.get_value_for_org(
                    test_org, "university"), test_config['university'])
            self.assertEqual(
                configuration_helpers.get_value_for_org(
                    test_org, "css_overrides_file"),
                test_config['css_overrides_file'])

            six.assertCountEqual(
                self,
                configuration_helpers.get_value_for_org(
                    test_org, "REGISTRATION_EXTRA_FIELDS"),
                test_config['REGISTRATION_EXTRA_FIELDS'])

            # Test default value of key is not present in configuration
            self.assertEqual(
                configuration_helpers.get_value_for_org(
                    test_org, "non_existent_key"), None)
            self.assertEqual(
                configuration_helpers.get_value_for_org(
                    test_org, "non_existent_key", "default for non existent"),
                "default for non existent")
            self.assertEqual(
                configuration_helpers.get_value_for_org(
                    "missing_org", "university", "default for non existent"),
                "default for non existent")
예제 #12
0
def handle_course_cert_changed(sender, user, course_key, mode, status,
                               **kwargs):  # pylint: disable=unused-argument
    """
        If a learner is awarded a course certificate,
        schedule a celery task to process that course certificate

        Args:
            sender:
                class of the object instance that sent this signal
            user:
                django.contrib.auth.User - the user to whom a cert was awarded
            course_key:
                refers to the course run for which the cert was awarded
            mode:
                mode / certificate type, e.g. "verified"
            status:
                "downloadable"

        Returns:
            None

        """
    # Import here instead of top of file since this module gets imported before
    # the credentials app is loaded, resulting in a Django deprecation warning.
    from openedx.core.djangoapps.credentials.models import CredentialsApiConfig

    # Avoid scheduling new tasks if certification is disabled.
    if not CredentialsApiConfig.current().is_learner_issuance_enabled:
        return

    # Avoid scheduling new tasks if learner records are disabled for this site (right now, course certs are only
    # used for learner records -- when that changes, we can remove this bit and always send course certs).
    if not helpers.get_value_for_org(course_key.org, 'ENABLE_LEARNER_RECORDS',
                                     True):
        return

    # schedule background task to process
    LOGGER.debug(
        'handling COURSE_CERT_CHANGED: username=%s, course_key=%s, mode=%s, status=%s',
        user,
        course_key,
        mode,
        status,
    )
    # import here, because signal is registered at startup, but items in tasks are not yet able to be loaded
    from openedx.core.djangoapps.programs.tasks.v1.tasks import award_course_certificate
    award_course_certificate.delay(user.username, str(course_key))
예제 #13
0
def handle_course_cert_changed(sender, user, course_key, mode, status, **kwargs):  # pylint: disable=unused-argument
    """
        If a learner is awarded a course certificate,
        schedule a celery task to process that course certificate

        Args:
            sender:
                class of the object instance that sent this signal
            user:
                django.contrib.auth.User - the user to whom a cert was awarded
            course_key:
                refers to the course run for which the cert was awarded
            mode:
                mode / certificate type, e.g. "verified"
            status:
                "downloadable"

        Returns:
            None

        """
    # Import here instead of top of file since this module gets imported before
    # the credentials app is loaded, resulting in a Django deprecation warning.
    from openedx.core.djangoapps.credentials.models import CredentialsApiConfig

    # Avoid scheduling new tasks if certification is disabled.
    if not CredentialsApiConfig.current().is_learner_issuance_enabled:
        return

    # Avoid scheduling new tasks if learner records are disabled for this site (right now, course certs are only
    # used for learner records -- when that changes, we can remove this bit and always send course certs).
    if not helpers.get_value_for_org(course_key.org, 'ENABLE_LEARNER_RECORDS', True):
        return

    # schedule background task to process
    LOGGER.debug(
        'handling COURSE_CERT_CHANGED: username=%s, course_key=%s, mode=%s, status=%s',
        user,
        course_key,
        mode,
        status,
    )
    # import here, because signal is registered at startup, but items in tasks are not yet able to be loaded
    from openedx.core.djangoapps.programs.tasks.v1.tasks import award_course_certificate
    award_course_certificate.delay(user.username, str(course_key))
예제 #14
0
def send_grade_if_interesting(user, course_run_key, mode, status, letter_grade, percent_grade):
    """ Checks if grade is interesting to Credentials and schedules a Celery task if so. """

    # Avoid scheduling new tasks if certification is disabled. (Grades are a part of the records/cert story)
    if not CredentialsApiConfig.current().is_learner_issuance_enabled:
        return

    # Avoid scheduling new tasks if learner records are disabled for this site.
    if not helpers.get_value_for_org(course_run_key.org, 'ENABLE_LEARNER_RECORDS', True):
        return

    # Grab mode/status if we don't have them in hand
    if mode is None or status is None:
        try:
            cert = GeneratedCertificate.objects.get(user=user, course_id=course_run_key)  # pylint: disable=no-member
            mode = cert.mode
            status = cert.status
        except GeneratedCertificate.DoesNotExist:
            # We only care about grades for which there is a certificate.
            return

    # Don't worry about whether it's available as well as awarded. Just awarded is good enough to record a verified
    # attempt at a course. We want even the grades that didn't pass the class because Credentials wants to know about
    # those too.
    if mode not in INTERESTING_MODES or status not in INTERESTING_STATUSES:
        return

    # If the course isn't in any program, don't bother telling Credentials about it. When Credentials grows support
    # for course records as well as program records, we'll need to open this up.
    if not is_course_run_in_a_program(course_run_key):
        return

    # Grab grades if we don't have them in hand
    if letter_grade is None or percent_grade is None:
        grade = CourseGradeFactory().read(user, course_key=course_run_key, create_if_needed=False)
        if grade is None:
            return
        letter_grade = grade.letter_grade
        percent_grade = grade.percent

    send_grade_to_credentials.delay(user.username, str(course_run_key), True, letter_grade, percent_grade)
예제 #15
0
def send_grade_if_interesting(user, course_run_key, mode, status, letter_grade, percent_grade):
    """ Checks if grade is interesting to Credentials and schedules a Celery task if so. """

    # Avoid scheduling new tasks if certification is disabled. (Grades are a part of the records/cert story)
    if not CredentialsApiConfig.current().is_learner_issuance_enabled:
        return

    # Avoid scheduling new tasks if learner records are disabled for this site.
    if not helpers.get_value_for_org(course_run_key.org, 'ENABLE_LEARNER_RECORDS', True):
        return

    # Grab mode/status if we don't have them in hand
    if mode is None or status is None:
        try:
            cert = GeneratedCertificate.objects.get(user=user, course_id=course_run_key)  # pylint: disable=no-member
            mode = cert.mode
            status = cert.status
        except GeneratedCertificate.DoesNotExist:
            # We only care about grades for which there is a certificate.
            return

    # Don't worry about whether it's available as well as awarded. Just awarded is good enough to record a verified
    # attempt at a course. We want even the grades that didn't pass the class because Credentials wants to know about
    # those too.
    if mode not in INTERESTING_MODES or status not in INTERESTING_STATUSES:
        return

    # If the course isn't in any program, don't bother telling Credentials about it. When Credentials grows support
    # for course records as well as program records, we'll need to open this up.
    if not is_course_run_in_a_program(course_run_key):
        return

    # Grab grades if we don't have them in hand
    if letter_grade is None or percent_grade is None:
        grade = CourseGradeFactory().read(user, course_key=course_run_key, create_if_needed=False)
        if grade is None:
            return
        letter_grade = grade.letter_grade
        percent_grade = grade.percent

    send_grade_to_credentials.delay(user.username, str(course_run_key), True, letter_grade, percent_grade)
예제 #16
0
    def test_get_value_for_org(self):
        """
        Test that get_value_for_org returns correct value for any given key.
        """
        test_org = test_config['course_org_filter']
        with with_site_configuration_context(configuration=test_config):
            assert configuration_helpers.get_value_for_org(
                test_org, 'university') == test_config['university']
            assert configuration_helpers.get_value_for_org(test_org, 'css_overrides_file') ==\
                   test_config['css_overrides_file']

            self.assertCountEqual(
                configuration_helpers.get_value_for_org(
                    test_org, "REGISTRATION_EXTRA_FIELDS"),
                test_config['REGISTRATION_EXTRA_FIELDS'])

            # Test default value of key is not present in configuration
            assert configuration_helpers.get_value_for_org(
                test_org, 'non_existent_key') is None
            assert configuration_helpers.get_value_for_org(test_org, 'non_existent_key', 'default for non existent') ==\
                   'default for non existent'
            assert configuration_helpers.get_value_for_org('missing_org', 'university', 'default for non existent') ==\
                   'default for non existent'
예제 #17
0
def send_grade_if_interesting(user,
                              course_run_key,
                              mode,
                              status,
                              letter_grade,
                              percent_grade,
                              verbose=False):
    """ Checks if grade is interesting to Credentials and schedules a Celery task if so. """

    if verbose:
        msg = u"Starting send_grade_if_interesting with params: "\
            "user [{username}], "\
            "course_run_key [{key}], "\
            "mode [{mode}], "\
            "status [{status}], "\
            "letter_grade [{letter_grade}], "\
            "percent_grade [{percent_grade}], "\
            "verbose [{verbose}]"\
            .format(
                username=getattr(user, 'username', None),
                key=str(course_run_key),
                mode=mode,
                status=status,
                letter_grade=letter_grade,
                percent_grade=percent_grade,
                verbose=verbose
            )
        log.info(msg)
    # Avoid scheduling new tasks if certification is disabled. (Grades are a part of the records/cert story)
    if not CredentialsApiConfig.current().is_learner_issuance_enabled:
        if verbose:
            log.info("Skipping send grade: is_learner_issuance_enabled False")
        return

    # Avoid scheduling new tasks if learner records are disabled for this site.
    if not helpers.get_value_for_org(course_run_key.org,
                                     'ENABLE_LEARNER_RECORDS', True):
        if verbose:
            log.info(
                u"Skipping send grade: ENABLE_LEARNER_RECORDS False for org [{org}]"
                .format(org=course_run_key.org))
        return

    # Grab mode/status if we don't have them in hand
    if mode is None or status is None:
        try:
            cert = GeneratedCertificate.objects.get(user=user,
                                                    course_id=course_run_key)  # pylint: disable=no-member
            mode = cert.mode
            status = cert.status
        except GeneratedCertificate.DoesNotExist:
            # We only care about grades for which there is a certificate.
            if verbose:
                log.info(
                    u"Skipping send grade: no cert for user [{username}] & course_id [{course_id}]"
                    .format(username=getattr(user, 'username', None),
                            course_id=str(course_run_key)))
            return

    # Don't worry about whether it's available as well as awarded. Just awarded is good enough to record a verified
    # attempt at a course. We want even the grades that didn't pass the class because Credentials wants to know about
    # those too.
    if mode not in INTERESTING_MODES or status not in INTERESTING_STATUSES:
        if verbose:
            log.info(
                u"Skipping send grade: mode/status uninteresting for mode [{mode}] & status [{status}]"
                .format(mode=mode, status=status))
        return

    # If the course isn't in any program, don't bother telling Credentials about it. When Credentials grows support
    # for course records as well as program records, we'll need to open this up.
    if not is_course_run_in_a_program(course_run_key):
        if verbose:
            log.info(
                u"Skipping send grade: course run not in a program. [{course_id}]"
                .format(course_id=str(course_run_key)))
        return

    # Grab grades if we don't have them in hand
    if letter_grade is None or percent_grade is None:
        grade = CourseGradeFactory().read(user,
                                          course_key=course_run_key,
                                          create_if_needed=False)
        if grade is None:
            if verbose:
                log.info(
                    u"Skipping send grade: No grade found for user [{username}] & course_id [{course_id}]"
                    .format(username=getattr(user, 'username', None),
                            course_id=str(course_run_key)))
            return
        letter_grade = grade.letter_grade
        percent_grade = grade.percent

    send_grade_to_credentials.delay(user.username, str(course_run_key), True,
                                    letter_grade, percent_grade)
예제 #18
0
파일: basic.py 프로젝트: fccn/edx-platform
def enrolled_students_features(course_key, features):
    """
    Return list of student features as dictionaries.

    enrolled_students_features(course_key, ['username', 'first_name'])
    would return [
        {'username': '******', 'first_name': 'firstname1'}
        {'username': '******', 'first_name': 'firstname2'}
        {'username': '******', 'first_name': 'firstname3'}
    ]
    """
    include_cohort_column = 'cohort' in features
    include_team_column = 'team' in features
    include_enrollment_mode = 'enrollment_mode' in features
    include_verification_status = 'verification_status' in features

    students = User.objects.filter(
        courseenrollment__course_id=course_key,
        courseenrollment__is_active=1,
    ).order_by('username').select_related('profile')

    if include_cohort_column:
        students = students.prefetch_related('course_groups')

    if include_team_column:
        students = students.prefetch_related('teams')

    STUDENT_FEATURES_WITH_CUSTOM = STUDENT_FEATURES + tuple(
        configuration_helpers.get_value_for_org(
            course_key.org,
            'student_profile_download_fields_custom_student_attributes',
            getattr(
                settings,
                "STUDENT_PROFILE_DOWNLOAD_FIELDS_CUSTOM_STUDENT_ATTRIBUTES",
                ())))

    def extract_attr(student, feature):
        """Evaluate a student attribute that is ready for JSON serialization"""
        attr = getattr(student, feature)
        try:
            DjangoJSONEncoder().default(attr)
            return attr
        except TypeError:
            return six.text_type(attr)

    def extract_student(student, features):
        """ convert student to dictionary """
        student_features = [
            x for x in STUDENT_FEATURES_WITH_CUSTOM if x in features
        ]
        profile_features = [x for x in PROFILE_FEATURES if x in features]

        # For data extractions on the 'meta' field
        # the feature name should be in the format of 'meta.foo' where
        # 'foo' is the keyname in the meta dictionary
        meta_features = []
        for feature in features:
            if 'meta.' in feature:
                meta_key = feature.split('.')[1]
                meta_features.append((feature, meta_key))

        student_dict = dict((feature, extract_attr(student, feature))
                            for feature in student_features)
        profile = student.profile
        if profile is not None:
            profile_dict = dict((feature, extract_attr(profile, feature))
                                for feature in profile_features)
            student_dict.update(profile_dict)

            # now fetch the requested meta fields
            meta_dict = json.loads(profile.meta) if profile.meta else {}
            for meta_feature, meta_key in meta_features:
                student_dict[meta_feature] = meta_dict.get(meta_key)

        if include_cohort_column:
            # Note that we use student.course_groups.all() here instead of
            # student.course_groups.filter(). The latter creates a fresh query,
            # therefore negating the performance gain from prefetch_related().
            student_dict['cohort'] = next(
                (cohort.name for cohort in student.course_groups.all()
                 if cohort.course_id == course_key), "[unassigned]")

        if include_team_column:
            student_dict['team'] = next(
                (team.name for team in student.teams.all()
                 if team.course_id == course_key), UNAVAILABLE)

        if include_enrollment_mode or include_verification_status:
            enrollment_mode = CourseEnrollment.enrollment_mode_for_user(
                student, course_key)[0]
            if include_verification_status:
                student_dict[
                    'verification_status'] = IDVerificationService.verification_status_for_user(
                        student, enrollment_mode)
            if include_enrollment_mode:
                student_dict['enrollment_mode'] = enrollment_mode

        return student_dict

    return [extract_student(student, features) for student in students]
예제 #19
0
def send_grade_if_interesting(user, course_run_key, mode, status, letter_grade, percent_grade, verbose=False):
    """ Checks if grade is interesting to Credentials and schedules a Celery task if so. """

    if verbose:
        msg = u"Starting send_grade_if_interesting with params: "\
            u"user [{username}], "\
            u"course_run_key [{key}], "\
            u"mode [{mode}], "\
            u"status [{status}], "\
            u"letter_grade [{letter_grade}], "\
            u"percent_grade [{percent_grade}], "\
            u"verbose [{verbose}]"\
            .format(
                username=getattr(user, 'username', None),
                key=str(course_run_key),
                mode=mode,
                status=status,
                letter_grade=letter_grade,
                percent_grade=percent_grade,
                verbose=verbose
            )
        log.info(msg)
    # Avoid scheduling new tasks if certification is disabled. (Grades are a part of the records/cert story)
    if not CredentialsApiConfig.current().is_learner_issuance_enabled:
        if verbose:
            log.info("Skipping send grade: is_learner_issuance_enabled False")
        return

    # Avoid scheduling new tasks if learner records are disabled for this site.
    if not helpers.get_value_for_org(course_run_key.org, 'ENABLE_LEARNER_RECORDS', True):
        if verbose:
            log.info(
                u"Skipping send grade: ENABLE_LEARNER_RECORDS False for org [{org}]".format(
                    org=course_run_key.org
                )
            )
        return

    # Grab mode/status if we don't have them in hand
    if mode is None or status is None:
        try:
            cert = GeneratedCertificate.objects.get(user=user, course_id=course_run_key)  # pylint: disable=no-member
            mode = cert.mode
            status = cert.status
        except GeneratedCertificate.DoesNotExist:
            # We only care about grades for which there is a certificate.
            if verbose:
                log.info(
                    u"Skipping send grade: no cert for user [{username}] & course_id [{course_id}]".format(
                        username=getattr(user, 'username', None),
                        course_id=str(course_run_key)
                    )
                )
            return

    # Don't worry about whether it's available as well as awarded. Just awarded is good enough to record a verified
    # attempt at a course. We want even the grades that didn't pass the class because Credentials wants to know about
    # those too.
    if mode not in INTERESTING_MODES or status not in INTERESTING_STATUSES:
        if verbose:
            log.info(
                u"Skipping send grade: mode/status uninteresting for mode [{mode}] & status [{status}]".format(
                    mode=mode,
                    status=status
                )
            )
        return

    # If the course isn't in any program, don't bother telling Credentials about it. When Credentials grows support
    # for course records as well as program records, we'll need to open this up.
    if not is_course_run_in_a_program(course_run_key):
        if verbose:
            log.info(
                u"Skipping send grade: course run not in a program. [{course_id}]".format(course_id=str(course_run_key))
            )
        return

    # Grab grades if we don't have them in hand
    if letter_grade is None or percent_grade is None:
        grade = CourseGradeFactory().read(user, course_key=course_run_key, create_if_needed=False)
        if grade is None:
            if verbose:
                log.info(
                    u"Skipping send grade: No grade found for user [{username}] & course_id [{course_id}]".format(
                        username=getattr(user, 'username', None),
                        course_id=str(course_run_key)
                    )
                )
            return
        letter_grade = grade.letter_grade
        percent_grade = grade.percent

    send_grade_to_credentials.delay(user.username, str(course_run_key), True, letter_grade, percent_grade)
def is_learner_records_enabled_for_org(org):
    return config_helpers.get_value_for_org(
        org, "ENABLE_LEARNER_RECORDS", ENABLE_LEARNER_RECORDS.is_enabled())
예제 #21
0
def handle_course_cert_changed(sender, user, course_key, mode, status,
                               **kwargs):
    """
        If a learner is awarded a course certificate,
        schedule a celery task to process that course certificate

        Args:
            sender:
                class of the object instance that sent this signal
            user:
                django.contrib.auth.User - the user to whom a cert was awarded
            course_key:
                refers to the course run for which the cert was awarded
            mode:
                mode / certificate type, e.g. "verified"
            status:
                "downloadable"

        Returns:
            None

        """
    # Import here instead of top of file since this module gets imported before
    # the credentials app is loaded, resulting in a Django deprecation warning.
    from openedx.core.djangoapps.credentials.models import CredentialsApiConfig

    verbose = kwargs.get('verbose', False)
    if verbose:
        msg = u"Starting handle_course_cert_changed with params: "\
            u"sender [{sender}], "\
            u"user [{username}], "\
            u"course_key [{course_key}], "\
            u"mode [{mode}], "\
            u"status [{status}], "\
            u"kwargs [{kw}]"\
            .format(
                sender=sender,
                username=getattr(user, 'username', None),
                course_key=str(course_key),
                mode=mode,
                status=status,
                kw=kwargs
            )

        LOGGER.info(msg)

    # Avoid scheduling new tasks if certification is disabled.
    if not CredentialsApiConfig.current().is_learner_issuance_enabled:
        if verbose:
            LOGGER.info(
                "Skipping send cert: is_learner_issuance_enabled False")
        return

    # Avoid scheduling new tasks if learner records are disabled for this site (right now, course certs are only
    # used for learner records -- when that changes, we can remove this bit and always send course certs).
    if not helpers.get_value_for_org(course_key.org, 'ENABLE_LEARNER_RECORDS',
                                     True):
        if verbose:
            LOGGER.info(
                u"Skipping send cert: ENABLE_LEARNER_RECORDS False for org [{org}]"
                .format(org=course_key.org))
        return

    # schedule background task to process
    LOGGER.debug(
        u'handling COURSE_CERT_CHANGED: username=%s, course_key=%s, mode=%s, status=%s',
        user,
        course_key,
        mode,
        status,
    )
    # import here, because signal is registered at startup, but items in tasks are not yet able to be loaded
    from openedx.core.djangoapps.programs.tasks.v1.tasks import award_course_certificate
    award_course_certificate.delay(user.username, str(course_key))
예제 #22
0
def handle_course_cert_changed(sender, user, course_key, mode, status, **kwargs):
    """
        If a learner is awarded a course certificate,
        schedule a celery task to process that course certificate

        Args:
            sender:
                class of the object instance that sent this signal
            user:
                django.contrib.auth.User - the user to whom a cert was awarded
            course_key:
                refers to the course run for which the cert was awarded
            mode:
                mode / certificate type, e.g. "verified"
            status:
                "downloadable"

        Returns:
            None

        """
    # Import here instead of top of file since this module gets imported before
    # the credentials app is loaded, resulting in a Django deprecation warning.
    from openedx.core.djangoapps.credentials.models import CredentialsApiConfig

    verbose = kwargs.get('verbose', False)
    if verbose:
        msg = "Starting handle_course_cert_changed with params: "\
            "sender [{sender}], "\
            "user [{username}], "\
            "course_key [{course_key}], "\
            "mode [{mode}], "\
            "status [{status}], "\
            "kwargs [{kw}]"\
            .format(
                sender=sender,
                username=getattr(user, 'username', None),
                course_key=str(course_key),
                mode=mode,
                status=status,
                kw=kwargs
            )

        LOGGER.info(msg)

    # Avoid scheduling new tasks if certification is disabled.
    if not CredentialsApiConfig.current().is_learner_issuance_enabled:
        if verbose:
            LOGGER.info("Skipping send cert: is_learner_issuance_enabled False")
        return

    # Avoid scheduling new tasks if learner records are disabled for this site (right now, course certs are only
    # used for learner records -- when that changes, we can remove this bit and always send course certs).
    if not helpers.get_value_for_org(course_key.org, 'ENABLE_LEARNER_RECORDS', True):
        if verbose:
            LOGGER.info(
                "Skipping send cert: ENABLE_LEARNER_RECORDS False for org [{org}]".format(
                    org=course_key.org
                )
            )
        return

    # schedule background task to process
    LOGGER.debug(
        'handling COURSE_CERT_CHANGED: username=%s, course_key=%s, mode=%s, status=%s',
        user,
        course_key,
        mode,
        status,
    )
    # import here, because signal is registered at startup, but items in tasks are not yet able to be loaded
    from openedx.core.djangoapps.programs.tasks.v1.tasks import award_course_certificate
    award_course_certificate.delay(user.username, str(course_key))