"""
Provide the Locale API.
"""
from __future__ import annotations
from typing import Sequence, TypeAlias
from babel import Locale, negotiate_locale as babel_negotiate_locale
from babel.core import UnknownLocaleError
from betty import fs
from langcodes import Language
DEFAULT_LOCALE = "en-US"
UNDETERMINED_LOCALE = "und"
_LOCALE_DIRECTORY_PATH = fs.ASSETS_DIRECTORY_PATH / "locale"
[docs]
def to_babel_identifier(locale: Localey) -> str:
"""
Convert a locale or locale metadata to a Babel locale identifier.
"""
if isinstance(locale, Locale):
return str(locale)
language_data = Language.get(locale)
return "_".join(
part
for part in [
language_data.language,
language_data.script,
language_data.territory,
]
if part
)
[docs]
def to_locale(locale: Localey) -> str:
"""
Ensure that a locale or locale metadata is a locale.
"""
if isinstance(locale, str):
return locale
return "-".join(
part
for part in [
locale.language,
locale.script,
locale.territory,
]
if part
)
Localey: TypeAlias = str | Locale
[docs]
def get_data(locale: Localey) -> Locale:
"""
Get locale metadata.
:raises betty.locale.InvalidLocale: Raised if the given identifier is not a valid locale.
:raises betty.locale.LocaleNotFoundError: Raised if the given locale cannot be found.
"""
if isinstance(locale, Locale):
return locale
try:
return Locale.parse(to_babel_identifier(locale))
except ValueError:
from betty.locale.error import InvalidLocale
raise InvalidLocale(locale) from None
except UnknownLocaleError:
from betty.locale.error import LocaleNotFound
raise LocaleNotFound(locale) from None