mirror of
https://github.com/Rapptz/discord.py.git
synced 2025-05-13 01:09:50 +00:00
Add auto_locale_strings parameter to application commands
This commit is contained in:
parent
2d586ae805
commit
1c9792e0ed
discord/app_commands
@ -457,12 +457,6 @@ def _get_context_menu_parameter(func: ContextMenuCallback) -> Tuple[str, Any, Ap
|
||||
return (parameter.name, resolved, type)
|
||||
|
||||
|
||||
async def _get_translation_payload(
|
||||
command: Union[Command[Any, ..., Any], Group, ContextMenu], translator: Translator
|
||||
) -> Dict[str, Any]:
|
||||
...
|
||||
|
||||
|
||||
class Command(Generic[GroupT, P, T]):
|
||||
"""A class that implements an application command.
|
||||
|
||||
@ -475,15 +469,39 @@ class Command(Generic[GroupT, P, T]):
|
||||
|
||||
.. versionadded:: 2.0
|
||||
|
||||
Parameters
|
||||
-----------
|
||||
name: Union[:class:`str`, :class:`locale_str`]
|
||||
The name of the application command.
|
||||
description: Union[:class:`str`, :class:`locale_str`]
|
||||
The description of the application command. This shows up in the UI to describe
|
||||
the application command.
|
||||
callback: :ref:`coroutine <coroutine>`
|
||||
The coroutine that is executed when the command is called.
|
||||
auto_locale_strings: :class:`bool`
|
||||
If this is set to ``True``, then all translatable strings will implicitly
|
||||
be wrapped into :class:`locale_str` rather than :class:`str`. This could
|
||||
avoid some repetition and be more ergonomic for certain defaults such
|
||||
as default command names, command descriptions, and parameter names.
|
||||
Defaults to ``False``.
|
||||
nsfw: :class:`bool`
|
||||
Whether the command is NSFW and should only work in NSFW channels.
|
||||
Defaults to ``False``.
|
||||
|
||||
Due to a Discord limitation, this does not work on subcommands.
|
||||
parent: Optional[:class:`Group`]
|
||||
The parent application command. ``None`` if there isn't one.
|
||||
extras: :class:`dict`
|
||||
A dictionary that can be used to store extraneous data.
|
||||
The library will not touch any values or keys within this dictionary.
|
||||
|
||||
Attributes
|
||||
------------
|
||||
name: :class:`str`
|
||||
The name of the application command. When passed as an argument
|
||||
to ``__init__`` this can also be :class:`locale_str`.
|
||||
The name of the application command.
|
||||
description: :class:`str`
|
||||
The description of the application command. This shows up in the UI to describe
|
||||
the application command. When passed as an argument to ``__init__`` this
|
||||
can also be :class:`locale_str`.
|
||||
the application command.
|
||||
checks
|
||||
A list of predicates that take a :class:`~discord.Interaction` parameter
|
||||
to indicate whether the command callback should be executed. If an exception
|
||||
@ -499,12 +517,10 @@ class Command(Generic[GroupT, P, T]):
|
||||
Due to a Discord limitation, this does not work on subcommands.
|
||||
guild_only: :class:`bool`
|
||||
Whether the command should only be usable in guild contexts.
|
||||
Defaults to ``False``.
|
||||
|
||||
Due to a Discord limitation, this does not work on subcommands.
|
||||
nsfw: :class:`bool`
|
||||
Whether the command is NSFW and should only work in NSFW channels.
|
||||
Defaults to ``False``.
|
||||
|
||||
Due to a Discord limitation, this does not work on subcommands.
|
||||
parent: Optional[:class:`Group`]
|
||||
@ -523,6 +539,7 @@ class Command(Generic[GroupT, P, T]):
|
||||
nsfw: bool = False,
|
||||
parent: Optional[Group] = None,
|
||||
guild_ids: Optional[List[int]] = None,
|
||||
auto_locale_strings: bool = False,
|
||||
extras: Dict[Any, Any] = MISSING,
|
||||
):
|
||||
name, locale = (name.message, name) if isinstance(name, locale_str) else (name, None)
|
||||
@ -562,6 +579,18 @@ class Command(Generic[GroupT, P, T]):
|
||||
if self._guild_ids is not None and self.parent is not None:
|
||||
raise ValueError('child commands cannot have default guilds set, consider setting them in the parent instead')
|
||||
|
||||
if auto_locale_strings:
|
||||
self._convert_to_locale_strings()
|
||||
|
||||
def _convert_to_locale_strings(self) -> None:
|
||||
if self._locale_name is None:
|
||||
self._locale_name = locale_str(self.name)
|
||||
if self._locale_description is None:
|
||||
self._locale_description = locale_str(self.description)
|
||||
|
||||
for param in self._params.values():
|
||||
param._convert_to_locale_strings()
|
||||
|
||||
def __set_name__(self, owner: Type[Any], name: str) -> None:
|
||||
self._attr = name
|
||||
|
||||
@ -972,11 +1001,32 @@ class ContextMenu:
|
||||
|
||||
.. versionadded:: 2.0
|
||||
|
||||
Parameters
|
||||
-----------
|
||||
name: Union[:class:`str`, :class:`locale_str`]
|
||||
The name of the context menu.
|
||||
callback: :ref:`coroutine <coroutine>`
|
||||
The coroutine that is executed when the command is called.
|
||||
type: :class:`.AppCommandType`
|
||||
The type of context menu application command. By default, this is inferred
|
||||
by the parameter of the callback.
|
||||
auto_locale_strings: :class:`bool`
|
||||
If this is set to ``True``, then all translatable strings will implicitly
|
||||
be wrapped into :class:`locale_str` rather than :class:`str`. This could
|
||||
avoid some repetition and be more ergonomic for certain defaults such
|
||||
as default command names, command descriptions, and parameter names.
|
||||
Defaults to ``False``.
|
||||
nsfw: :class:`bool`
|
||||
Whether the command is NSFW and should only work in NSFW channels.
|
||||
Defaults to ``False``.
|
||||
extras: :class:`dict`
|
||||
A dictionary that can be used to store extraneous data.
|
||||
The library will not touch any values or keys within this dictionary.
|
||||
|
||||
Attributes
|
||||
------------
|
||||
name: :class:`str`
|
||||
The name of the context menu. When passed as an argument to ``__init__``
|
||||
this can be :class:`locale_str`.
|
||||
The name of the context menu.
|
||||
type: :class:`.AppCommandType`
|
||||
The type of context menu application command. By default, this is inferred
|
||||
by the parameter of the callback.
|
||||
@ -1010,6 +1060,7 @@ class ContextMenu:
|
||||
type: AppCommandType = MISSING,
|
||||
nsfw: bool = False,
|
||||
guild_ids: Optional[List[int]] = None,
|
||||
auto_locale_strings: bool = False,
|
||||
extras: Dict[Any, Any] = MISSING,
|
||||
):
|
||||
name, locale = (name.message, name) if isinstance(name, locale_str) else (name, None)
|
||||
@ -1037,6 +1088,10 @@ class ContextMenu:
|
||||
self.checks: List[Check] = getattr(callback, '__discord_app_commands_checks__', [])
|
||||
self.extras: Dict[Any, Any] = extras or {}
|
||||
|
||||
if auto_locale_strings:
|
||||
if self._locale_name is None:
|
||||
self._locale_name = locale_str(self.name)
|
||||
|
||||
@property
|
||||
def callback(self) -> ContextMenuCallback:
|
||||
""":ref:`coroutine <coroutine>`: The coroutine that is executed when the context menu is called."""
|
||||
@ -1164,17 +1219,21 @@ class Group:
|
||||
|
||||
.. versionadded:: 2.0
|
||||
|
||||
Attributes
|
||||
------------
|
||||
name: :class:`str`
|
||||
Parameters
|
||||
-----------
|
||||
name: Union[:class:`str`, :class:`locale_str`]
|
||||
The name of the group. If not given, it defaults to a lower-case
|
||||
kebab-case version of the class name. When passed as an argument to
|
||||
``__init__`` or the class this can be :class:`locale_str`.
|
||||
description: :class:`str`
|
||||
kebab-case version of the class name.
|
||||
description: Union[:class:`str`, :class:`locale_str`]
|
||||
The description of the group. This shows up in the UI to describe
|
||||
the group. If not given, it defaults to the docstring of the
|
||||
class shortened to 100 characters. When passed as an argument to
|
||||
``__init__`` or the class this can be :class:`locale_str`.
|
||||
class shortened to 100 characters.
|
||||
auto_locale_strings: :class:`bool`
|
||||
If this is set to ``True``, then all translatable strings will implicitly
|
||||
be wrapped into :class:`locale_str` rather than :class:`str`. This could
|
||||
avoid some repetition and be more ergonomic for certain defaults such
|
||||
as default command names, command descriptions, and parameter names.
|
||||
Defaults to ``False``.
|
||||
default_permissions: Optional[:class:`~discord.Permissions`]
|
||||
The default permissions that can execute this group on Discord. Note
|
||||
that server administrators can override this value in the client.
|
||||
@ -1191,6 +1250,34 @@ class Group:
|
||||
Whether the command is NSFW and should only work in NSFW channels.
|
||||
Defaults to ``False``.
|
||||
|
||||
Due to a Discord limitation, this does not work on subcommands.
|
||||
parent: Optional[:class:`Group`]
|
||||
The parent application command. ``None`` if there isn't one.
|
||||
extras: :class:`dict`
|
||||
A dictionary that can be used to store extraneous data.
|
||||
The library will not touch any values or keys within this dictionary.
|
||||
|
||||
Attributes
|
||||
------------
|
||||
name: :class:`str`
|
||||
The name of the group.
|
||||
description: :class:`str`
|
||||
The description of the group. This shows up in the UI to describe
|
||||
the group.
|
||||
default_permissions: Optional[:class:`~discord.Permissions`]
|
||||
The default permissions that can execute this group on Discord. Note
|
||||
that server administrators can override this value in the client.
|
||||
Setting an empty permissions field will disallow anyone except server
|
||||
administrators from using the command in a guild.
|
||||
|
||||
Due to a Discord limitation, this does not work on subcommands.
|
||||
guild_only: :class:`bool`
|
||||
Whether the group should only be usable in guild contexts.
|
||||
|
||||
Due to a Discord limitation, this does not work on subcommands.
|
||||
nsfw: :class:`bool`
|
||||
Whether the command is NSFW and should only work in NSFW channels.
|
||||
|
||||
Due to a Discord limitation, this does not work on subcommands.
|
||||
parent: Optional[:class:`Group`]
|
||||
The parent group. ``None`` if there isn't one.
|
||||
@ -1276,6 +1363,7 @@ class Group:
|
||||
guild_ids: Optional[List[int]] = None,
|
||||
guild_only: bool = MISSING,
|
||||
nsfw: bool = MISSING,
|
||||
auto_locale_strings: bool = False,
|
||||
default_permissions: Optional[Permissions] = MISSING,
|
||||
extras: Dict[Any, Any] = MISSING,
|
||||
):
|
||||
@ -1364,6 +1452,17 @@ class Group:
|
||||
raise ValueError('groups can only be nested at most one level')
|
||||
parent.add_command(self)
|
||||
|
||||
if auto_locale_strings:
|
||||
self._convert_to_locale_strings()
|
||||
|
||||
def _convert_to_locale_strings(self) -> None:
|
||||
if self._locale_name is None:
|
||||
self._locale_name = locale_str(self.name)
|
||||
if self._locale_description is None:
|
||||
self._locale_description = locale_str(self.description)
|
||||
|
||||
# I don't know if propagating to the children is the right behaviour here.
|
||||
|
||||
def __set_name__(self, owner: Type[Any], name: str) -> None:
|
||||
self._attr = name
|
||||
self.module = owner.__module__
|
||||
@ -1653,6 +1752,7 @@ class Group:
|
||||
name: Union[str, locale_str] = MISSING,
|
||||
description: Union[str, locale_str] = MISSING,
|
||||
nsfw: bool = False,
|
||||
auto_locale_strings: bool = False,
|
||||
extras: Dict[Any, Any] = MISSING,
|
||||
) -> Callable[[CommandCallback[GroupT, P, T]], Command[GroupT, P, T]]:
|
||||
"""Creates an application command under this group.
|
||||
@ -1668,6 +1768,12 @@ class Group:
|
||||
of the callback shortened to 100 characters.
|
||||
nsfw: :class:`bool`
|
||||
Whether the command is NSFW and should only work in NSFW channels. Defaults to ``False``.
|
||||
auto_locale_strings: :class:`bool`
|
||||
If this is set to ``True``, then all translatable strings will implicitly
|
||||
be wrapped into :class:`locale_str` rather than :class:`str`. This could
|
||||
avoid some repetition and be more ergonomic for certain defaults such
|
||||
as default command names, command descriptions, and parameter names.
|
||||
Defaults to ``False``.
|
||||
extras: :class:`dict`
|
||||
A dictionary that can be used to store extraneous data.
|
||||
The library will not touch any values or keys within this dictionary.
|
||||
@ -1691,6 +1797,7 @@ class Group:
|
||||
callback=func,
|
||||
nsfw=nsfw,
|
||||
parent=self,
|
||||
auto_locale_strings=auto_locale_strings,
|
||||
extras=extras,
|
||||
)
|
||||
self.add_command(command)
|
||||
@ -1704,6 +1811,7 @@ def command(
|
||||
name: Union[str, locale_str] = MISSING,
|
||||
description: Union[str, locale_str] = MISSING,
|
||||
nsfw: bool = False,
|
||||
auto_locale_strings: bool = False,
|
||||
extras: Dict[Any, Any] = MISSING,
|
||||
) -> Callable[[CommandCallback[GroupT, P, T]], Command[GroupT, P, T]]:
|
||||
"""Creates an application command from a regular function.
|
||||
@ -1721,6 +1829,12 @@ def command(
|
||||
Whether the command is NSFW and should only work in NSFW channels. Defaults to ``False``.
|
||||
|
||||
Due to a Discord limitation, this does not work on subcommands.
|
||||
auto_locale_strings: :class:`bool`
|
||||
If this is set to ``True``, then all translatable strings will implicitly
|
||||
be wrapped into :class:`locale_str` rather than :class:`str`. This could
|
||||
avoid some repetition and be more ergonomic for certain defaults such
|
||||
as default command names, command descriptions, and parameter names.
|
||||
Defaults to ``False``.
|
||||
extras: :class:`dict`
|
||||
A dictionary that can be used to store extraneous data.
|
||||
The library will not touch any values or keys within this dictionary.
|
||||
@ -1744,6 +1858,7 @@ def command(
|
||||
callback=func,
|
||||
parent=None,
|
||||
nsfw=nsfw,
|
||||
auto_locale_strings=auto_locale_strings,
|
||||
extras=extras,
|
||||
)
|
||||
|
||||
@ -1754,6 +1869,7 @@ def context_menu(
|
||||
*,
|
||||
name: Union[str, locale_str] = MISSING,
|
||||
nsfw: bool = False,
|
||||
auto_locale_strings: bool = False,
|
||||
extras: Dict[Any, Any] = MISSING,
|
||||
) -> Callable[[ContextMenuCallback], ContextMenu]:
|
||||
"""Creates an application command context menu from a regular function.
|
||||
@ -1785,6 +1901,12 @@ def context_menu(
|
||||
Whether the command is NSFW and should only work in NSFW channels. Defaults to ``False``.
|
||||
|
||||
Due to a Discord limitation, this does not work on subcommands.
|
||||
auto_locale_strings: :class:`bool`
|
||||
If this is set to ``True``, then all translatable strings will implicitly
|
||||
be wrapped into :class:`locale_str` rather than :class:`str`. This could
|
||||
avoid some repetition and be more ergonomic for certain defaults such
|
||||
as default command names, command descriptions, and parameter names.
|
||||
Defaults to ``False``.
|
||||
extras: :class:`dict`
|
||||
A dictionary that can be used to store extraneous data.
|
||||
The library will not touch any values or keys within this dictionary.
|
||||
@ -1795,7 +1917,13 @@ def context_menu(
|
||||
raise TypeError('context menu function must be a coroutine function')
|
||||
|
||||
actual_name = func.__name__.title() if name is MISSING else name
|
||||
return ContextMenu(name=actual_name, nsfw=nsfw, callback=func, extras=extras)
|
||||
return ContextMenu(
|
||||
name=actual_name,
|
||||
nsfw=nsfw,
|
||||
callback=func,
|
||||
auto_locale_strings=auto_locale_strings,
|
||||
extras=extras,
|
||||
)
|
||||
|
||||
return decorator
|
||||
|
||||
|
@ -176,6 +176,19 @@ class CommandParameter:
|
||||
|
||||
return base
|
||||
|
||||
def _convert_to_locale_strings(self) -> None:
|
||||
if self._rename is MISSING:
|
||||
self._rename = locale_str(self.name)
|
||||
elif isinstance(self._rename, str):
|
||||
self._rename = locale_str(self._rename)
|
||||
|
||||
if isinstance(self.description, str):
|
||||
self.description = locale_str(self.description)
|
||||
|
||||
for choice in self.choices:
|
||||
if choice._locale_name is None:
|
||||
choice._locale_name = locale_str(choice.name)
|
||||
|
||||
def is_choice_annotation(self) -> bool:
|
||||
return getattr(self._annotation, '__discord_app_commands_is_choice__', False)
|
||||
|
||||
|
@ -838,6 +838,7 @@ class CommandTree(Generic[ClientT]):
|
||||
nsfw: bool = False,
|
||||
guild: Optional[Snowflake] = MISSING,
|
||||
guilds: Sequence[Snowflake] = MISSING,
|
||||
auto_locale_strings: bool = False,
|
||||
extras: Dict[Any, Any] = MISSING,
|
||||
) -> Callable[[CommandCallback[Group, P, T]], Command[Group, P, T]]:
|
||||
"""Creates an application command directly under this tree.
|
||||
@ -862,6 +863,12 @@ class CommandTree(Generic[ClientT]):
|
||||
The list of guilds to add the command to. This cannot be mixed
|
||||
with the ``guild`` parameter. If no guilds are given at all
|
||||
then it becomes a global command instead.
|
||||
auto_locale_strings: :class:`bool`
|
||||
If this is set to ``True``, then all translatable strings will implicitly
|
||||
be wrapped into :class:`locale_str` rather than :class:`str`. This could
|
||||
avoid some repetition and be more ergonomic for certain defaults such
|
||||
as default command names, command descriptions, and parameter names.
|
||||
Defaults to ``False``.
|
||||
extras: :class:`dict`
|
||||
A dictionary that can be used to store extraneous data.
|
||||
The library will not touch any values or keys within this dictionary.
|
||||
@ -885,6 +892,7 @@ class CommandTree(Generic[ClientT]):
|
||||
callback=func,
|
||||
nsfw=nsfw,
|
||||
parent=None,
|
||||
auto_locale_strings=auto_locale_strings,
|
||||
extras=extras,
|
||||
)
|
||||
self.add_command(command, guild=guild, guilds=guilds)
|
||||
@ -899,6 +907,7 @@ class CommandTree(Generic[ClientT]):
|
||||
nsfw: bool = False,
|
||||
guild: Optional[Snowflake] = MISSING,
|
||||
guilds: Sequence[Snowflake] = MISSING,
|
||||
auto_locale_strings: bool = False,
|
||||
extras: Dict[Any, Any] = MISSING,
|
||||
) -> Callable[[ContextMenuCallback], ContextMenu]:
|
||||
"""Creates an application command context menu from a regular function directly under this tree.
|
||||
@ -937,6 +946,12 @@ class CommandTree(Generic[ClientT]):
|
||||
The list of guilds to add the command to. This cannot be mixed
|
||||
with the ``guild`` parameter. If no guilds are given at all
|
||||
then it becomes a global command instead.
|
||||
auto_locale_strings: :class:`bool`
|
||||
If this is set to ``True``, then all translatable strings will implicitly
|
||||
be wrapped into :class:`locale_str` rather than :class:`str`. This could
|
||||
avoid some repetition and be more ergonomic for certain defaults such
|
||||
as default command names, command descriptions, and parameter names.
|
||||
Defaults to ``False``.
|
||||
extras: :class:`dict`
|
||||
A dictionary that can be used to store extraneous data.
|
||||
The library will not touch any values or keys within this dictionary.
|
||||
@ -947,7 +962,13 @@ class CommandTree(Generic[ClientT]):
|
||||
raise TypeError('context menu function must be a coroutine function')
|
||||
|
||||
actual_name = func.__name__.title() if name is MISSING else name
|
||||
context_menu = ContextMenu(name=actual_name, nsfw=nsfw, callback=func, extras=extras)
|
||||
context_menu = ContextMenu(
|
||||
name=actual_name,
|
||||
nsfw=nsfw,
|
||||
callback=func,
|
||||
auto_locale_strings=auto_locale_strings,
|
||||
extras=extras,
|
||||
)
|
||||
self.add_command(context_menu, guild=guild, guilds=guilds)
|
||||
return context_menu
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user