示例#1
0
    def to_dict(self):
        """
        Convert entitlement to dictionary representation including relevant policy information.

        Returns:
            The entitlement UUID
            The associated course's UUID
            The date at which the entitlement expired. None if it is still active.
            The localized string representing the date at which the entitlement expires.
        """
        expiration_date = None
        if self.get_days_until_expiration(
        ) < settings.ENTITLEMENT_EXPIRED_ALERT_PERIOD:
            expiration_date = strftime_localized(
                now() + timedelta(days=self.get_days_until_expiration()),
                'SHORT_DATE')
        expired_at = strftime_localized(
            self.expired_at_datetime,
            'SHORT_DATE') if self.expired_at_datetime else None

        return {
            'uuid': str(self.uuid),
            'course_uuid': str(self.course_uuid),
            'expired_at': expired_at,
            'expiration_date': expiration_date
        }
示例#2
0
def get_user_orders(user):
    """Given a user, get the detail of all the orders from the Ecommerce service.

    Args:
        user (User): The user to authenticate as when requesting ecommerce.

    Returns:
        list of dict, representing orders returned by the Ecommerce service.
    """
    user_orders = []
    commerce_configuration = CommerceConfiguration.current()
    user_query = {'username': user.username}

    use_cache = commerce_configuration.is_cache_enabled
    cache_key = commerce_configuration.CACHE_KEY + '.' + str(user.id) if use_cache else None
    api = ecommerce_api_client(user)
    commerce_user_orders = get_edx_api_data(
        commerce_configuration, 'orders', api=api, querystring=user_query, cache_key=cache_key
    )

    for order in commerce_user_orders:
        if order['status'].lower() == 'complete':
            date_placed = datetime.strptime(order['date_placed'], "%Y-%m-%dT%H:%M:%SZ")
            order_data = {
                'number': order['number'],
                'price': order['total_excl_tax'],
                'order_date': strftime_localized(date_placed, 'SHORT_DATE'),
                'receipt_url': EcommerceService().get_receipt_page_url(order['number']),
                'lines': order['lines'],
            }
            user_orders.append(order_data)

    return user_orders
示例#3
0
    def test_expired_course(self):
        """
        Ensure that a user accessing an expired course sees a redirect to
        the student dashboard, not a 404.
        """
        CourseDurationLimitConfig.objects.create(enabled=True, enabled_as_of=datetime(2010, 1, 1, tzinfo=UTC))
        course = CourseFactory.create(start=THREE_YEARS_AGO)
        url = course_home_url(course)

        for mode in [CourseMode.AUDIT, CourseMode.VERIFIED]:
            CourseModeFactory.create(course_id=course.id, mode_slug=mode)

        # assert that an if an expired audit user tries to access the course they are redirected to the dashboard
        audit_user = UserFactory(password=self.TEST_PASSWORD)
        self.client.login(username=audit_user.username, password=self.TEST_PASSWORD)
        audit_enrollment = CourseEnrollment.enroll(audit_user, course.id, mode=CourseMode.AUDIT)
        audit_enrollment.created = THREE_YEARS_AGO + timedelta(days=1)
        audit_enrollment.save()

        response = self.client.get(url)

        expiration_date = strftime_localized(course.start + timedelta(weeks=4) + timedelta(days=1), 'SHORT_DATE')
        expected_params = QueryDict(mutable=True)
        course_name = CourseOverview.get_from_id(course.id).display_name_with_default
        expected_params['access_response_error'] = 'Access to {run} expired on {expiration_date}'.format(
            run=course_name,
            expiration_date=expiration_date
        )
        expected_url = '{url}?{params}'.format(
            url=reverse('dashboard'),
            params=expected_params.urlencode()
        )
        self.assertRedirects(response, expected_url)
