diff --git a/ezcord/i18n.py b/ezcord/i18n.py index 9bcabab..7643377 100644 --- a/ezcord/i18n.py +++ b/ezcord/i18n.py @@ -5,7 +5,7 @@ import re from copy import deepcopy from pathlib import Path -from typing import TYPE_CHECKING, Callable, Literal, Union, overload +from typing import TYPE_CHECKING, Callable, Literal, Union from .internal.dc import PYCORD, discord from .logs import log @@ -22,6 +22,7 @@ WEBHOOK_EDIT_MESSAGE = discord.Webhook.edit_message WEBHOOK_EDIT = discord.WebhookMessage.edit +LOCALE = Union[str] if PYCORD: INTERACTION_EDIT_ORIGINAL = discord.Interaction.edit_original_response @@ -41,19 +42,20 @@ if TYPE_CHECKING: import discord # type: ignore - LOCALE_OBJECT = Union[ + LOCALE = Union[ # type: ignore discord.Interaction, discord.ApplicationContext, discord.InteractionResponse, discord.Webhook, discord.Guild, discord.Member, + str, ] -__all__ = ("t", "TEmbed", "I18N") +__all__ = ("t", "TEmbed", "I18N", "LOCALE") -def t(obj: LOCALE_OBJECT | str, key: str, count: int | None = None, **variables): +def t(obj: LOCALE | str, key: str, count: int | None = None, **variables): """Get the localized string for the given key and insert all variables. Parameters @@ -197,7 +199,7 @@ async def wrapper( content=None, *, count: int | None = None, - use_locale: LOCALE_OBJECT | str | None = None, + use_locale: LOCALE | None = None, **kwargs, ): """Wrapper to localize the content and the embed of a message. @@ -241,7 +243,7 @@ async def wrapper( message_id: int | None = None, *, count: int | None = None, - use_locale: LOCALE_OBJECT | str | None = None, + use_locale: LOCALE | None = None, **kwargs, ): """The message_id is only needed for followup.edit_message, because it's a positional @@ -444,15 +446,7 @@ def __init__( setattr(discord.WebhookMessage, "edit_message", _localize_edit(WEBHOOK_EDIT)) @staticmethod - @overload - def get_locale(obj: str) -> str: ... - - @staticmethod - @overload - def get_locale(obj: LOCALE_OBJECT) -> str: ... - - @staticmethod - def get_locale(obj): + def get_locale(obj: LOCALE) -> str: """Get the locale from the given object. By default, this is the guild's locale. This method can be called even if the I18N class has not been initialized. @@ -530,7 +524,7 @@ def get_locale(obj): return locale # I18N class is not in use @staticmethod - def get_clean_locale(obj: LOCALE_OBJECT | str) -> str: + def get_clean_locale(obj: LOCALE) -> str: """Get the clean locale from the given object. This is the locale without the region, e.g. ``en`` instead of ``en-US``. @@ -601,25 +595,31 @@ def _get_text( """Looks for the specified key in different locations of the language file.""" file_name, method_name, class_name = I18N.get_location() - lookups: list[list | tuple] = [ - (file_name, method_name, key), - (file_name, called_class, key), - (file_name, class_name, key), - (file_name, "general", key), - ("general", key), - ] - for location in add_locations: - lookups.append((file_name, location, key)) + + lookups: list[list | tuple] if "." in key: - lookups.append([file_name] + key.split(".")) - lookups.append(key.split(".")) + lookups = [key.split("."), [file_name] + key.split(".")] + else: + lookups = [ + (file_name, method_name, key), + (file_name, called_class, key), + (file_name, class_name, key), + (file_name, "general", key), + ("general", key), + (file_name, key), + ] + for location in add_locations: + lookups.append((file_name, location, key)) localizations = I18N.localizations[locale] for lookup in lookups: current_section = localizations.copy() for location in lookup: - current_section = current_section.get(location, {}) + try: + current_section = current_section.get(location, {}) + except AttributeError: + return key txt = current_section if isinstance(txt, str): @@ -686,21 +686,23 @@ def replace_keys(m: re.Match): def load_embed(embed: TEmbed, locale: str) -> discord.Embed: """Loads an embed from the language file.""" - file_name, cmd_name, class_name = I18N.get_location() + file_name, method_name, class_name = I18N.get_location() # search not only the location of the embed usage, # but also the location of the embed creation original_method, original_class = embed.method_name, embed.class_name - lookups: list[list | tuple] = [ - (file_name, cmd_name, embed.key), - (file_name, original_method, embed.key), - (file_name, original_class, embed.key), - (file_name, class_name, embed.key), - ] + lookups: list[list | tuple] if "." in embed.key: - lookups.append([file_name] + embed.key.split(".")) - lookups.append(embed.key.split(".")) + lookups = [embed.key.split("."), [file_name] + embed.key.split(".")] + else: + lookups = [ + (file_name, method_name, embed.key), + (file_name, original_method, embed.key), + (file_name, original_class, embed.key), + (file_name, class_name, embed.key), + (file_name, embed.key), + ] localizations = I18N.localizations[locale] @@ -739,6 +741,9 @@ def load_lang_keys( for key, value in content.items(): if isinstance(value, str): + if key in ["color", "colour", "type", "url", "timestamp", "image", "thumbnail"]: + continue + content[key] = I18N.load_text( value, locale, count, add_locations=add_locations, **variables ) diff --git a/ezcord/internal/translation.py b/ezcord/internal/translation.py index 5d8041a..acfd6c2 100644 --- a/ezcord/internal/translation.py +++ b/ezcord/internal/translation.py @@ -12,7 +12,7 @@ from .language.languages import load_lang if TYPE_CHECKING: - from ..i18n import LOCALE_OBJECT + from ..i18n import LOCALE def plural_de(amount: int, word: str, relative: bool = True) -> str: @@ -121,7 +121,7 @@ def tp( amount: int, *args: str, relative: bool = True, - use_locale: LOCALE_OBJECT | None = None, + use_locale: LOCALE | None = None, ) -> str: """Load a string in the selected language and pluralize it. @@ -161,7 +161,7 @@ def get_locale(obj) -> str: return EzConfig.lang -def tr(key: str, *args: str, use_locale: LOCALE_OBJECT | None = None) -> str: +def tr(key: str, *args: str, use_locale: LOCALE | None = None) -> str: """Load a string in the selected language. Parameters diff --git a/ezcord/times.py b/ezcord/times.py index d762cc8..c64045a 100644 --- a/ezcord/times.py +++ b/ezcord/times.py @@ -9,7 +9,7 @@ from .internal.dc import discord if TYPE_CHECKING: - from .i18n import LOCALE_OBJECT + from .i18n import LOCALE __all__ = ( "set_utc", @@ -36,7 +36,7 @@ def set_utc(dt: datetime) -> datetime: def convert_time( - seconds: int | float, relative: bool = True, *, use_locale: LOCALE_OBJECT | None = None + seconds: int | float, relative: bool = True, *, use_locale: LOCALE | None = None ) -> str: """Convert seconds to a human-readable time. @@ -80,7 +80,7 @@ def convert_dt( dt: datetime | timedelta, relative: bool = True, *, - use_locale: LOCALE_OBJECT | None = None, + use_locale: LOCALE | None = None, ) -> str: """Convert :class:`datetime` or :class:`timedelta` to a human-readable time.