From 5594796c3045ccdb59778d2455d1ba796efcc71e Mon Sep 17 00:00:00 2001 From: Maria Fernanda Magallanes Zubillaga Date: Wed, 21 Jun 2023 14:53:30 -0500 Subject: [PATCH] feat: having released_languages tenant and site aware --- .../backends/dark_lang_middleware_o_v1.py | 5 +++ .../edxapp_wrapper/dark_lang_middleware.py | 11 +++++ eox_tenant/settings/common.py | 1 + .../released_languages.py | 38 +++++++++++++++++ eox_tenant/tenant_wise/__init__.py | 15 ++++++- eox_tenant/tenant_wise/proxies.py | 42 ++++++++++++++++++- 6 files changed, 109 insertions(+), 3 deletions(-) create mode 100644 eox_tenant/edxapp_wrapper/backends/dark_lang_middleware_o_v1.py create mode 100644 eox_tenant/edxapp_wrapper/dark_lang_middleware.py create mode 100644 eox_tenant/tenant_aware_functions/released_languages.py diff --git a/eox_tenant/edxapp_wrapper/backends/dark_lang_middleware_o_v1.py b/eox_tenant/edxapp_wrapper/backends/dark_lang_middleware_o_v1.py new file mode 100644 index 00000000..d04b491d --- /dev/null +++ b/eox_tenant/edxapp_wrapper/backends/dark_lang_middleware_o_v1.py @@ -0,0 +1,5 @@ +from openedx.core.djangoapps.dark_lang.middleware import DarkLangMiddleware + +def get_dark_lang_middleware(): + """Backend to get the DarkLangMiddleware from openedx.""" + return DarkLangMiddleware diff --git a/eox_tenant/edxapp_wrapper/dark_lang_middleware.py b/eox_tenant/edxapp_wrapper/dark_lang_middleware.py new file mode 100644 index 00000000..7ee55bf2 --- /dev/null +++ b/eox_tenant/edxapp_wrapper/dark_lang_middleware.py @@ -0,0 +1,11 @@ +""" Backend abstraction. """ +from importlib import import_module + +from django.conf import settings + + +def get_dark_lang_middleware(*args, **kwargs): + """ Get DarkLangMiddleware. """ + backend_function = settings.DARK_LANG_MIDDLEWARE + backend = import_module(backend_function) + return backend.get_dark_lang_middleware(*args, **kwargs) diff --git a/eox_tenant/settings/common.py b/eox_tenant/settings/common.py index a866ec6c..789911fd 100644 --- a/eox_tenant/settings/common.py +++ b/eox_tenant/settings/common.py @@ -48,6 +48,7 @@ def plugin_settings(settings): settings.EDXMAKO_MODULE_BACKEND = 'eox_tenant.edxapp_wrapper.backends.edxmako_l_v1' settings.UTILS_MODULE_BACKEND = 'eox_tenant.edxapp_wrapper.backends.util_h_v1' settings.CHANGE_DOMAIN_DEFAULT_SITE_NAME = "stage.edunext.co" + settings.DARK_LANG_MIDDLEWARE = 'eox_tenant.edxapp_wrapper.backends.dark_lang_middleware_o_v1' settings.EOX_TENANT_LOAD_PERMISSIONS = True settings.EOX_TENANT_APPEND_LMS_MIDDLEWARE_CLASSES = False settings.USE_EOX_TENANT = False diff --git a/eox_tenant/tenant_aware_functions/released_languages.py b/eox_tenant/tenant_aware_functions/released_languages.py new file mode 100644 index 00000000..6f996d02 --- /dev/null +++ b/eox_tenant/tenant_aware_functions/released_languages.py @@ -0,0 +1,38 @@ +from collections import namedtuple + +from django.conf import settings + +Language = namedtuple('Language', 'code name') + +def tenant_languages(): + """Retrieve the list of released languages by tenant. + + Constructs a list of Language tuples by intersecting the + list of valid language tuples with the list of released + language codes. + + Returns: + list of Language: Languages in which full translations are available. + + Example: + + >>> print released_languages() + [Language(code='en', name=u'English'), Language(code='fr', name=u'Français')] + + """ + released_languages = getattr(settings, "released_languages", "") + released_language_codes = [lang.lower().strip() for lang in released_languages.split(',')] + default_language_code = settings.LANGUAGE_CODE + + if default_language_code not in released_language_codes: + released_language_codes.append(default_language_code) + + released_language_codes.sort() + + # Intersect the list of valid language tuples with the list + # of released language codes + return [ + Language(language_info[0], language_info[1]) + for language_info in settings.LANGUAGES + if language_info[0] in released_language_codes + ] diff --git a/eox_tenant/tenant_wise/__init__.py b/eox_tenant/tenant_wise/__init__.py index df545f71..3b89d194 100644 --- a/eox_tenant/tenant_wise/__init__.py +++ b/eox_tenant/tenant_wise/__init__.py @@ -10,7 +10,8 @@ from django.conf import settings from eox_tenant.constants import LMS_ENVIRONMENT -from eox_tenant.tenant_wise.proxies import TenantSiteConfigProxy +from eox_tenant.tenant_wise.proxies import TenantSiteConfigProxy, DarkLangMiddlewareProxy +from eox_tenant.tenant_aware_functions.released_languages import tenant_languages def load_tenant_wise_overrides(): @@ -32,6 +33,18 @@ def load_tenant_wise_overrides(): proxy=TenantSiteConfigProxy ) + if settings.FEATURES.get("EDNX_SITE_AWARE_LOCALE", False): + set_as_proxy( + modules='openedx.core.djangoapps.lang_pref.api', + model='released_languages', + proxy=tenant_languages + ) + set_as_proxy( + modules='openedx.core.djangoapps.dark_lang.middleware', + model='DarkLangMiddleware', + proxy=DarkLangMiddlewareProxy + ) + def set_as_proxy(modules, model, proxy): """ diff --git a/eox_tenant/tenant_wise/proxies.py b/eox_tenant/tenant_wise/proxies.py index 9ee036ce..76354b8d 100644 --- a/eox_tenant/tenant_wise/proxies.py +++ b/eox_tenant/tenant_wise/proxies.py @@ -8,12 +8,15 @@ import six from django.conf import settings from django.core.cache import cache - -from eox_tenant.edxapp_wrapper.site_configuration_module import get_site_configuration_models +from eox_tenant.edxapp_wrapper.dark_lang_middleware import \ + get_dark_lang_middleware +from eox_tenant.edxapp_wrapper.site_configuration_module import \ + get_site_configuration_models from eox_tenant.models import Microsite, TenantConfig, TenantOrganization from eox_tenant.utils import clean_serializable_values SiteConfigurationModels = get_site_configuration_models() +DarkLangMiddleware = get_dark_lang_middleware() TENANT_ALL_ORGS_CACHE_KEY = "tenant.all_orgs_list" EOX_TENANT_CACHE_KEY_TIMEOUT = getattr( @@ -196,3 +199,38 @@ def pre_load_values_by_org(cls, val_name): cls.set_key_to_cache(key, result) cls.set_key_to_cache(pre_load_value_key, True) + + +class DarkLangMiddlewareProxy(DarkLangMiddleware): + """This Middleware will be used if you have FEATURES["EDNX_SITE_AWARE_LOCALE"] in True. + This take the released_languages from the site aware settings, and set a HTTP_ACCEPT_LANGUAGE if + you don't have one.""" + + class Meta: + """ Set as a proxy model. """ + proxy = True + + @property + def released_langs(self): + """ + Current list of released languages from settings. + """ + + language_options = getattr(settings, "released_languages", "") + if settings.LANGUAGE_CODE not in language_options: + language_options.append(settings.LANGUAGE_CODE) + return language_options + + def process_request(self, request): + """ + This will be run when you do a request, and prevent user from requesting un-released languages. + """ + + # If the request doesn't have HTTP_ACCEPT_LANGUAGE, eduNEXT set it to + # settings.LANGUAGE_CODE that is site aware so that + # django.utils.locale.LocaleMiddleware can pick it up + accept = request.META.get('HTTP_ACCEPT_LANGUAGE', None) + if not accept: + request.META['HTTP_ACCEPT_LANGUAGE'] = f"{settings.LANGUAGE_CODE};q=0.1" + + self._clean_accept_headers(request)