Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: having released_languages tenant and site aware DS-553 #184

Merged
merged 3 commits into from
Jun 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"""
DarkLangMiddleware Backend for tests.
"""
from unittest.mock import MagicMock


def get_dark_lang_middleware():
"""Backend to get the DarkLangMiddleware from openedx."""
return MagicMock()
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"""
DarkLangMiddleware Backend.
"""
from openedx.core.djangoapps.dark_lang.middleware import DarkLangMiddleware # pylint: disable=import-error


def get_dark_lang_middleware():
"""Backend to get the DarkLangMiddleware from openedx."""
return DarkLangMiddleware
11 changes: 11 additions & 0 deletions eox_tenant/edxapp_wrapper/dark_lang_middleware.py
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions eox_tenant/settings/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions eox_tenant/settings/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class SettingsClass:
GET_THEMING_HELPERS = 'eox_tenant.edxapp_wrapper.backends.theming_helpers_test_v1'
EOX_TENANT_USERS_BACKEND = 'eox_tenant.edxapp_wrapper.backends.users_test_v1'
EOX_TENANT_BEARER_AUTHENTICATION = 'eox_tenant.edxapp_wrapper.backends.bearer_authentication_test_v1'
DARK_LANG_MIDDLEWARE = 'eox_tenant.edxapp_wrapper.backends.dark_lang_middleware_o_test_v1'

COURSE_KEY_PATTERN = r'(?P<course_key_string>[^/+]+(/|\+)[^/+]+(/|\+)[^/?]+)'
COURSE_ID_PATTERN = COURSE_KEY_PATTERN.replace('course_key_string', 'course_id')
Expand Down
42 changes: 42 additions & 0 deletions eox_tenant/tenant_aware_functions/released_languages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
"""
Site/Tenant aware languages filter.
"""
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
]
15 changes: 14 additions & 1 deletion eox_tenant/tenant_wise/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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_aware_functions.released_languages import tenant_languages
from eox_tenant.tenant_wise.proxies import DarkLangMiddlewareProxy, TenantSiteConfigProxy


def load_tenant_wise_overrides():
Expand All @@ -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):
"""
Expand Down
38 changes: 38 additions & 0 deletions eox_tenant/tenant_wise/proxies.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@
from django.conf import settings
from django.core.cache import cache

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(
Expand Down Expand Up @@ -196,3 +198,39 @@ 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.
"""

get_language_options = getattr(settings, "released_languages", "")
language_options = [lang.lower().strip() for lang in get_language_options.split(',')]
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)