示例#4
0
def check_course_access_with_redirect(course, user, action, check_if_enrolled=False, check_survey_complete=True, check_if_authenticated=False):  # lint-amnesty, pylint: disable=line-too-long
    """
    Check that the user has the access to perform the specified action
    on the course (CourseBlock|CourseOverview).

    check_if_enrolled: If true, additionally verifies that the user is enrolled.
    check_survey_complete: If true, additionally verifies that the user has completed the survey.
    """
    request = get_current_request()
    check_content_start_date_for_masquerade_user(course.id, user, request,
                                                 course.start)

    access_response = check_course_access(course, user, action, check_if_enrolled, check_survey_complete, check_if_authenticated)  # lint-amnesty, pylint: disable=line-too-long

    if not access_response:
        # Redirect if StartDateError
        if isinstance(access_response, StartDateError):
            start_date = strftime_localized(course.start, 'SHORT_DATE')
            params = QueryDict(mutable=True)
            params['notlive'] = start_date
            raise CourseAccessRedirect(
                '{dashboard_url}?{params}'.format(
                    dashboard_url=reverse('dashboard'),
                    params=params.urlencode()), access_response)

        # Redirect if AuditExpiredError
        if isinstance(access_response, AuditExpiredError):
            params = QueryDict(mutable=True)
            params[
                'access_response_error'] = access_response.additional_context_user_message
            raise CourseAccessRedirect(
                '{dashboard_url}?{params}'.format(
                    dashboard_url=reverse('dashboard'),
                    params=params.urlencode()), access_response)

        # Redirect if the user must answer a survey before entering the course.
        if isinstance(access_response, MilestoneAccessError):
            raise CourseAccessRedirect(
                '{dashboard_url}'.format(dashboard_url=reverse('dashboard'), ),
                access_response)

        # Redirect if the user is not enrolled and must be to see content
        if isinstance(access_response, EnrollmentRequiredAccessError):
            raise CourseAccessRedirect(
                reverse('about_course', args=[str(course.id)]))

        # Redirect if user must be authenticated to view the content
        if isinstance(access_response, AuthenticationRequiredAccessError):
            raise CourseAccessRedirect(
                reverse('about_course', args=[str(course.id)]))

        # Redirect if the user must answer a survey before entering the course.
        if isinstance(access_response, SurveyRequiredAccessError):
            raise CourseAccessRedirect(
                reverse('course_survey', args=[str(course.id)]))

        # Deliberately return a non-specific error message to avoid
        # leaking info about access control settings
        raise CoursewareAccessException(access_response)
示例#5
0
 def test_usual_strftime_behavior(self, fmt_expected):
     (fmt, expected) = fmt_expected
     dtime = datetime(2013, 2, 14, 16, 41, 17)
     self.assertEqual(expected, strftime_localized(dtime, fmt))
     # strftime doesn't like Unicode, so do the work in UTF8.
     self.assertEqual(
         expected.encode('utf-8') if six.PY2 else expected,
         dtime.strftime(fmt.encode('utf-8') if six.PY2 else fmt))
示例#6
0
def _update_certificate_context(context, course, user_certificate, platform_name):
    """
    Build up the certificate web view context using the provided values
    (Helper method to keep the view clean)
    """
    # Populate dynamic output values using the course/certificate data loaded above
    certificate_type = context.get('certificate_type')

    # Override the defaults with any mode-specific static values
    context['certificate_id_number'] = user_certificate.verify_uuid
    context['certificate_verify_url'] = u"{prefix}{uuid}{suffix}".format(
        prefix=context.get('certificate_verify_url_prefix'),
        uuid=user_certificate.verify_uuid,
        suffix=context.get('certificate_verify_url_suffix')
    )

    # Translators:  The format of the date includes the full name of the month
    date = display_date_for_certificate(course, user_certificate)
    context['certificate_date_issued'] = _(u'{month} {day}, {year}').format(
        month=strftime_localized(date, "%B"),
        day=date.day,
        year=date.year
    )

    # Translators:  This text represents the verification of the certificate
    context['document_meta_description'] = _(u'This is a valid {platform_name} certificate for {user_name}, '
                                             u'who participated in {partner_short_name} {course_number}').format(
        platform_name=platform_name,
        user_name=context['accomplishment_copy_name'],
        partner_short_name=context['organization_short_name'],
        course_number=context['course_number']
    )

    # Translators:  This text is bound to the HTML 'title' element of the page and appears in the browser title bar
    context['document_title'] = _(u"{partner_short_name} {course_number} Certificate | {platform_name}").format(
        partner_short_name=context['organization_short_name'],
        course_number=context['course_number'],
        platform_name=platform_name
    )

    # Translators:  This text fragment appears after the student's name (displayed in a large font) on the certificate
    # screen.  The text describes the accomplishment represented by the certificate information displayed to the user
    context['accomplishment_copy_description_full'] = _(u"successfully completed, received a passing grade, and was "
                                                        u"awarded this {platform_name} {certificate_type} "
                                                        u"Certificate of Completion in ").format(
        platform_name=platform_name,
        certificate_type=context.get("certificate_type"))

    certificate_type_description = get_certificate_description(user_certificate.mode, certificate_type, platform_name)
    if certificate_type_description:
        context['certificate_type_description'] = certificate_type_description

    # Translators: This text describes the purpose (and therefore, value) of a course certificate
    context['certificate_info_description'] = _(u"{platform_name} acknowledges achievements through "
                                                u"certificates, which are awarded for course activities "
                                                u"that {platform_name} students complete.").format(
        platform_name=platform_name,
    )
