Schedules: convert course language to supported released language
This commit is contained in:
@@ -40,7 +40,7 @@ from courseware.courses import get_course_by_id
|
||||
from edxmako.shortcuts import render_to_response
|
||||
from edxmako.template import Template
|
||||
from openedx.core.djangoapps.catalog.utils import get_course_run_details
|
||||
from openedx.core.djangoapps.lang_pref.api import released_languages
|
||||
from openedx.core.djangoapps.lang_pref.api import get_closest_released_language
|
||||
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
|
||||
from openedx.core.lib.courses import course_image_url
|
||||
from openedx.core.djangoapps.certificates.api import display_date_for_certificate, certificates_viewable_for_course
|
||||
@@ -656,7 +656,7 @@ def _get_custom_template_and_language(course_id, course_mode, course_language):
|
||||
Return the custom certificate template, if any, that should be rendered for the provided course/mode/language
|
||||
combination, along with the language that should be used to render that template.
|
||||
"""
|
||||
closest_released_language = _get_closest_released_language(course_language) if course_language else None
|
||||
closest_released_language = get_closest_released_language(course_language) if course_language else None
|
||||
template = get_certificate_template(course_id, course_mode, closest_released_language)
|
||||
|
||||
if template and template.language:
|
||||
@@ -667,24 +667,6 @@ def _get_custom_template_and_language(course_id, course_mode, course_language):
|
||||
return (None, None)
|
||||
|
||||
|
||||
def _get_closest_released_language(target):
|
||||
"""
|
||||
Return the language code that most closely matches the target and is fully supported by the LMS, or None
|
||||
if there are no fully supported languages that match the target.
|
||||
"""
|
||||
match = None
|
||||
languages = released_languages()
|
||||
|
||||
for language in languages:
|
||||
if language.code == target:
|
||||
match = language.code
|
||||
break
|
||||
elif (match is None) and (language.code[:2] == target[:2]):
|
||||
match = language.code
|
||||
|
||||
return match
|
||||
|
||||
|
||||
def _render_invalid_certificate(course_id, platform_name, configuration):
|
||||
context = {}
|
||||
_update_context_with_basic_info(context, course_id, platform_name, configuration)
|
||||
|
||||
@@ -17,6 +17,7 @@ from model_utils.models import TimeStampedModel
|
||||
from config_models.models import ConfigurationModel
|
||||
from lms.djangoapps import django_comment_client
|
||||
from openedx.core.djangoapps.catalog.models import CatalogIntegration
|
||||
from openedx.core.djangoapps.lang_pref.api import get_closest_released_language
|
||||
from openedx.core.djangoapps.models.course_details import CourseDetails
|
||||
from static_replace.models import AssetBaseUrlConfig
|
||||
from xmodule import course_metadata_utils, block_metadata_utils
|
||||
@@ -610,6 +611,15 @@ class CourseOverview(TimeStampedModel):
|
||||
"""
|
||||
return 'self' if self.self_paced else 'instructor'
|
||||
|
||||
@property
|
||||
def closest_released_language(self):
|
||||
"""
|
||||
Returns the language code that most closely matches this course' language and is fully
|
||||
supported by the LMS, or None if there are no fully supported languages that
|
||||
match the target.
|
||||
"""
|
||||
return get_closest_released_language(self.language) if self.language else None
|
||||
|
||||
def apply_cdn_to_urls(self, image_urls):
|
||||
"""
|
||||
Given a dict of resolutions -> urls, return a copy with CDN applied.
|
||||
|
||||
@@ -18,6 +18,7 @@ from PIL import Image
|
||||
|
||||
from lms.djangoapps.certificates.api import get_active_web_certificate
|
||||
from openedx.core.djangoapps.catalog.tests.mixins import CatalogIntegrationMixin
|
||||
from openedx.core.djangoapps.dark_lang.models import DarkLangConfig
|
||||
from openedx.core.djangoapps.models.course_details import CourseDetails
|
||||
from openedx.core.lib.courses import course_image_url
|
||||
from static_replace.models import AssetBaseUrlConfig
|
||||
@@ -37,6 +38,7 @@ from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
|
||||
from xmodule.modulestore.tests.factories import CourseFactory, check_mongo_calls_range
|
||||
|
||||
from ..models import CourseOverview, CourseOverviewImageSet, CourseOverviewImageConfig
|
||||
from .factories import CourseOverviewFactory
|
||||
|
||||
|
||||
@attr(shard=3)
|
||||
@@ -289,6 +291,21 @@ class CourseOverviewTestCase(CatalogIntegrationMixin, ModuleStoreTestCase):
|
||||
else:
|
||||
self.assertEqual(course_overview.language, course.language)
|
||||
|
||||
@ddt.data(
|
||||
('fa', 'fa-ir', 'fa'),
|
||||
('fa', 'fa', 'fa'),
|
||||
('es-419', 'es-419', 'es-419'),
|
||||
('es-419', 'es-es', 'es-419'),
|
||||
('es-419', 'es', 'es-419'),
|
||||
('es-419', None, None),
|
||||
('es-419', 'fr', None),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_closest_released_language(self, released_languages, course_language, expected_language):
|
||||
DarkLangConfig(released_languages=released_languages, enabled=True, changed_by=self.user).save()
|
||||
course_overview = CourseOverviewFactory.create(language=course_language)
|
||||
self.assertEqual(course_overview.closest_released_language, expected_language)
|
||||
|
||||
@ddt.data(ModuleStoreEnum.Type.split, ModuleStoreEnum.Type.mongo)
|
||||
def test_get_non_existent_course(self, modulestore_type):
|
||||
"""
|
||||
|
||||
@@ -73,3 +73,22 @@ def all_languages():
|
||||
"""
|
||||
languages = [(lang[0], _(lang[1])) for lang in settings.ALL_LANGUAGES] # pylint: disable=translation-of-non-string
|
||||
return sorted(languages, key=lambda lang: lang[1])
|
||||
|
||||
|
||||
def get_closest_released_language(target_language_code):
|
||||
"""
|
||||
Return the language code that most closely matches the target and is fully
|
||||
supported by the LMS, or None if there are no fully supported languages that
|
||||
match the target.
|
||||
"""
|
||||
match = None
|
||||
languages = released_languages()
|
||||
|
||||
for language in languages:
|
||||
if language.code == target_language_code:
|
||||
match = language.code
|
||||
break
|
||||
elif (match is None) and (language.code[:2] == target_language_code[:2]):
|
||||
match = language.code
|
||||
|
||||
return match
|
||||
|
||||
@@ -195,7 +195,7 @@ class BinnedSchedulesBaseResolver(PrefixedDebugLoggerMixin, RecipientResolver):
|
||||
except InvalidContextError:
|
||||
continue
|
||||
|
||||
yield (user, first_schedule.enrollment.course.language, template_context)
|
||||
yield (user, first_schedule.enrollment.course.closest_released_language, template_context)
|
||||
|
||||
def get_template_context(self, user, user_schedules):
|
||||
"""
|
||||
@@ -317,7 +317,7 @@ def _get_upsell_information_for_schedule(user, schedule):
|
||||
enrollment.dynamic_upgrade_deadline,
|
||||
get_format(
|
||||
'DATE_FORMAT',
|
||||
lang=course.language,
|
||||
lang=course.closest_released_language,
|
||||
use_l10n=True
|
||||
)
|
||||
)
|
||||
@@ -370,7 +370,7 @@ class CourseUpdateResolver(BinnedSchedulesBaseResolver):
|
||||
})
|
||||
template_context.update(_get_upsell_information_for_schedule(user, schedule))
|
||||
|
||||
yield (user, schedule.enrollment.course.language, template_context)
|
||||
yield (user, schedule.enrollment.course.closest_released_language, template_context)
|
||||
|
||||
|
||||
def _get_trackable_course_home_url(course_id):
|
||||
|
||||
Reference in New Issue
Block a user