Browse Source

Refactor ApplicationCommand ABC and implement default member permissions

pull/10109/head
dolfies 3 years ago
parent
commit
f57b179dcf
  1. 96
      discord/commands.py

96
discord/commands.py

@ -29,7 +29,8 @@ from typing import Any, Dict, List, Optional, Protocol, Tuple, Type, runtime_che
from .enums import AppCommandOptionType, AppCommandType, ChannelType, InteractionType, try_enum from .enums import AppCommandOptionType, AppCommandType, ChannelType, InteractionType, try_enum
from .errors import InvalidData from .errors import InvalidData
from .mixins import Hashable from .mixins import Hashable
from .utils import _generate_nonce from .permissions import Permissions
from .utils import _generate_nonce, _get_as_snowflake
if TYPE_CHECKING: if TYPE_CHECKING:
from .abc import Messageable, Snowflake from .abc import Messageable, Snowflake
@ -71,6 +72,8 @@ class ApplicationCommand(Protocol):
The type of application command. The type of application command.
default_permission: :class:`bool` default_permission: :class:`bool`
Whether the command is enabled in guilds by default. Whether the command is enabled in guilds by default.
dm_permission: :class:`bool`
Whether the command is enabled in DMs.
application: Optional[:class:`InteractionApplication`] application: Optional[:class:`InteractionApplication`]
The application this command belongs to. The application this command belongs to.
Only available if requested. Only available if requested.
@ -82,13 +85,15 @@ class ApplicationCommand(Protocol):
if TYPE_CHECKING: if TYPE_CHECKING:
_state: ConnectionState _state: ConnectionState
application_id: int _channel: Optional[Messageable]
_default_member_permissions: Optional[int]
name: str name: str
description: str description: str
version: int version: int
type: AppCommandType type: AppCommandType
target_channel: Optional[Messageable]
default_permission: bool default_permission: bool
dm_permission: bool
application_id: int
application: Optional[InteractionApplication] application: Optional[InteractionApplication]
def __str__(self) -> str: def __str__(self) -> str:
@ -119,6 +124,42 @@ class ApplicationCommand(Protocol):
state._interaction_cache.pop(nonce, None) state._interaction_cache.pop(nonce, None)
return i return i
def is_group(self) -> bool:
"""Query whether this command is a group.
Returns
-------
:class:`bool`
Whether this command is a group.
"""
return False
@property
def target_channel(self) -> Optional[Messageable]:
"""Optional[:class:`.abc.Messageable`]: The channel this application command will be used on.
You can set this in order to use this command in a different channel without re-fetching it.
"""
return self._channel
@target_channel.setter
def target_channel(self, value: Optional[Messageable]) -> None:
from .abc import Messageable
if not isinstance(value, Messageable) and value is not None:
raise TypeError('channel must derive from Messageable')
self._channel = value
@property
def default_member_permissions(self) -> Optional[Permissions]:
"""Optional[:class:`Permissions`]: The default permissions required to use this command.
..note::
This may be overrided on a guild-by-guild basis.
"""
perms = self._default_member_permissions
return Permissions(perms) if perms is not None else None
class BaseCommand(ApplicationCommand, Hashable): class BaseCommand(ApplicationCommand, Hashable):
"""Represents a base command. """Represents a base command.
@ -155,6 +196,8 @@ class BaseCommand(ApplicationCommand, Hashable):
The type of application command. The type of application command.
default_permission: :class:`bool` default_permission: :class:`bool`
Whether the command is enabled in guilds by default. Whether the command is enabled in guilds by default.
dm_permission: :class:`bool`
Whether the command is enabled in DMs.
application: Optional[:class:`InteractionApplication`] application: Optional[:class:`InteractionApplication`]
The application this command belongs to. The application this command belongs to.
Only available if requested. Only available if requested.
@ -171,10 +214,10 @@ class BaseCommand(ApplicationCommand, Hashable):
'default_permission', 'default_permission',
'application', 'application',
'application_id', 'application_id',
'dm_permission',
'_data', '_data',
'_state', '_state',
'_channel', '_channel',
'_dm_permission',
'_default_member_permissions', '_default_member_permissions',
) )
@ -188,42 +231,16 @@ class BaseCommand(ApplicationCommand, Hashable):
self.id: int = int(data['id']) self.id: int = int(data['id'])
self.version = int(data['version']) self.version = int(data['version'])
self.type = try_enum(AppCommandType, data['type']) self.type = try_enum(AppCommandType, data['type'])
self.default_permission: bool = data.get('default_permission', True)
self._dm_permission = data.get('dm_permission')
self._default_member_permissions = data['default_member_permissions']
self.application = application self.application = application
self._default_member_permissions = _get_as_snowflake(data, 'default_member_permissions')
self.default_permission: bool = data.get('default_permission', True)
dm_permission = data.get('dm_permission') # Null means true?
self.dm_permission = dm_permission if dm_permission is not None else True
def __repr__(self) -> str: def __repr__(self) -> str:
return f'<{self.__class__.__name__} id={self.id} name={self.name!r}>' return f'<{self.__class__.__name__} id={self.id} name={self.name!r}>'
def is_group(self) -> bool:
"""Query whether this command is a group.
Here for compatibility purposes.
Returns
-------
:class:`bool`
Whether this command is a group.
"""
return False
@property
def target_channel(self) -> Optional[Messageable]:
"""Optional[:class:`.abc.Messageable`]: The channel this application command will be used on.
You can set this in order to use this command in a different channel without re-fetching it.
"""
return self._channel
@target_channel.setter
def target_channel(self, value: Optional[Messageable]) -> None:
from .abc import Messageable
if not isinstance(value, Messageable) and value is not None:
raise TypeError('channel must derive from Messageable')
self._channel = value
class SlashMixin(ApplicationCommand, Protocol): class SlashMixin(ApplicationCommand, Protocol):
if TYPE_CHECKING: if TYPE_CHECKING:
@ -576,6 +593,10 @@ class SubCommand(SlashMixin):
BASE += f' children={len(self.children)}' BASE += f' children={len(self.children)}'
return BASE + '>' return BASE + '>'
@property
def _default_member_permissions(self) -> Optional[int]:
return self._parent._default_member_permissions
@property @property
def application_id(self) -> int: def application_id(self) -> int:
""":class:`int`: The ID of the application this command belongs to.""" """:class:`int`: The ID of the application this command belongs to."""
@ -591,6 +612,11 @@ class SubCommand(SlashMixin):
""":class:`bool`: Whether the command is enabled in guilds by default.""" """:class:`bool`: Whether the command is enabled in guilds by default."""
return self._parent.default_permission return self._parent.default_permission
@property
def dm_permission(self) -> bool:
""":class:`bool`: Whether the command is enabled in DMs."""
return self._parent.dm_permission
def is_group(self) -> bool: def is_group(self) -> bool:
"""Query whether this command is a group. """Query whether this command is a group.

Loading…
Cancel
Save