示例#7
0
def enforce_compliance_on_login(user, password):
    """
    Verify that the user's password is compliant with password policy rules and determine what should be done
    if it is not.

    Raises NonCompliantPasswordException when the password is found to be non-compliant and the compliance deadline
    for the user has been reached. In this case, login should be prevented.

    Raises NonCompliantPasswordWarning when the password is found to be non-compliant and the compliance deadline for
    the user is in the future.

    Returns None when the password is found to be compliant, or when no deadline for compliance has been set for the
    user.

    Important: This method should only be called AFTER the user has been authenticated.
    """
    is_compliant = _check_user_compliance(user, password)
    if is_compliant:
        return

    deadline = _get_compliance_deadline_for_user(user)
    if deadline is None:
        return

    now = datetime.now(pytz.UTC)
    if now >= deadline:  # lint-amnesty, pylint: disable=no-else-raise
        raise NonCompliantPasswordException(
            HTML(_(
                '{strong_tag_open}We recently changed our password requirements{strong_tag_close}{break_line_tag}'
                'Your current password does not meet the new security requirements. We just sent a password-reset '
                'message to the email address associated with this account. Thank you for helping us keep your data '
                'safe.'
            )).format(
                strong_tag_open=HTML('<strong>'),
                strong_tag_close=HTML('</strong>'),
                break_line_tag=HTML('<br/>'),
            )
        )
    else:
        raise NonCompliantPasswordWarning(
            HTML(_(
                '{strong_tag_open}Required Action: Please update your password{strong_tag_close}{break_line_tag}'
                'As of {deadline}, {platform_name} will require all learners to have complex passwords. Your current '
                'password does not meet these requirements. To reset your password, go to to '
                '{anchor_tag_open}Account Settings{anchor_tag_close}.'
            )).format(
                strong_tag_open=HTML('<strong>'),
                strong_tag_close=HTML('</strong>'),
                break_line_tag=HTML('<br/>'),
                platform_name=settings.PLATFORM_NAME,
                deadline=strftime_localized(deadline, DEFAULT_SHORT_DATE_FORMAT),
                anchor_tag_open=HTML('<a href="{account_settings_url}">').format(
                    account_settings_url=settings.LMS_ROOT_URL + "/account/settings"
                ),
                anchor_tag_close=HTML('</a>')
            )
        )
