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 .errors import InvalidData
from .mixins import Hashable
from .utils import _generate_nonce
from .permissions import Permissions
from .utils import _generate_nonce, _get_as_snowflake
if TYPE_CHECKING:
from .abc import Messageable, Snowflake
@ -71,6 +72,8 @@ class ApplicationCommand(Protocol):
The type of application command.
default_permission: :class:`bool`
Whether the command is enabled in guilds by default.
dm_permission: :class:`bool`
Whether the command is enabled in DMs.
application: Optional[:class:`InteractionApplication`]
The application this command belongs to.
Only available if requested.
@ -82,13 +85,15 @@ class ApplicationCommand(Protocol):
if TYPE_CHECKING:
_state: ConnectionState
application_id: int
_channel: Optional[Messageable]
_default_member_permissions: Optional[int]
name: str
description: str
version: int
type: AppCommandType
target_channel: Optional[Messageable]
default_permission: bool
dm_permission: bool
application_id: int
application: Optional[InteractionApplication]
def __str__(self) -> str:
@ -119,6 +124,42 @@ class ApplicationCommand(Protocol):
state._interaction_cache.pop(nonce, None)
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):
"""Represents a base command.
@ -155,6 +196,8 @@ class BaseCommand(ApplicationCommand, Hashable):
The type of application command.
default_permission: :class:`bool`
Whether the command is enabled in guilds by default.
dm_permission: :class:`bool`
Whether the command is enabled in DMs.
application: Optional[:class:`InteractionApplication`]
The application this command belongs to.
Only available if requested.
@ -171,10 +214,10 @@ class BaseCommand(ApplicationCommand, Hashable):
'default_permission',
'application',
'application_id',
'dm_permission',
'_data',
'_state',
'_channel',
'_dm_permission',
'_default_member_permissions',
)
@ -188,42 +231,16 @@ class BaseCommand(ApplicationCommand, Hashable):
self.id: int = int(data['id'])
self.version = int(data['version'])
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._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:
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):
if TYPE_CHECKING:
@ -576,6 +593,10 @@ class SubCommand(SlashMixin):
BASE += f' children={len(self.children)}'
return BASE + '>'
@property
def _default_member_permissions(self) -> Optional[int]:
return self._parent._default_member_permissions
@property
def application_id(self) -> int:
""":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."""
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:
"""Query whether this command is a group.

Loading…
Cancel
Save