Test Failed
Push — main ( e3918a...309543 )
by Jochen
04:24
created

byceps.util.l10n.get_user_locale()   A

Complexity

Conditions 1

Size

Total Lines 7
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nop 1
dl 0
loc 7
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
"""
2
byceps.util.l10n
3
~~~~~~~~~~~~~~~~
4
5
Localization.
6
7
:Copyright: 2006-2021 Jochen Kupperschmidt
8
:License: Revised BSD (see `LICENSE` file for details)
9
"""
10
11 1
from __future__ import annotations
12 1
from contextlib import contextmanager
13 1
import locale
14 1
from typing import Iterator, Optional
15
import warnings
16 1
17 1
from babel import Locale
18 1
from flask import current_app, g, request
19
from flask_babel import force_locale
20
from wtforms import Form
21 1
22 1
from ..services.user.transfer.models import User
23 1
24 1
25 1
def set_locale(locale_str: str) -> None:
26
    try:
27
        locale.setlocale(locale.LC_ALL, locale_str)
28 1
    except locale.Error:
29
        warnings.warn(f'Could not set locale to "{locale_str}".')
30
31 1
32 1
def get_current_user_locale() -> Optional[str]:
33
    """Return the locale for the current user, if available."""
34
    # Look for a locale on the current user object.
35 1
    user = getattr(g, 'user')
36
    if (user is not None) and (user.locale is not None):
37 1
        return user.locale
38 1
39
    if request:
40 1
        # Try to match user agent's accepted languages.
41
        languages = [locale.language for locale in get_locales()]
42
        return request.accept_languages.best_match(languages)
43 1
44
    return None
45
46 1
47
@contextmanager
48 1
def force_user_locale(user: User) -> Iterator[None]:
49
    """Execute code with the user's preferred locale."""
50
    locale = get_user_locale(user)
51 1
    with force_locale(locale):
52
        yield
53 1
54 1
55 1
def get_user_locale(user: User) -> str:
56 1
    """Return the user's preferred locale.
57
58
    If no preference is set for the user, return the app's default
59
    locale.
60
    """
61
    return user.locale or current_app.config['LOCALE']
62
63
64
BASE_LOCALE = Locale('en')
65
66
67
def get_locales() -> list[Locale]:
68
    """List available locales."""
69
    return [BASE_LOCALE] + current_app.babel_instance.list_translations()
70
71
72
class LocalizedForm(Form):
73
74
    def __init__(self, *args, **kwargs):
75
        locales = current_app.config['LOCALES_FORMS']
76
        kwargs['meta'] = {'locales': locales}
77
        super().__init__(*args, **kwargs)
78