示例#8
0
def get_expiration_banner_text(user, course, language='en'):
    """
    Get text for banner that messages user course expiration date
    for different tests that depend on it.
    """
    upgrade_link = verified_upgrade_deadline_link(user=user, course=course)
    enrollment = CourseEnrollment.get_enrollment(user, course.id)
    expiration_date = enrollment.created + timedelta(weeks=4)
    upgrade_deadline = enrollment.upgrade_deadline
    if upgrade_deadline is None or now() < upgrade_deadline:
        upgrade_deadline = enrollment.course_upgrade_deadline

    date_string = u'<span class="localized-datetime" data-format="shortDate" data-timezone="None" \
        data-datetime="{formatted_date}" data-language="{language}">{formatted_date_localized}</span>'
    formatted_expiration_date = date_string.format(
        language=language,
        formatted_date=expiration_date.isoformat(),
        formatted_date_localized=strftime_localized(expiration_date, EXPIRATION_DATE_FORMAT_STR)
    )
    if upgrade_deadline:
        formatted_upgrade_deadline = date_string.format(
            language=language,
            formatted_date=upgrade_deadline.isoformat(),
            formatted_date_localized=strftime_localized(upgrade_deadline, EXPIRATION_DATE_FORMAT_STR)
        )

        bannerText = u'<strong>Audit Access Expires {expiration_date}</strong><br>\
                     You lose all access to this course, including your progress, on {expiration_date}.\
                     <br>Upgrade by {upgrade_deadline} to get unlimited access to the course as long as it exists\
                     on the site. <a id="FBE_banner" href="{upgrade_link}">Upgrade now<span class="sr-only"> to retain access past\
                     {expiration_date}</span></a>'.format(
            expiration_date=formatted_expiration_date,
            upgrade_link=upgrade_link,
            upgrade_deadline=formatted_upgrade_deadline
        )
    else:
        bannerText = u'<strong>Audit Access Expires {expiration_date}</strong><br>\
                     You lose all access to this course, including your progress, on {expiration_date}.\
                     '.format(
            expiration_date=formatted_expiration_date
        )
    return bannerText
示例#9
0
def get_formatted_date(date_to_format, formatting):
    """
    Takes a date and a format to return a string in the desired format

    Arguments:
        date_to_format (datetime.datetime): Date that we want to format
        formatting (str): The format we want the result to be in

    Returns:
        str: Formatted date
    """
    return strftime_localized(date_to_format, formatting
                              or '') if date_to_format else ''
示例#10
0
def convert_date_time_zone_and_format(date_time_object, time_zone,
                                      time_format):
    """
    Change time zone of datetime object and return a formatted string
    Args:
        date_time_object (datetime): datetime object
        time_zone (string): a time zone string
        time_format (string): a time format string
    Returns:
        DateTime(string)
    """
    date_in_desired_timezone = convert_timezone(date_time_object, time_zone)
    return strftime_localized(date_in_desired_timezone, time_format)
示例#11
0
 def test_non_live_course(self):
     """Ensure that a user accessing a non-live course sees a redirect to
     the student dashboard, not a 404.
     """
     self.setup_user()
     self.enroll(self.course)
     url = reverse('info', args=[str(self.course.id)])
     response = self.client.get(url)
     start_date = strftime_localized(self.course.start, 'SHORT_DATE')
     expected_params = QueryDict(mutable=True)
     expected_params['notlive'] = start_date
     expected_url = '{url}?{params}'.format(
         url=reverse('dashboard'), params=expected_params.urlencode())
     self.assertRedirects(response, expected_url)
示例#12
0
    def strftime(self, *args, **kwargs):
        """
        A locale-aware implementation of strftime.
        """
        # This is the wrong place to import this function.  I'm putting it here
        # because the xmodule test suite can't import this module, because
        # Django is not available in that suite.  This function isn't called in
        # that suite, so this hides the import so the test won't fail.
        #
        # As I said, this is wrong.  But Cale says this code will soon be
        # refactored to a place that will be right, and the code can be made
        # right there.  If you are reading this comment after April 1, 2014,
        # then Cale was a liar.
        from common.djangoapps.util.date_utils import strftime_localized

        return strftime_localized(*args, **kwargs)
示例#13
0
    def test_non_live_course(self):
        """
        Ensure that a user accessing a non-live course sees a redirect to
        the student dashboard, not a 404.
        """
        future_course = self.create_future_course()
        self.create_user_for_course(future_course, CourseUserType.ENROLLED)

        url = course_home_url(future_course)
        response = self.client.get(url)
        start_date = strftime_localized(future_course.start, 'SHORT_DATE')
        expected_params = QueryDict(mutable=True)
        expected_params['notlive'] = start_date
        expected_url = '{url}?{params}'.format(
            url=reverse('dashboard'), params=expected_params.urlencode())
        self.assertRedirects(response, expected_url)
