def get_language_from_request(request): """ Analyzes the request to find what language the user wants the system to show. Only languages listed in settings.LANGUAGES are taken into account. If the user requests a sublanguage where we have a main language, we send out the main language. """ global _supported if _supported is None: _supported = OrderedDict(settings.LANGUAGES) # Priority 1: User settings if request.user.is_authenticated(): lang_code = request.user.locale if lang_code in _supported and lang_code is not None and check_for_language(lang_code): return lang_code # Priority 2: Anonymous user settings (session, cookie) if hasattr(request, 'session'): lang_code = request.session.get(LANGUAGE_SESSION_KEY) if lang_code in _supported and lang_code is not None and check_for_language(lang_code): return lang_code lang_code = request.COOKIES.get(settings.LANGUAGE_COOKIE_NAME) try: return get_supported_language_variant(lang_code) except LookupError: pass # Priority 3: Event default if hasattr(request, 'event'): lang_code = request.event.locale try: return get_supported_language_variant(lang_code) except LookupError: pass # Priority 4: Browser default accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '') for accept_lang, unused in parse_accept_lang_header(accept): if accept_lang == '*': break if not language_code_re.search(accept_lang): continue try: return get_supported_language_variant(accept_lang) except LookupError: continue try: return get_supported_language_variant(settings.LANGUAGE_CODE) except LookupError: return settings.LANGUAGE_CODE
def get_language_from_event(request) -> str: if hasattr(request, 'event'): lang_code = request.event.settings.locale try: return get_supported_language_variant(lang_code) except LookupError: pass
def _variant(country, language): language_code = '{}-{}'.format(language, country) try: return get_supported_language_variant(language_code) except LookupError: raise ImproperlyConfigured( "No matching locale found for '{}'. ".format(language_code) + "Check your COUNTRIES and LANGUAGES settings.")
def get_language_from_path(path): regex_match = language_code_prefix_re.match(path) if not regex_match: return None lang_code = regex_match.group(1) try: return get_supported_language_variant(lang_code) except LookupError: return None
def __init__(self, *args, **kwargs): current_language = kwargs.pop('_current_language', None) # Used for TranslatableViewMixin super().__init__(*args, **kwargs) # Load the initial values for the translated fields instance = kwargs.get('instance', None) if instance: for meta in instance._parler_meta: try: # By not auto creating a model, any template code that reads the fields # will continue to see one of the other translations. # This also causes admin inlines to show the fallback title in __unicode__. translation = instance._get_translated_model(meta=meta) except TranslationDoesNotExist: pass else: for field in meta.get_translated_fields(): try: model_field = translation._meta.get_field(field) self.initial.setdefault( field, model_field.value_from_object(translation)) except ObjectDoesNotExist: # This occurs when a ForeignKey field is part of the translation, # but it's value is still not yet, and the field has null=False. pass # Typically already set by admin if self.language_code is None: if instance: self.language_code = instance.get_current_language() else: self.language_code = current_language or get_language() try: get_supported_language_variant(self.language_code) except LookupError: # Instead of raising a ValidationError raise ValueError( "Translatable forms can't be initialized for the language '{0}', " "that option does not exist in the 'LANGUAGES' setting.". format(self.language_code))
def get_language_from_session_or_cookie(request: HttpRequest) -> str: if hasattr(request, 'session'): lang_code = request.session.get(LANGUAGE_SESSION_KEY) if lang_code in _supported and lang_code is not None and check_for_language(lang_code): return lang_code lang_code = request.COOKIES.get(settings.LANGUAGE_COOKIE_NAME) try: return get_supported_language_variant(lang_code) except LookupError: pass
def _language_from_request(request, supported): lang = request.GET.get("lang") if lang: with suppress(LookupError): value = get_supported_language_variant(lang) if value in supported: if hasattr(request, "session"): request.session[LANGUAGE_SESSION_KEY] = value else: request.COOKIES[settings.LANGUAGE_COOKIE_NAME] = value return value
def get_language_from_path(path): from django.conf import settings supported = SortedDict(settings.LANGUAGES) regex_match = language_code_prefix_re.match(path) if not regex_match: return None lang_code = regex_match.group(1) try: return get_supported_language_variant(lang_code, supported) except LookupError: return None
def get_language_from_session_or_cookie(request) -> str: if hasattr(request, 'session'): lang_code = request.session.get(LANGUAGE_SESSION_KEY) if lang_code in _supported and lang_code is not None and check_for_language(lang_code): return lang_code lang_code = request.COOKIES.get(settings.LANGUAGE_COOKIE_NAME) try: return get_supported_language_variant(lang_code) except LookupError: pass
def get_language_from_request_and_is_from_path(request): # noqa complexity-16 """ Analyzes the request to find what language the user wants the system to show. Only languages listed in settings.LANGUAGES are taken into account. If the user requests a sublanguage where we have a main language, we send out the main language. It also returns a value to determine if the language code was derived from a language code in the URL, or inferred from some other source. :returns: tuple of language code, boolean. The former can be None if the url being requested does not require translation, otherwise it should be a language code from the values in settings.LANGUAGES. The boolean should indicate whether the language code was calculated by reading a language code from the requested URL. In the case that it was, True should be returned, in the case where the URL language code was not used or not present, False is returned. """ try: # If this is not a view that needs to be translated, return None, and be done with it! if not getattr(resolve(request.path_info).func, "translated", False): return None, False except Resolver404: # If this is an unrecognized URL, it may be redirectable to a language prefixed # URL, so let the language code setting carry on from here. pass supported_lang_codes = get_languages() lang_code = get_language_from_path(request.path_info) if lang_code in supported_lang_codes and lang_code is not None: return lang_code, True if hasattr(request, "session"): lang_code = request.session.get(LANGUAGE_SESSION_KEY) if (lang_code in supported_lang_codes and lang_code is not None and check_for_language(lang_code)): return lang_code, False lang_code = request.COOKIES.get(settings.LANGUAGE_COOKIE_NAME) try: return get_supported_language_variant(lang_code), False except LookupError: pass device_language = get_device_language() if device_language is not None: return device_language, False headers_language = get_accept_headers_language(request) if headers_language is not None: return headers_language, False return get_settings_language(), False
def get_language_from_request(request, check_path=False): """ Replacement for django.utils.translation.get_language_from_request. The portion of code that is modified is identified below with a comment. """ if check_path: lang_code = get_language_from_path(request.path_info) if lang_code is not None: return lang_code lang_code = request.COOKIES.get(settings.LANGUAGE_COOKIE_NAME) if lang_code is not None and lang_code in get_languages( ) and check_for_language(lang_code): return lang_code try: return get_supported_language_variant(lang_code) except LookupError: pass accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '') for accept_lang, unused in parse_accept_lang_header(accept): if accept_lang == '*': break # Convert lowercase region to uppercase before attempting to find a variant. # This is the only portion of code that is modified from the core function. accept_lang = language_code_to_iso_3166(accept_lang) if not language_code_re.search(accept_lang): continue try: return get_supported_language_variant(accept_lang) except LookupError: continue try: return get_supported_language_variant(settings.LANGUAGE_CODE) except LookupError: return settings.LANGUAGE_CODE
def __init__(self, *args, **kwargs): current_language = kwargs.pop('_current_language', None) # Used for TranslatableViewMixin super(BaseTranslatableModelForm, self).__init__(*args, **kwargs) # Load the initial values for the translated fields instance = kwargs.get('instance', None) if instance: for meta in instance._parler_meta: try: # By not auto creating a model, any template code that reads the fields # will continue to see one of the other translations. # This also causes admin inlines to show the fallback title in __unicode__. translation = instance._get_translated_model(meta=meta) except TranslationDoesNotExist: pass else: for field in meta.get_translated_fields(): try: value = getattr(translation, field) prepared_value = translation._meta.get_field(field).get_prep_value(value) self.initial.setdefault(field, prepared_value) except ObjectDoesNotExist: # This occurs when a ForeignKey field is part of the translation, # but it's value is still not yet, and the field has null=False. pass # Typically already set by admin if self.language_code is None: if instance: self.language_code = instance.get_current_language() else: self.language_code = current_language or get_language() try: get_supported_language_variant(self.language_code) except LookupError: # Instead of raising a ValidationError raise ValueError( "Translatable forms can't be initialized for the language '{0}', " "that option does not exist in the 'LANGUAGES' setting.".format(self.language_code) )
def get_language_from_browser(request: HttpRequest) -> str: accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '') for accept_lang, unused in parse_accept_lang_header(accept): if accept_lang == '*': break if not language_code_re.search(accept_lang): continue try: return get_supported_language_variant(accept_lang) except LookupError: continue
def get_language_from_browser(request: HttpRequest) -> str: accept = request.headers.get('Accept-Language', '') for accept_lang, unused in parse_accept_lang_header(accept): if accept_lang == '*': break if not language_code_re.search(accept_lang): continue try: return get_supported_language_variant(accept_lang) except LookupError: continue
def get_language_from_browser(request) -> str: accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '') for accept_lang, unused in parse_accept_lang_header(accept): if accept_lang == '*': break if not language_code_re.search(accept_lang): continue try: return get_supported_language_variant(accept_lang) except LookupError: continue
def _language_from_browser(request, supported): accept_value = request.headers.get("Accept-Language", "") for accept_lang, _ in parse_accept_lang_header(accept_value): if accept_lang == "*": break if not language_code_re.search(accept_lang): continue with suppress(LookupError): val = get_supported_language_variant(accept_lang) if val and val in supported: return val
def get_accept_headers_language(request): accept = request.META.get("HTTP_ACCEPT_LANGUAGE", "") for accept_lang, unused in parse_accept_lang_header(accept): if accept_lang == "*": break if not language_code_re.search(accept_lang): continue try: return get_supported_language_variant(accept_lang) except LookupError: continue
def get_device_language(): from .models import DeviceSettings try: if cache.get(DEVICE_LANGUAGE_CACHE_KEY) is None: # Use a relatively short expiry, in case the device setting is changed in another # thread and this cache does not get invalidated. cache.set(DEVICE_LANGUAGE_CACHE_KEY, DeviceSettings.objects.get().language_id, 600) return get_supported_language_variant( cache.get(DEVICE_LANGUAGE_CACHE_KEY)) except (DeviceSettings.DoesNotExist, LookupError, OperationalError): return None
def _get_locale_from_language_header(self, request): # Copied from django.utils.translation.real_trans.get_language_from_request accept = request.META.get("HTTP_ACCEPT_LANGUAGE", "") for accept_lang, unused in parse_accept_lang_header(accept): if accept_lang == "*": break if not language_code_re.search(accept_lang): continue try: return get_supported_language_variant(accept_lang) except LookupError: continue return None
def _language_from_browser(self, request, supported): accept_value = request.META.get('HTTP_ACCEPT_LANGUAGE', '') for accept_lang, unused in parse_accept_lang_header(accept_value): if accept_lang == '*': break if not language_code_re.search(accept_lang): continue try: val = get_supported_language_variant(accept_lang) if val and val in supported: return val except LookupError: continue
def _language_from_browser(request, supported): accept_value = request.headers.get('Accept-Language', '') for accept_lang, _ in parse_accept_lang_header(accept_value): if accept_lang == '*': break if not language_code_re.search(accept_lang): continue try: val = get_supported_language_variant(accept_lang) if val and val in supported: return val except LookupError: continue return None
def process_request(self, request): if request.path_info == '/graphql': regex_match = referer_language_code_prefix.match( request.META.get('HTTP_REFERER', '')) if not regex_match: lang_code = None else: lang_code = regex_match.group(1) language = get_supported_language_variant(lang_code) if not language: language = 'en' translation.activate(language) request.LANGUAGE_CODE = translation.get_language() return return super(GraphQLLocaleMiddleware, self).process_request(request)
def process_request(self, request): # check api url full_path = request.get_full_path() is_api_url = False for i in LOGIN_API_URL_SUFFIX_LIST: if (full_path.startswith(settings.SITE_URL + 'api/v2/' + i + '/') or full_path.startswith(settings.SITE_URL + "accounts/" + i + '/')): is_api_url = True break # only api url do if is_api_url: try: language = request.META.get('HTTP_BLUEKING_LANGUAGE', 'en') language = trans.get_supported_language_variant(language) except Exception: language = 'en' if language: translation.activate(language) request.LANGUAGE_CODE = translation.get_language()
def _get_locale_from_language_header(self) -> Optional[str]: # Logic adapted from django.utils.translation.real_trans.get_language_from_request for accept_lang, unused in parse_accept_lang_header( self.accept_language_header): if accept_lang == "*": break if not language_code_re.search(accept_lang): continue try: locale_id = get_supported_language_variant(accept_lang) except LookupError: continue if is_supported(locale_id): return locale_id else: continue return None
def get_default_language(): try: return get_supported_language_variant(settings.LANGUAGE_CODE) except LookupError: # NOQA return settings.LANGUAGE_CODE
def _language_from_user(request, supported): if request.user.is_authenticated: with suppress(LookupError): value = get_supported_language_variant(request.user.locale) if value and value in supported: return value
def footer(request): """Retrieve the branded footer. This end-point provides information about the site footer, allowing for consistent display of the footer across other sites (for example, on the marketing site and blog). It can be used in one of two ways: 1) A client renders the footer from a JSON description. 2) A browser loads an HTML representation of the footer and injects it into the DOM. The HTML includes CSS and JavaScript links. In case (2), we assume that the following dependencies are included on the page: a) JQuery (same version as used in edx-platform) b) font-awesome (same version as used in edx-platform) c) Open Sans web fonts Example: Retrieving the footer as JSON GET /api/branding/v1/footer Accepts: application/json { "navigation_links": [ { "url": "http://example.com/about", "name": "about", "title": "About" }, # ... ], "social_links": [ { "url": "http://example.com/social", "name": "facebook", "icon-class": "fa-facebook-square", "title": "Facebook", "action": "Sign up on Facebook!" }, # ... ], "mobile_links": [ { "url": "http://example.com/android", "name": "google", "image": "http://example.com/google.png", "title": "Google" }, # ... ], "legal_links": [ { "url": "http://example.com/terms-of-service.html", "name": "terms_of_service", "title': "Terms of Service" }, # ... ], "openedx_link": { "url": "http://open.edx.org", "title": "Powered by Open edX", "image": "http://example.com/openedx.png" }, "logo_image": "http://example.com/static/images/logo.png", "copyright": "edX, Open edX and their respective logos are registered trademarks of edX Inc." } Example: Retrieving the footer as HTML GET /api/branding/v1/footer Accepts: text/html Example: Including the footer with the "Powered by Open edX" logo GET /api/branding/v1/footer?show-openedx-logo=1 Accepts: text/html Example: Retrieving the footer in a particular language GET /api/branding/v1/footer?language=en Accepts: text/html Example: Retrieving the footer with a language selector GET /api/branding/v1/footer?include-language-selector=1 Accepts: text/html Example: Retrieving the footer with all JS and CSS dependencies (for testing) GET /api/branding/v1/footer?include-dependencies=1 Accepts: text/html """ if not branding_api.is_enabled(): raise Http404 # Use the content type to decide what representation to serve accepts = request.META.get('HTTP_ACCEPT', '*/*') # Show the OpenEdX logo in the footer show_openedx_logo = bool(request.GET.get('show-openedx-logo', False)) # Include JS and CSS dependencies # This is useful for testing the end-point directly. include_dependencies = bool(request.GET.get('include-dependencies', False)) # Override the language if necessary language = request.GET.get('language', translation.get_language()) try: language = get_supported_language_variant(language) except LookupError: language = settings.LANGUAGE_CODE # Include a language selector include_language_selector = request.GET.get('include-language-selector', '') == '1' # Render the footer information based on the extension if 'text/html' in accepts or '*/*' in accepts: cache_params = { 'language': language, 'show_openedx_logo': show_openedx_logo, 'include_dependencies': include_dependencies } if include_language_selector: cache_params['language_selector_options'] = ','.join( sorted([lang.code for lang in released_languages()])) cache_key = u"branding.footer.{params}.html".format( params=six.moves.urllib.parse.urlencode(cache_params)) content = cache.get(cache_key) if content is None: with translation.override(language): content = _render_footer_html(request, show_openedx_logo, include_dependencies, include_language_selector, language) cache.set(cache_key, content, settings.FOOTER_CACHE_TIMEOUT) return HttpResponse(content, status=200, content_type="text/html; charset=utf-8") elif 'application/json' in accepts: cache_key = u"branding.footer.{params}.json".format( params=six.moves.urllib.parse.urlencode( { 'language': language, 'is_secure': request.is_secure(), })) footer_dict = cache.get(cache_key) if footer_dict is None: with translation.override(language): footer_dict = branding_api.get_footer( is_secure=request.is_secure()) cache.set(cache_key, footer_dict, settings.FOOTER_CACHE_TIMEOUT) return JsonResponse(footer_dict, 200, content_type="application/json; charset=utf-8") else: return HttpResponse(status=406)
def is_valid_language_code(lc): try: get_supported_language_variant(lc) except LookupError: return False return True
def _language_from_cookie(self, request, supported): cookie_value = request.COOKIES.get(settings.LANGUAGE_COOKIE_NAME) with suppress(LookupError): cookie_value = get_supported_language_variant(cookie_value) if cookie_value and cookie_value in supported: return cookie_value
class PybbProfile(models.Model): """ Abstract class for user profile, site profile should be inherted from this class """ class Meta(object): abstract = True permissions = (("block_users", "Can block any user"), ) signature = models.TextField(_('Signature'), blank=True, max_length=defaults.PYBB_SIGNATURE_MAX_LENGTH) signature_html = models.TextField( _('Signature HTML Version'), blank=True, max_length=defaults.PYBB_SIGNATURE_MAX_LENGTH + 30) time_zone = models.FloatField(_('Time zone'), choices=TZ_CHOICES, default=float( defaults.PYBB_DEFAULT_TIME_ZONE)) language = models.CharField(_('Language'), max_length=10, blank=True, choices=settings.LANGUAGES, default=get_supported_language_variant( settings.LANGUAGE_CODE, strict=True)) show_signatures = models.BooleanField(_('Show signatures'), default=True) post_count = models.IntegerField(_('Post count'), blank=True, default=0) avatar = get_image_field_class()( _('Avatar'), blank=True, null=True, upload_to=util.FilePathGenerator(to='pybb/avatar')) autosubscribe = models.BooleanField( _('Automatically subscribe'), help_text=_('Automatically subscribe to topics that you answer'), default=defaults.PYBB_DEFAULT_AUTOSUBSCRIBE) nickname = models.CharField(_('Nickname'), blank=True, null=True, max_length=30, unique=True) def save(self, *args, **kwargs): self.signature_html = util._get_markup_formatter()(self.signature) super(PybbProfile, self).save(*args, **kwargs) @property def calculate_post_count(self): return apps.get_models( 'pybb', 'Post').objects.filter(user=self.user_id).count() @property def avatar_url(self): try: return self.avatar.url except: return defaults.PYBB_DEFAULT_AVATAR_URL def get_display_name(self): try: if hasattr(self, 'user'): # we have OneToOne foreign key to user model return self.user.get_username() if not defaults.PYBB_PROFILE_RELATED_NAME: # we now in user custom model itself return self.get_username() except Exception: return force_text(self)
def footer(request): """Retrieve the branded footer. This end-point provides information about the site footer, allowing for consistent display of the footer across other sites (for example, on the marketing site and blog). It can be used in one of two ways: 1) A client renders the footer from a JSON description. 2) A browser loads an HTML representation of the footer and injects it into the DOM. The HTML includes CSS and JavaScript links. In case (2), we assume that the following dependencies are included on the page: a) JQuery (same version as used in edx-platform) b) font-awesome (same version as used in edx-platform) c) Open Sans web fonts Example: Retrieving the footer as JSON GET /api/branding/v1/footer Accepts: application/json { "navigation_links": [ { "url": "http://example.com/about", "name": "about", "title": "About" }, # ... ], "social_links": [ { "url": "http://example.com/social", "name": "facebook", "icon-class": "fa-facebook-square", "title": "Facebook", "action": "Sign up on Facebook!" }, # ... ], "mobile_links": [ { "url": "http://example.com/android", "name": "google", "image": "http://example.com/google.png", "title": "Google" }, # ... ], "legal_links": [ { "url": "http://example.com/terms-of-service.html", "name": "terms_of_service", "title': "Terms of Service" }, # ... ], "openedx_link": { "url": "http://open.edx.org", "title": "Powered by Open edX", "image": "http://example.com/openedx.png" }, "logo_image": "http://example.com/static/images/logo.png", "copyright": "edX, Open edX and their respective logos are registered trademarks of edX Inc." } Example: Retrieving the footer as HTML GET /api/branding/v1/footer Accepts: text/html Example: Including the footer with the "Powered by Open edX" logo GET /api/branding/v1/footer?show-openedx-logo=1 Accepts: text/html Example: Retrieving the footer in a particular language GET /api/branding/v1/footer?language=en Accepts: text/html Example: Retrieving the footer with a language selector GET /api/branding/v1/footer?include-language-selector=1 Accepts: text/html Example: Retrieving the footer with all JS and CSS dependencies (for testing) GET /api/branding/v1/footer?include-dependencies=1 Accepts: text/html """ if not branding_api.is_enabled(): raise Http404 # Use the content type to decide what representation to serve accepts = request.META.get('HTTP_ACCEPT', '*/*') # Show the OpenEdX logo in the footer show_openedx_logo = bool(request.GET.get('show-openedx-logo', False)) # Include JS and CSS dependencies # This is useful for testing the end-point directly. include_dependencies = bool(request.GET.get('include-dependencies', False)) # Override the language if necessary language = request.GET.get('language', translation.get_language()) try: language = get_supported_language_variant(language) except LookupError: language = settings.LANGUAGE_CODE # Include a language selector include_language_selector = request.GET.get('include-language-selector', '') == '1' # Render the footer information based on the extension if 'text/html' in accepts or '*/*' in accepts: cache_params = { 'language': language, 'show_openedx_logo': show_openedx_logo, 'include_dependencies': include_dependencies } if include_language_selector: cache_params['language_selector_options'] = ','.join(sorted([lang.code for lang in released_languages()])) cache_key = u"branding.footer.{params}.html".format(params=six.moves.urllib.parse.urlencode(cache_params)) content = cache.get(cache_key) if content is None: with translation.override(language): content = _render_footer_html( request, show_openedx_logo, include_dependencies, include_language_selector, language ) cache.set(cache_key, content, settings.FOOTER_CACHE_TIMEOUT) return HttpResponse(content, status=200, content_type="text/html; charset=utf-8") elif 'application/json' in accepts: cache_key = u"branding.footer.{params}.json".format( params=six.moves.urllib.parse.urlencode({ 'language': language, 'is_secure': request.is_secure(), }) ) footer_dict = cache.get(cache_key) if footer_dict is None: with translation.override(language): footer_dict = branding_api.get_footer(is_secure=request.is_secure()) cache.set(cache_key, footer_dict, settings.FOOTER_CACHE_TIMEOUT) return JsonResponse(footer_dict, 200, content_type="application/json; charset=utf-8") else: return HttpResponse(status=406)
class Migration(migrations.Migration): dependencies = [ ('pybb', '0004_slugs_required'), ] operations = [ migrations.AlterField( model_name='post', name='user_ip', field=models.GenericIPAddressField(blank=True, default='0.0.0.0', null=True, verbose_name='User IP'), ), migrations.AlterField( model_name='profile', name='avatar', field=get_image_field_class()( blank=True, null=True, upload_to=pybb.util.FilePathGenerator(to='pybb/avatar'), verbose_name='Avatar'), ), migrations.AlterField( model_name='profile', name='language', field=models.CharField(blank=True, choices=settings.LANGUAGES, default=get_supported_language_variant( settings.LANGUAGE_CODE, strict=True), max_length=10, verbose_name='Language'), ), migrations.AlterField( model_name='profile', name='time_zone', field=models.FloatField(choices=[(-12.0, '-12'), (-11.0, '-11'), (-10.0, '-10'), (-9.5, '-09.5'), (-9.0, '-09'), (-8.5, '-08.5'), (-8.0, '-08 PST'), (-7.0, '-07 MST'), (-6.0, '-06 CST'), (-5.0, '-05 EST'), (-4.0, '-04 AST'), (-3.5, '-03.5'), (-3.0, '-03 ADT'), (-2.0, '-02'), (-1.0, '-01'), (0.0, '00 GMT'), (1.0, '+01 CET'), (2.0, '+02'), (3.0, '+03'), (3.5, '+03.5'), (4.0, '+04'), (4.5, '+04.5'), (5.0, '+05'), (5.5, '+05.5'), (6.0, '+06'), (6.5, '+06.5'), (7.0, '+07'), (8.0, '+08'), (9.0, '+09'), (9.5, '+09.5'), (10.0, '+10'), (10.5, '+10.5'), (11.0, '+11'), (11.5, '+11.5'), (12.0, '+12'), (13.0, '+13'), (14.0, '+14')], default=3.0, verbose_name='Time zone'), ), ]
def set_language_in_session(language, session): try: language = get_supported_language_variant(language) session[LANGUAGE_SESSION_KEY] = language except LookupError: pass
def _is_language_supported(lang: str) -> bool: try: get_supported_language_variant(lang) return True except LookupError: return False
def get_default_language(): try: return get_supported_language_variant(settings.LANGUAGE_CODE) except LookupError: return settings.LANGUAGE_CODE
def get_device_language(): language_id = get_device_setting("language_id", None) try: return get_supported_language_variant(language_id) except LookupError: return None