示例#14
0
def construct_arabic_datetime_string(date_time_object, output_format):
    """
    Create the correct Arabic language localized date string based on the string
    format provided

    Args:
        date_time_object (datetime): Datetime date, time or datetime object
        output_format (str): Output formatting for the datetime object

    Returns:
        str: Localized arabic output string in the specified format
    """
    date_in_AST = convert_timezone(date_time_object, WEBINAR_DEFAULT_TIME_ZONE)

    with override(ARABIC_LANGUAGE_CODE):
        if output_format == WEBINAR_DATE_TIME_FORMAT:
            return '{week_day}, {month} {day}, {year} {hours}:{minutes} {time_format} AST'.format(
                week_day=strftime_localized(date_in_AST, '%A'),
                month=strftime_localized(date_in_AST, '%B'),
                day=date_in_AST.day,
                year=date_in_AST.year,
                hours=strftime_localized(date_in_AST, '%I'),
                minutes=strftime_localized(date_in_AST, '%M'),
                time_format=strftime_localized(date_in_AST, '%p'),
            )

        elif output_format == WEBINAR_DATE_FORMAT:
            return '{month} {day}, {year}'.format(month=strftime_localized(
                date_in_AST, '%B'),
                                                  day=date_in_AST.day,
                                                  year=date_in_AST.year)

        elif output_format == WEBINAR_TIME_FORMAT:
            return '{hours}:{minutes}, {time_format} AST'.format(
                hours=strftime_localized(date_in_AST, '%I'),
                minutes=strftime_localized(date_in_AST, '%M'),
                time_format=strftime_localized(date_in_AST, '%p'),
            )
示例#15
0
def get_arabic_certificate_extra_context(request, course_id):
    """
    Compute `date_issued` and `gender` for the Arabic Course Certificates.

    This method is used directly from arabic certificate template. This is done to avoid core changes and customise the
    Arabic certificates. To display gender specific text, we need to send gender in context. Date formatting is also
    custom for Arabic certificates so this method returns date in the required format as well.

    Args:
        request (WSGIRequest): request object
        course_id (str): Course Id

    Returns:
        tuple: Gender of the learner and Date issued.
    """
    certificate = None
    certificate_uuid = request.resolver_match.kwargs.get('certificate_uuid', None)
    if certificate_uuid:
        certificate = GeneratedCertificate.eligible_certificates.filter(
            verify_uuid=certificate_uuid,
            status=CertificateStatuses.downloadable
        ).first()

    user = certificate.user if certificate else request.user
    course_key = CourseKey.from_string(course_id)
    course = get_course_by_id(course_key)

    if not certificate:
        preview_mode = request.GET.get('preview', None)
        certificate = _get_user_certificate(request, user, course_key, course, preview_mode)

    date_format = u'{day} {month} {year}' if course.language == ARABIC_LANGUAGE_CODE else u'{month} {day}, {year}'
    display_date = display_date_for_certificate(course, certificate)

    with translation.override(ARABIC_LANGUAGE_CODE):
        date_issued = _(date_format).format(  # pylint: disable=translation-of-non-string
            month=strftime_localized(display_date, '%B'),
            day=display_date.day,
            year=display_date.year
        )

    return user.profile.gender, date_issued
    def __init__(self, user, course, expiration_date):
        error_code = 'audit_expired'
        developer_message = f'User {user} had access to {course} until {expiration_date}'
        expiration_date = strftime_localized(expiration_date, 'SHORT_DATE')
        user_message = _('Access expired on {expiration_date}').format(
            expiration_date=expiration_date)
        try:
            course_name = course.display_name_with_default
            additional_context_user_message = _(
                'Access to {course_name} expired on {expiration_date}').format(
                    course_name=course_name, expiration_date=expiration_date)
        except CourseOverview.DoesNotExist:
            additional_context_user_message = _(
                'Access to the course you were looking'
                ' for expired on {expiration_date}').format(
                    expiration_date=expiration_date)

        # lint-amnesty, pylint: disable=super-with-arguments
        super().__init__(error_code, developer_message, user_message,
                         additional_context_user_message)
示例#17
0
 def __init__(self, user, course, expiration_date):
     error_code = 'audit_expired'
     developer_message = 'User {} had access to {} until {}'.format(
         user, course, expiration_date)
     expiration_date = strftime_localized(expiration_date, 'SHORT_DATE')
     user_message = _('Access expired on {expiration_date}').format(
         expiration_date=expiration_date)
     try:
         course_name = course.display_name_with_default
         additional_context_user_message = _(
             'Access to {course_name} expired on {expiration_date}').format(
                 course_name=course_name, expiration_date=expiration_date)
     except CourseOverview.DoesNotExist:
         additional_context_user_message = _(
             'Access to the course you were looking'
             ' for expired on {expiration_date}').format(
                 expiration_date=expiration_date)
     super(AuditExpiredError,
           self).__init__(error_code, developer_message, user_message,
                          additional_context_user_message)
示例#18
0
 def __init__(self, user, course, expiration_date):
     error_code = "audit_expired"
     developer_message = u"User {} had access to {} until {}".format(
         user, course, expiration_date)
     expiration_date = strftime_localized(expiration_date,
                                          EXPIRATION_DATE_FORMAT_STR)
     user_message = _(u"Access expired on {expiration_date}").format(
         expiration_date=expiration_date)
     try:
         course_name = course.display_name_with_default
         additional_context_user_message = _(
             u"Access to {course_name} expired on {expiration_date}"
         ).format(course_name=course_name, expiration_date=expiration_date)
     except CourseOverview.DoesNotExist:
         additional_context_user_message = _(
             u"Access to the course you were looking"
             u" for expired on {expiration_date}").format(
                 expiration_date=expiration_date)
     super(AuditExpiredError,
           self).__init__(error_code, developer_message, user_message,
                          additional_context_user_message)
示例#19
0
def get_weekly_application_submissions(submitted_applications,
                                       number_of_weeks):
    """
    Calculates the number of submitted applications for the past few weeks, sent as argument, including the current
    week.

    Arguments:
        submitted_applications (QuerySet): queryset containing submitted applications
        number_of_weeks (int): number of weeks for which weekly submissions need to be calculated

    Returns:
        JSON: a json object containing two lists: one for dates of the past 12 weeks and the other for number of
        application submissions in those weeks
    """
    today = datetime.today()
    start_of_week = today - timedelta(days=today.weekday())

    submissions_list = [0] * number_of_weeks
    date_list = [''] * number_of_weeks
    start_date = start_of_week
    end_date = today

    for index in range(number_of_weeks - 1, -1, -1):
        filtered_applications_count = submitted_applications.get_submitted_applications_count_in_date_range(
            start_date, end_date)

        submissions_list[index] = filtered_applications_count
        date_list[index] = strftime_localized(
            start_date, WEEKLY_SUBMISSIONS_GRAPH_DATE_FORMAT)

        end_date = start_date - timedelta(days=1)
        start_date = start_date - timedelta(days=7)

    return json.dumps({
        'submissions_list': submissions_list,
        'date_list': date_list
    })
示例#20
0
    def get_certificates(self):
        """
        Get certificates data for user.

        Returns:
            list: Contains dicts which has data for all the courses.
        """
        user = self.request.user
        certificates = GeneratedCertificate.eligible_certificates.filter(
            user=user).order_by('course_id')

        certificate_data = []
        for cert in certificates:
            formatted_cert = format_certificate_for_user(user.username, cert)

            if formatted_cert:
                course = get_course_by_id(cert.course_id)
                formatted_cert['course_display_name'] = course.display_name
                formatted_cert['date_created'] = strftime_localized(
                    display_date_for_certificate(course, cert), '%b %d, %Y')

                certificate_data.append(formatted_cert)

        return certificate_data
示例#21
0
 def _attach_course_run_enrollment_open_date(self, run_mode):
     run_mode['enrollment_open_date'] = strftime_localized(
         self.enrollment_start, 'SHORT_DATE')
示例#22
0
 def test_invalid_format_strings(self, fmt):
     dtime = datetime(2013, 2, 14, 16, 41, 17)
     with self.assertRaises(ValueError):
         strftime_localized(dtime, fmt)
示例#23
0
 def test_recursion_protection(self, fmt_expected):
     (fmt, expected) = fmt_expected
     dtime = datetime(2013, 2, 14, 16, 41, 17)
     self.assertEqual(expected, strftime_localized(dtime, fmt))
示例#24
0
 def test_usual_strftime_behavior(self, fmt_expected):
     (fmt, expected) = fmt_expected
     dtime = datetime(2013, 2, 14, 16, 41, 17)
     self.assertEqual(expected, strftime_localized(dtime, fmt))
     self.assertEqual(expected, dtime.strftime(fmt))
示例#25
0
 def test_shortcuts(self, fmt_expected):
     (fmt, expected) = fmt_expected
     dtime = datetime(2013, 2, 14, 16, 41, 17)
     assert expected == strftime_localized(dtime, fmt)
示例#26
0
 def test_translated_words(self, fmt_expected):
     (fmt, expected) = fmt_expected
     dtime = datetime(2013, 2, 14, 16, 41, 17)
     assert expected == strftime_localized(dtime, fmt)
示例#27
0
def _update_certificate_context(context, course, course_overview,
                                user_certificate, platform_name):
    """
    Build up the certificate web view context using the provided values
    (Helper method to keep the view clean)
    """
    # Populate dynamic output values using the course/certificate data loaded above
    certificate_type = context.get('certificate_type')

    # Override the defaults with any mode-specific static values
    context['certificate_id_number'] = user_certificate.verify_uuid
    context['certificate_verify_url'] = "{prefix}{uuid}{suffix}".format(
        prefix=context.get('certificate_verify_url_prefix'),
        uuid=user_certificate.verify_uuid,
        suffix=context.get('certificate_verify_url_suffix'))

    # We prefer a CourseOverview for this function because it validates and corrects certificate_available_date
    # and certificates_display_behavior values. However, not all certificates are guaranteed to have a CourseOverview
    # associated with them, so we fall back on the course in that case. This shouldn't cause a problem because courses
    # that are missing CourseOverviews are generally old courses, and thus their display values are no longer relevant
    if course_overview:
        date = display_date_for_certificate(course_overview, user_certificate)
    else:
        date = display_date_for_certificate(course, user_certificate)
    # Translators:  The format of the date includes the full name of the month
    context['certificate_date_issued'] = strftime_localized(
        date, settings.CERTIFICATE_DATE_FORMAT)

    # Translators:  This text represents the verification of the certificate
    context['document_meta_description'] = _(
        'This is a valid {platform_name} certificate for {user_name}, '
        'who participated in {partner_short_name} {course_number}').format(
            platform_name=platform_name,
            user_name=context['accomplishment_copy_name'],
            partner_short_name=context['organization_short_name'],
            course_number=context['course_number'])

    # Translators:  This text is bound to the HTML 'title' element of the page and appears in the browser title bar
    context['document_title'] = _(
        "{partner_short_name} {course_number} Certificate | {platform_name}"
    ).format(partner_short_name=context['organization_short_name'],
             course_number=context['course_number'],
             platform_name=platform_name)

    # Translators:  This text fragment appears after the student's name (displayed in a large font) on the certificate
    # screen.  The text describes the accomplishment represented by the certificate information displayed to the user
    context['accomplishment_copy_description_full'] = _(
        "successfully completed, received a passing grade, and was "
        "awarded this {platform_name} {certificate_type} "
        "Certificate of Completion in ").format(
            platform_name=platform_name,
            certificate_type=context.get("certificate_type"))

    certificate_type_description = get_certificate_description(
        user_certificate.mode, certificate_type, platform_name,
        course.location.course_key)
    if certificate_type_description:
        context['certificate_type_description'] = certificate_type_description

    # Translators: This text describes the purpose (and therefore, value) of a course certificate
    context['certificate_info_description'] = _(
        "{platform_name} acknowledges achievements through "
        "certificates, which are awarded for course activities "
        "that {platform_name} students complete.").format(
            platform_name=platform_name, )
示例#28
0
    def assertDateInMessage(self, date, message):  # lint-amnesty, pylint: disable=missing-function-docstring
        # First, check that the formatted version is in there
        assert strftime_localized(date, 'SHORT_DATE') in message

        # But also that the machine-readable version is in there
        assert 'data-datetime="%s"' % date.isoformat() in message
示例#29
0
 def test_translated_formats(self, fmt_expected):
     (fmt, expected) = fmt_expected
     dtime = datetime(2013, 2, 14, 16, 41, 17)
     self.assertEqual(expected, strftime_localized(dtime, fmt))
示例#30
0
def generate_course_expired_message(user, course):
    """
    Generate the message for the user course expiration date if it exists.
    """
    expiration_date = get_user_course_expiration_date(user, course)
    if not expiration_date:
        return

    user_timezone_locale = user_timezone_locale_prefs(
        crum.get_current_request())
    user_timezone = user_timezone_locale['user_timezone']

    now = timezone.now()
    if is_masquerading_as_specific_student(
            user, course.id) and now > expiration_date:
        upgrade_message = _(
            'This learner does not have access to this course. '
            u'Their access expired on {expiration_date}.')
        return HTML(upgrade_message).format(expiration_date=strftime_localized(
            expiration_date, EXPIRATION_DATE_FORMAT_STR))
    else:
        enrollment = CourseEnrollment.get_enrollment(user, course.id)
        if enrollment is None:
            return

        upgrade_deadline = enrollment.upgrade_deadline
        if (not upgrade_deadline) or (upgrade_deadline < now):
            upgrade_deadline = enrollment.course_upgrade_deadline

        expiration_message = _(
            u'{strong_open}Audit Access Expires {expiration_date}{strong_close}'
            u'{line_break}You lose all access to this course, including your progress, on '
            u'{expiration_date}.')
        upgrade_deadline_message = _(
            u'{line_break}Upgrade by {upgrade_deadline} to get unlimited access to the course '
            u'as long as it exists on the site. {a_open}Upgrade now{sronly_span_open} to '
            u'retain access past {expiration_date}{span_close}{a_close}')
        full_message = expiration_message
        if upgrade_deadline and now < upgrade_deadline:
            full_message += upgrade_deadline_message
            using_upgrade_messaging = True
        else:
            using_upgrade_messaging = False

        language = get_language()
        date_string = get_date_string()
        formatted_expiration_date = date_string.format(
            language=language,
            user_timezone=user_timezone,
            formatted_date=expiration_date.isoformat(),
            formatted_date_localized=strftime_localized(
                expiration_date, EXPIRATION_DATE_FORMAT_STR))
        if using_upgrade_messaging:
            formatted_upgrade_deadline = date_string.format(
                language=language,
                user_timezone=user_timezone,
                formatted_date=upgrade_deadline.isoformat(),
                formatted_date_localized=strftime_localized(
                    upgrade_deadline, EXPIRATION_DATE_FORMAT_STR))

            return HTML(full_message).format(
                a_open=HTML(u'<a id="FBE_banner" href="{upgrade_link}">').
                format(upgrade_link=verified_upgrade_deadline_link(
                    user=user, course=course)),
                sronly_span_open=HTML('<span class="sr-only">'),
                span_close=HTML('</span>'),
                a_close=HTML('</a>'),
                expiration_date=HTML(formatted_expiration_date),
                strong_open=HTML('<strong>'),
                strong_close=HTML('</strong>'),
                line_break=HTML('<br>'),
                upgrade_deadline=HTML(formatted_upgrade_deadline))

        else:
            return HTML(full_message).format(
                span_close=HTML('</span>'),
                expiration_date=HTML(formatted_expiration_date),
                strong_open=HTML('<strong>'),
                strong_close=HTML('</strong>'),
                line_break=HTML('<br>'),
            )