Voice et bot modif
This commit is contained in:
parent
189d56026b
commit
7333a22bcd
10774 changed files with 634644 additions and 933308 deletions
|
|
@ -13,7 +13,7 @@ __title__ = 'discord'
|
|||
__author__ = 'Rapptz'
|
||||
__license__ = 'MIT'
|
||||
__copyright__ = 'Copyright 2015-present Rapptz'
|
||||
__version__ = '2.6.4'
|
||||
__version__ = '2.7.1'
|
||||
|
||||
__path__ = __import__('pkgutil').extend_path(__path__, __name__)
|
||||
|
||||
|
|
@ -75,6 +75,7 @@ from .subscription import *
|
|||
from .presences import *
|
||||
from .primary_guild import *
|
||||
from .onboarding import *
|
||||
from .collectible import *
|
||||
|
||||
|
||||
class VersionInfo(NamedTuple):
|
||||
|
|
@ -85,7 +86,7 @@ class VersionInfo(NamedTuple):
|
|||
serial: int
|
||||
|
||||
|
||||
version_info: VersionInfo = VersionInfo(major=2, minor=6, micro=4, releaselevel='final', serial=0)
|
||||
version_info: VersionInfo = VersionInfo(major=2, minor=7, micro=1, releaselevel='final', serial=0)
|
||||
|
||||
logging.getLogger(__name__).addHandler(logging.NullHandler())
|
||||
|
||||
|
|
|
|||
|
|
@ -48,6 +48,14 @@ def show_version() -> None:
|
|||
entries.append(f' - discord.py metadata: v{version}')
|
||||
|
||||
entries.append(f'- aiohttp v{aiohttp.__version__}')
|
||||
|
||||
try:
|
||||
import davey # type: ignore
|
||||
except ImportError:
|
||||
entries.append('- davey not found')
|
||||
else:
|
||||
entries.append(f'- davey v{davey.__version__}')
|
||||
|
||||
uname = platform.uname()
|
||||
entries.append('- system info: {0.system} {0.release} {0.version}'.format(uname))
|
||||
print('\n'.join(entries))
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -195,6 +195,9 @@ async def _purge_helper(
|
|||
count = 0
|
||||
await asyncio.sleep(1)
|
||||
|
||||
if not message.type.is_deletable():
|
||||
continue
|
||||
|
||||
if not check(message):
|
||||
continue
|
||||
|
||||
|
|
@ -818,7 +821,7 @@ class GuildChannel:
|
|||
if obj.is_default():
|
||||
return base
|
||||
|
||||
overwrite = utils.get(self._overwrites, type=_Overwrites.ROLE, id=obj.id)
|
||||
overwrite = utils.find(lambda ow: ow.type == _Overwrites.ROLE and ow.id == obj.id, self._overwrites)
|
||||
if overwrite is not None:
|
||||
base.handle_overwrite(overwrite.allow, overwrite.deny)
|
||||
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1802,7 +1802,7 @@ class Group:
|
|||
yield from command.walk_commands()
|
||||
|
||||
@mark_overrideable
|
||||
async def on_error(self, interaction: Interaction, error: AppCommandError, /) -> None:
|
||||
async def on_error(self, interaction: Interaction[ClientT], error: AppCommandError, /) -> None:
|
||||
"""|coro|
|
||||
|
||||
A callback that is called when a child's command raises an :exc:`AppCommandError`.
|
||||
|
|
@ -1850,7 +1850,7 @@ class Group:
|
|||
self.on_error = coro # type: ignore
|
||||
return coro
|
||||
|
||||
async def interaction_check(self, interaction: Interaction, /) -> bool:
|
||||
async def interaction_check(self, interaction: Interaction[ClientT], /) -> bool:
|
||||
"""|coro|
|
||||
|
||||
A callback that is called when an interaction happens within the group
|
||||
|
|
@ -2180,8 +2180,9 @@ def describe(**parameters: Union[str, locale_str]) -> Callable[[T], T]:
|
|||
'''
|
||||
|
||||
def decorator(inner: T) -> T:
|
||||
if isinstance(inner, Command):
|
||||
_populate_descriptions(inner._params, parameters)
|
||||
unwrapped = getattr(inner, '__discord_app_commands_unwrap__', inner) or inner
|
||||
if isinstance(unwrapped, Command):
|
||||
_populate_descriptions(unwrapped._params, parameters)
|
||||
else:
|
||||
try:
|
||||
inner.__discord_app_commands_param_description__.update(parameters) # type: ignore # Runtime attribute access
|
||||
|
|
@ -2223,8 +2224,9 @@ def rename(**parameters: Union[str, locale_str]) -> Callable[[T], T]:
|
|||
"""
|
||||
|
||||
def decorator(inner: T) -> T:
|
||||
if isinstance(inner, Command):
|
||||
_populate_renames(inner._params, parameters)
|
||||
unwrapped = getattr(inner, '__discord_app_commands_unwrap__', inner) or inner
|
||||
if isinstance(unwrapped, Command):
|
||||
_populate_renames(unwrapped._params, parameters)
|
||||
else:
|
||||
try:
|
||||
inner.__discord_app_commands_param_rename__.update(parameters) # type: ignore # Runtime attribute access
|
||||
|
|
@ -2292,8 +2294,9 @@ def choices(**parameters: List[Choice[ChoiceT]]) -> Callable[[T], T]:
|
|||
"""
|
||||
|
||||
def decorator(inner: T) -> T:
|
||||
if isinstance(inner, Command):
|
||||
_populate_choices(inner._params, parameters)
|
||||
unwrapped = getattr(inner, '__discord_app_commands_unwrap__', inner) or inner
|
||||
if isinstance(unwrapped, Command):
|
||||
_populate_choices(unwrapped._params, parameters)
|
||||
else:
|
||||
try:
|
||||
inner.__discord_app_commands_param_choices__.update(parameters) # type: ignore # Runtime attribute access
|
||||
|
|
@ -2351,8 +2354,9 @@ def autocomplete(**parameters: AutocompleteCallback[GroupT, ChoiceT]) -> Callabl
|
|||
"""
|
||||
|
||||
def decorator(inner: T) -> T:
|
||||
if isinstance(inner, Command):
|
||||
_populate_autocomplete(inner._params, parameters)
|
||||
unwrapped = getattr(inner, '__discord_app_commands_unwrap__', inner) or inner
|
||||
if isinstance(unwrapped, Command):
|
||||
_populate_autocomplete(unwrapped._params, parameters)
|
||||
else:
|
||||
try:
|
||||
inner.__discord_app_commands_param_autocomplete__.update(parameters) # type: ignore # Runtime attribute access
|
||||
|
|
@ -2408,13 +2412,14 @@ def guilds(*guild_ids: Union[Snowflake, int]) -> Callable[[T], T]:
|
|||
defaults: List[int] = [g if isinstance(g, int) else g.id for g in guild_ids]
|
||||
|
||||
def decorator(inner: T) -> T:
|
||||
if isinstance(inner, (Group, ContextMenu)):
|
||||
inner._guild_ids = defaults
|
||||
elif isinstance(inner, Command):
|
||||
if inner.parent is not None:
|
||||
unwrapped = getattr(inner, '__discord_app_commands_unwrap__', inner) or inner
|
||||
if isinstance(unwrapped, (Group, ContextMenu)):
|
||||
unwrapped._guild_ids = defaults
|
||||
elif isinstance(unwrapped, Command):
|
||||
if unwrapped.parent is not None:
|
||||
raise ValueError('child commands of a group cannot have default guilds set')
|
||||
|
||||
inner._guild_ids = defaults
|
||||
unwrapped._guild_ids = defaults
|
||||
else:
|
||||
# Runtime attribute assignment
|
||||
inner.__discord_app_commands_default_guilds__ = defaults # type: ignore
|
||||
|
|
@ -2470,13 +2475,14 @@ def check(predicate: Check) -> Callable[[T], T]:
|
|||
"""
|
||||
|
||||
def decorator(func: CheckInputParameter) -> CheckInputParameter:
|
||||
if isinstance(func, (Command, ContextMenu)):
|
||||
func.checks.append(predicate)
|
||||
unwrapped = getattr(func, '__discord_app_commands_unwrap__', func) or func
|
||||
if isinstance(unwrapped, (Command, ContextMenu)):
|
||||
unwrapped.checks.append(predicate)
|
||||
else:
|
||||
if not hasattr(func, '__discord_app_commands_checks__'):
|
||||
func.__discord_app_commands_checks__ = []
|
||||
func.__discord_app_commands_checks__ = [] # type: ignore # Runtime attribute assignment
|
||||
|
||||
func.__discord_app_commands_checks__.append(predicate)
|
||||
func.__discord_app_commands_checks__.append(predicate) # type: ignore # Runtime attribute access
|
||||
|
||||
return func
|
||||
|
||||
|
|
@ -2513,10 +2519,11 @@ def guild_only(func: Optional[T] = None) -> Union[T, Callable[[T], T]]:
|
|||
"""
|
||||
|
||||
def inner(f: T) -> T:
|
||||
if isinstance(f, (Command, Group, ContextMenu)):
|
||||
f.guild_only = True
|
||||
allowed_contexts = f.allowed_contexts or AppCommandContext()
|
||||
f.allowed_contexts = allowed_contexts
|
||||
unwrapped = getattr(f, '__discord_app_commands_unwrap__', f) or f
|
||||
if isinstance(unwrapped, (Command, Group, ContextMenu)):
|
||||
unwrapped.guild_only = True
|
||||
allowed_contexts = unwrapped.allowed_contexts or AppCommandContext()
|
||||
unwrapped.allowed_contexts = allowed_contexts
|
||||
else:
|
||||
f.__discord_app_commands_guild_only__ = True # type: ignore # Runtime attribute assignment
|
||||
|
||||
|
|
@ -2567,10 +2574,11 @@ def private_channel_only(func: Optional[T] = None) -> Union[T, Callable[[T], T]]
|
|||
"""
|
||||
|
||||
def inner(f: T) -> T:
|
||||
if isinstance(f, (Command, Group, ContextMenu)):
|
||||
f.guild_only = False
|
||||
allowed_contexts = f.allowed_contexts or AppCommandContext()
|
||||
f.allowed_contexts = allowed_contexts
|
||||
unwrapped = getattr(f, '__discord_app_commands_unwrap__', f) or f
|
||||
if isinstance(unwrapped, (Command, Group, ContextMenu)):
|
||||
unwrapped.guild_only = False
|
||||
allowed_contexts = unwrapped.allowed_contexts or AppCommandContext()
|
||||
unwrapped.allowed_contexts = allowed_contexts
|
||||
else:
|
||||
allowed_contexts = getattr(f, '__discord_app_commands_contexts__', None) or AppCommandContext()
|
||||
f.__discord_app_commands_contexts__ = allowed_contexts # type: ignore # Runtime attribute assignment
|
||||
|
|
@ -2617,10 +2625,11 @@ def dm_only(func: Optional[T] = None) -> Union[T, Callable[[T], T]]:
|
|||
"""
|
||||
|
||||
def inner(f: T) -> T:
|
||||
if isinstance(f, (Command, Group, ContextMenu)):
|
||||
f.guild_only = False
|
||||
allowed_contexts = f.allowed_contexts or AppCommandContext()
|
||||
f.allowed_contexts = allowed_contexts
|
||||
unwrapped = getattr(f, '__discord_app_commands_unwrap__', f) or f
|
||||
if isinstance(unwrapped, (Command, Group, ContextMenu)):
|
||||
unwrapped.guild_only = False
|
||||
allowed_contexts = unwrapped.allowed_contexts or AppCommandContext()
|
||||
unwrapped.allowed_contexts = allowed_contexts
|
||||
else:
|
||||
allowed_contexts = getattr(f, '__discord_app_commands_contexts__', None) or AppCommandContext()
|
||||
f.__discord_app_commands_contexts__ = allowed_contexts # type: ignore # Runtime attribute assignment
|
||||
|
|
@ -2658,10 +2667,11 @@ def allowed_contexts(guilds: bool = MISSING, dms: bool = MISSING, private_channe
|
|||
"""
|
||||
|
||||
def inner(f: T) -> T:
|
||||
if isinstance(f, (Command, Group, ContextMenu)):
|
||||
f.guild_only = False
|
||||
allowed_contexts = f.allowed_contexts or AppCommandContext()
|
||||
f.allowed_contexts = allowed_contexts
|
||||
unwrapped = getattr(f, '__discord_app_commands_unwrap__', f) or f
|
||||
if isinstance(unwrapped, (Command, Group, ContextMenu)):
|
||||
unwrapped.guild_only = False
|
||||
allowed_contexts = unwrapped.allowed_contexts or AppCommandContext()
|
||||
unwrapped.allowed_contexts = allowed_contexts
|
||||
else:
|
||||
allowed_contexts = getattr(f, '__discord_app_commands_contexts__', None) or AppCommandContext()
|
||||
f.__discord_app_commands_contexts__ = allowed_contexts # type: ignore # Runtime attribute assignment
|
||||
|
|
@ -2709,9 +2719,10 @@ def guild_install(func: Optional[T] = None) -> Union[T, Callable[[T], T]]:
|
|||
"""
|
||||
|
||||
def inner(f: T) -> T:
|
||||
if isinstance(f, (Command, Group, ContextMenu)):
|
||||
allowed_installs = f.allowed_installs or AppInstallationType()
|
||||
f.allowed_installs = allowed_installs
|
||||
unwrapped = getattr(f, '__discord_app_commands_unwrap__', f) or f
|
||||
if isinstance(unwrapped, (Command, Group, ContextMenu)):
|
||||
allowed_installs = unwrapped.allowed_installs or AppInstallationType()
|
||||
unwrapped.allowed_installs = allowed_installs
|
||||
else:
|
||||
allowed_installs = getattr(f, '__discord_app_commands_installation_types__', None) or AppInstallationType()
|
||||
f.__discord_app_commands_installation_types__ = allowed_installs # type: ignore # Runtime attribute assignment
|
||||
|
|
@ -2757,9 +2768,10 @@ def user_install(func: Optional[T] = None) -> Union[T, Callable[[T], T]]:
|
|||
"""
|
||||
|
||||
def inner(f: T) -> T:
|
||||
if isinstance(f, (Command, Group, ContextMenu)):
|
||||
allowed_installs = f.allowed_installs or AppInstallationType()
|
||||
f.allowed_installs = allowed_installs
|
||||
unwrapped = getattr(f, '__discord_app_commands_unwrap__', f) or f
|
||||
if isinstance(unwrapped, (Command, Group, ContextMenu)):
|
||||
allowed_installs = unwrapped.allowed_installs or AppInstallationType()
|
||||
unwrapped.allowed_installs = allowed_installs
|
||||
else:
|
||||
allowed_installs = getattr(f, '__discord_app_commands_installation_types__', None) or AppInstallationType()
|
||||
f.__discord_app_commands_installation_types__ = allowed_installs # type: ignore # Runtime attribute assignment
|
||||
|
|
@ -2801,9 +2813,10 @@ def allowed_installs(
|
|||
"""
|
||||
|
||||
def inner(f: T) -> T:
|
||||
if isinstance(f, (Command, Group, ContextMenu)):
|
||||
allowed_installs = f.allowed_installs or AppInstallationType()
|
||||
f.allowed_installs = allowed_installs
|
||||
unwrapped = getattr(f, '__discord_app_commands_unwrap__', f) or f
|
||||
if isinstance(unwrapped, (Command, Group, ContextMenu)):
|
||||
allowed_installs = unwrapped.allowed_installs or AppInstallationType()
|
||||
unwrapped.allowed_installs = allowed_installs
|
||||
else:
|
||||
allowed_installs = getattr(f, '__discord_app_commands_installation_types__', None) or AppInstallationType()
|
||||
f.__discord_app_commands_installation_types__ = allowed_installs # type: ignore # Runtime attribute assignment
|
||||
|
|
@ -2874,8 +2887,9 @@ def default_permissions(perms_obj: Optional[Permissions] = None, /, **perms: Unp
|
|||
permissions = Permissions(**perms)
|
||||
|
||||
def decorator(func: T) -> T:
|
||||
if isinstance(func, (Command, Group, ContextMenu)):
|
||||
func.default_permissions = permissions
|
||||
unwrapped = getattr(func, '__discord_app_commands_unwrap__', func) or func
|
||||
if isinstance(unwrapped, (Command, Group, ContextMenu)):
|
||||
unwrapped.default_permissions = permissions
|
||||
else:
|
||||
func.__discord_app_commands_default_permissions__ = permissions # type: ignore # Runtime attribute assignment
|
||||
|
||||
|
|
|
|||
|
|
@ -597,8 +597,7 @@ class AppCommandChannel(Hashable):
|
|||
slowmode_delay: :class:`int`
|
||||
The number of seconds a member must wait between sending messages
|
||||
in this channel. A value of ``0`` denotes that it is disabled.
|
||||
Bots and users with :attr:`~discord.Permissions.manage_channels` or
|
||||
:attr:`~discord.Permissions.manage_messages` bypass slowmode.
|
||||
Bots and users with :attr:`~discord.Permissions.bypass_slowmode` bypass slowmode.
|
||||
|
||||
.. versionadded:: 2.6
|
||||
nsfw: :class:`bool`
|
||||
|
|
@ -779,8 +778,7 @@ class AppCommandThread(Hashable):
|
|||
slowmode_delay: :class:`int`
|
||||
The number of seconds a member must wait between sending messages
|
||||
in this thread. A value of ``0`` denotes that it is disabled.
|
||||
Bots and users with :attr:`~discord.Permissions.manage_channels` or
|
||||
:attr:`~discord.Permissions.manage_messages` bypass slowmode.
|
||||
Bots and users with :attr:`~discord.Permissions.bypass_slowmode` bypass slowmode.
|
||||
|
||||
.. versionadded:: 2.6
|
||||
message_count: :class:`int`
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ DEALINGS IN THE SOFTWARE.
|
|||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
import datetime
|
||||
import inspect
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
|
@ -52,7 +53,7 @@ from ..channel import StageChannel, VoiceChannel, TextChannel, CategoryChannel,
|
|||
from ..abc import GuildChannel
|
||||
from ..threads import Thread
|
||||
from ..enums import Enum as InternalEnum, AppCommandOptionType, ChannelType, Locale
|
||||
from ..utils import MISSING, maybe_coroutine, _human_join
|
||||
from ..utils import MISSING, maybe_coroutine, _human_join, TIMESTAMP_PATTERN
|
||||
from ..user import User
|
||||
from ..role import Role
|
||||
from ..member import Member
|
||||
|
|
@ -62,6 +63,7 @@ from .._types import ClientT
|
|||
__all__ = (
|
||||
'Transformer',
|
||||
'Transform',
|
||||
'Timestamp',
|
||||
'Range',
|
||||
)
|
||||
|
||||
|
|
@ -681,6 +683,41 @@ class UnionChannelTransformer(BaseChannelTransformer[ClientT]):
|
|||
return resolved
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
Timestamp = datetime.datetime
|
||||
else:
|
||||
|
||||
class Timestamp(Transformer[ClientT]):
|
||||
"""A type annotation that can be applied to a parameter for transforming a :ddocs:`Discord style timestamp <reference#message-formatting>` input to a
|
||||
:class:`datetime.datetime`.
|
||||
|
||||
|
||||
.. versionadded:: 2.7
|
||||
|
||||
.. warning::
|
||||
Due to a Discord limitation, no timezone is provided with the input. The UTC timezone has been supplanted instead.
|
||||
|
||||
Examples
|
||||
---------
|
||||
|
||||
.. code-block:: python3
|
||||
|
||||
@app_commands.command()
|
||||
async def datetime(interaction: discord.Interaction, value: app_commands.Timestamp):
|
||||
await interaction.response.send_message(value.isoformat())
|
||||
"""
|
||||
|
||||
@property
|
||||
def type(self) -> AppCommandOptionType:
|
||||
return AppCommandOptionType.string
|
||||
|
||||
async def transform(self, interaction: Interaction[ClientT], value: Any, /):
|
||||
match = TIMESTAMP_PATTERN.match(value)
|
||||
if not match:
|
||||
raise TransformerError(value, AppCommandOptionType.string, self)
|
||||
return datetime.datetime.fromtimestamp(int(match[1]), tz=datetime.timezone.utc)
|
||||
|
||||
|
||||
CHANNEL_TO_TYPES: Dict[Any, List[ChannelType]] = {
|
||||
AppCommandChannel: [
|
||||
ChannelType.stage_voice,
|
||||
|
|
|
|||
|
|
@ -1289,7 +1289,12 @@ class CommandTree(Generic[ClientT]):
|
|||
await command._invoke_autocomplete(interaction, focused, namespace)
|
||||
except Exception:
|
||||
# Suppress exception since it can't be handled anyway.
|
||||
_log.exception('Ignoring exception in autocomplete for %r', command.qualified_name)
|
||||
_log.exception(
|
||||
'Ignoring exception in autocomplete for %r (Guild: %s, User: %s)',
|
||||
command.qualified_name,
|
||||
interaction.guild_id,
|
||||
interaction.user.id,
|
||||
)
|
||||
|
||||
return
|
||||
|
||||
|
|
|
|||
|
|
@ -355,6 +355,16 @@ class Asset(AssetMixin):
|
|||
animated=False,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def _from_user_collectible(cls, state: _State, asset: str, animated: bool = False) -> Self:
|
||||
name = 'static.png' if not animated else 'asset.webm'
|
||||
return cls(
|
||||
state,
|
||||
url=f'{cls.BASE}/assets/collectibles/{asset}{name}',
|
||||
key=asset,
|
||||
animated=animated,
|
||||
)
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self._url
|
||||
|
||||
|
|
|
|||
|
|
@ -630,11 +630,6 @@ class _AuditLogProxyAutoModAction(_AuditLogProxy):
|
|||
channel: Optional[Union[abc.GuildChannel, Thread]]
|
||||
|
||||
|
||||
class _AuditLogProxyAutoModActionQuarantineUser(_AuditLogProxy):
|
||||
automod_rule_name: str
|
||||
automod_rule_trigger_type: str
|
||||
|
||||
|
||||
class _AuditLogProxyMemberKickOrMemberRoleUpdate(_AuditLogProxy):
|
||||
integration_type: Optional[str]
|
||||
|
||||
|
|
@ -725,7 +720,6 @@ class AuditLogEntry(Hashable):
|
|||
_AuditLogProxyStageInstanceAction,
|
||||
_AuditLogProxyMessageBulkDelete,
|
||||
_AuditLogProxyAutoModAction,
|
||||
_AuditLogProxyAutoModActionQuarantineUser,
|
||||
_AuditLogProxyMemberKickOrMemberRoleUpdate,
|
||||
Member, User, None, PartialIntegration,
|
||||
Role, Object
|
||||
|
|
@ -766,6 +760,7 @@ class AuditLogEntry(Hashable):
|
|||
self.action is enums.AuditLogAction.automod_block_message
|
||||
or self.action is enums.AuditLogAction.automod_flag_message
|
||||
or self.action is enums.AuditLogAction.automod_timeout_member
|
||||
or self.action is enums.AuditLogAction.automod_quarantine_user
|
||||
):
|
||||
channel_id = utils._get_as_snowflake(extra, 'channel_id')
|
||||
channel = None
|
||||
|
|
@ -781,13 +776,6 @@ class AuditLogEntry(Hashable):
|
|||
),
|
||||
channel=channel,
|
||||
)
|
||||
elif self.action is enums.AuditLogAction.automod_quarantine_user:
|
||||
self.extra = _AuditLogProxyAutoModActionQuarantineUser(
|
||||
automod_rule_name=extra['auto_moderation_rule_name'],
|
||||
automod_rule_trigger_type=enums.try_enum(
|
||||
enums.AutoModRuleTriggerType, int(extra['auto_moderation_rule_trigger_type'])
|
||||
),
|
||||
)
|
||||
|
||||
elif self.action.name.startswith('overwrite_'):
|
||||
# the overwrite_ actions have a dict with some information
|
||||
|
|
|
|||
|
|
@ -322,8 +322,7 @@ class TextChannel(discord.abc.Messageable, discord.abc.GuildChannel, Hashable):
|
|||
slowmode_delay: :class:`int`
|
||||
The number of seconds a member must wait between sending messages
|
||||
in this channel. A value of ``0`` denotes that it is disabled.
|
||||
Bots and users with :attr:`~Permissions.manage_channels` or
|
||||
:attr:`~Permissions.manage_messages` bypass slowmode.
|
||||
Bots and users with :attr:`~Permissions.bypass_slowmode` bypass slowmode.
|
||||
nsfw: :class:`bool`
|
||||
If the channel is marked as "not safe for work" or "age restricted".
|
||||
default_auto_archive_duration: :class:`int`
|
||||
|
|
@ -1516,8 +1515,7 @@ class VoiceChannel(VocalGuildChannel):
|
|||
slowmode_delay: :class:`int`
|
||||
The number of seconds a member must wait between sending messages
|
||||
in this channel. A value of ``0`` denotes that it is disabled.
|
||||
Bots and users with :attr:`~Permissions.manage_channels` or
|
||||
:attr:`~Permissions.manage_messages` bypass slowmode.
|
||||
Bots and users with :attr:`~Permissions.bypass_slowmode` bypass slowmode.
|
||||
|
||||
.. versionadded:: 2.2
|
||||
"""
|
||||
|
|
@ -1744,8 +1742,7 @@ class StageChannel(VocalGuildChannel):
|
|||
slowmode_delay: :class:`int`
|
||||
The number of seconds a member must wait between sending messages
|
||||
in this channel. A value of ``0`` denotes that it is disabled.
|
||||
Bots and users with :attr:`~Permissions.manage_channels` or
|
||||
:attr:`~Permissions.manage_messages` bypass slowmode.
|
||||
Bots and users with :attr:`~Permissions.bypass_slowmode` bypass slowmode.
|
||||
|
||||
.. versionadded:: 2.2
|
||||
"""
|
||||
|
|
@ -2409,8 +2406,7 @@ class ForumChannel(discord.abc.GuildChannel, Hashable):
|
|||
slowmode_delay: :class:`int`
|
||||
The number of seconds a member must wait between creating threads
|
||||
in this forum. A value of ``0`` denotes that it is disabled.
|
||||
Bots and users with :attr:`~Permissions.manage_channels` or
|
||||
:attr:`~Permissions.manage_messages` bypass slowmode.
|
||||
Bots and users with :attr:`~Permissions.bypass_slowmode` bypass slowmode.
|
||||
nsfw: :class:`bool`
|
||||
If the forum is marked as "not safe for work" or "age restricted".
|
||||
default_auto_archive_duration: :class:`int`
|
||||
|
|
@ -2879,6 +2875,7 @@ class ForumChannel(discord.abc.GuildChannel, Hashable):
|
|||
applied_tags: Sequence[ForumTag] = ...,
|
||||
view: LayoutView,
|
||||
suppress_embeds: bool = ...,
|
||||
silent: bool = ...,
|
||||
reason: Optional[str] = ...,
|
||||
) -> ThreadWithMessage: ...
|
||||
|
||||
|
|
@ -2901,6 +2898,7 @@ class ForumChannel(discord.abc.GuildChannel, Hashable):
|
|||
applied_tags: Sequence[ForumTag] = ...,
|
||||
view: View = ...,
|
||||
suppress_embeds: bool = ...,
|
||||
silent: bool = ...,
|
||||
reason: Optional[str] = ...,
|
||||
) -> ThreadWithMessage: ...
|
||||
|
||||
|
|
@ -2922,6 +2920,7 @@ class ForumChannel(discord.abc.GuildChannel, Hashable):
|
|||
applied_tags: Sequence[ForumTag] = MISSING,
|
||||
view: BaseView = MISSING,
|
||||
suppress_embeds: bool = False,
|
||||
silent: bool = False,
|
||||
reason: Optional[str] = None,
|
||||
) -> ThreadWithMessage:
|
||||
"""|coro|
|
||||
|
|
@ -2976,6 +2975,11 @@ class ForumChannel(discord.abc.GuildChannel, Hashable):
|
|||
A list of stickers to upload. Must be a maximum of 3.
|
||||
suppress_embeds: :class:`bool`
|
||||
Whether to suppress embeds for the message. This sends the message without any embeds if set to ``True``.
|
||||
silent: :class:`bool`
|
||||
Whether to suppress push and desktop notifications for the message. This will increment the mention counter
|
||||
in the UI, but will not actually send a notification.
|
||||
|
||||
.. versionadded:: 2.7
|
||||
reason: :class:`str`
|
||||
The reason for creating a new thread. Shows up on the audit log.
|
||||
|
||||
|
|
@ -3008,8 +3012,10 @@ class ForumChannel(discord.abc.GuildChannel, Hashable):
|
|||
if view and not hasattr(view, '__discord_ui_view__'):
|
||||
raise TypeError(f'view parameter must be View not {view.__class__.__name__}')
|
||||
|
||||
if suppress_embeds:
|
||||
flags = MessageFlags._from_value(4)
|
||||
if suppress_embeds or silent:
|
||||
flags = MessageFlags._from_value(0)
|
||||
flags.suppress_embeds = suppress_embeds
|
||||
flags.suppress_notifications = silent
|
||||
else:
|
||||
flags = MISSING
|
||||
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ if TYPE_CHECKING:
|
|||
from .abc import Messageable, PrivateChannel, Snowflake, SnowflakeTime
|
||||
from .app_commands import Command, ContextMenu
|
||||
from .automod import AutoModAction, AutoModRule
|
||||
from .channel import DMChannel, GroupChannel
|
||||
from .channel import DMChannel, GroupChannel, VoiceChannelEffect
|
||||
from .ext.commands import AutoShardedBot, Bot, Context, CommandError
|
||||
from .guild import GuildChannel
|
||||
from .integrations import Integration
|
||||
|
|
@ -340,6 +340,10 @@ class Client:
|
|||
VoiceClient.warn_nacl = False
|
||||
_log.warning('PyNaCl is not installed, voice will NOT be supported')
|
||||
|
||||
if VoiceClient.warn_dave:
|
||||
VoiceClient.warn_dave = False
|
||||
_log.warning('davey is not installed, voice will NOT be supported')
|
||||
|
||||
async def __aenter__(self) -> Self:
|
||||
await self._async_setup_hook()
|
||||
return self
|
||||
|
|
@ -1753,6 +1757,38 @@ class Client:
|
|||
timeout: Optional[float] = ...,
|
||||
) -> Tuple[ScheduledEvent, User]: ...
|
||||
|
||||
@overload
|
||||
async def wait_for(
|
||||
self,
|
||||
event: Literal['scheduled_event_update'],
|
||||
/,
|
||||
*,
|
||||
check: Optional[Callable[[ScheduledEvent, ScheduledEvent], bool]] = ...,
|
||||
timeout: Optional[float] = ...,
|
||||
) -> Tuple[ScheduledEvent, ScheduledEvent]: ...
|
||||
|
||||
# Soundboard
|
||||
|
||||
@overload
|
||||
async def wait_for(
|
||||
self,
|
||||
event: Literal['soundboard_sound_create', 'soundboard_sound_delete'],
|
||||
/,
|
||||
*,
|
||||
check: Optional[Callable[[SoundboardSound], bool]] = ...,
|
||||
timeout: Optional[float] = ...,
|
||||
) -> SoundboardSound: ...
|
||||
|
||||
@overload
|
||||
async def wait_for(
|
||||
self,
|
||||
event: Literal['soundboard_sound_update'],
|
||||
/,
|
||||
*,
|
||||
check: Optional[Callable[[SoundboardSound, SoundboardSound], bool]] = ...,
|
||||
timeout: Optional[float] = ...,
|
||||
) -> Tuple[SoundboardSound, SoundboardSound]: ...
|
||||
|
||||
# Stages
|
||||
|
||||
@overload
|
||||
|
|
@ -1859,6 +1895,16 @@ class Client:
|
|||
timeout: Optional[float] = ...,
|
||||
) -> Tuple[Member, VoiceState, VoiceState]: ...
|
||||
|
||||
@overload
|
||||
async def wait_for(
|
||||
self,
|
||||
event: Literal['voice_channel_effect'],
|
||||
/,
|
||||
*,
|
||||
check: Optional[Callable[[VoiceChannelEffect], bool]] = ...,
|
||||
timeout: Optional[float] = ...,
|
||||
) -> VoiceChannelEffect: ...
|
||||
|
||||
# Polls
|
||||
|
||||
@overload
|
||||
|
|
@ -2511,7 +2557,7 @@ class Client:
|
|||
)
|
||||
return Invite.from_incomplete(state=self._connection, data=data)
|
||||
|
||||
async def delete_invite(self, invite: Union[Invite, str], /) -> Invite:
|
||||
async def delete_invite(self, invite: Union[Invite, str], /, *, reason: Optional[str] = None) -> Invite:
|
||||
"""|coro|
|
||||
|
||||
Revokes an :class:`.Invite`, URL, or ID to an invite.
|
||||
|
|
@ -2527,6 +2573,8 @@ class Client:
|
|||
----------
|
||||
invite: Union[:class:`.Invite`, :class:`str`]
|
||||
The invite to revoke.
|
||||
reason: Optional[:class:`str`]
|
||||
The reason for deleting the invite. Shows up on the audit log.
|
||||
|
||||
Raises
|
||||
-------
|
||||
|
|
@ -2539,7 +2587,7 @@ class Client:
|
|||
"""
|
||||
|
||||
resolved = utils.resolve_invite(invite)
|
||||
data = await self.http.delete_invite(resolved.code)
|
||||
data = await self.http.delete_invite(resolved.code, reason=reason)
|
||||
return Invite.from_incomplete(state=self._connection, data=data)
|
||||
|
||||
# Miscellaneous stuff
|
||||
|
|
|
|||
109
venv/lib/python3.12/site-packages/discord/collectible.py
Normal file
109
venv/lib/python3.12/site-packages/discord/collectible.py
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
"""
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-present Rapptz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Optional, TYPE_CHECKING
|
||||
|
||||
|
||||
from .asset import Asset
|
||||
from .enums import NameplatePalette, CollectibleType, try_enum
|
||||
from .utils import parse_time
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from datetime import datetime
|
||||
|
||||
from .state import ConnectionState
|
||||
from .types.user import (
|
||||
Collectible as CollectiblePayload,
|
||||
)
|
||||
|
||||
|
||||
__all__ = ('Collectible',)
|
||||
|
||||
|
||||
class Collectible:
|
||||
"""Represents a user's collectible.
|
||||
|
||||
.. versionadded:: 2.7
|
||||
|
||||
Attributes
|
||||
----------
|
||||
label: :class:`str`
|
||||
The label of the collectible.
|
||||
palette: Optional[:class:`NameplatePalette`]
|
||||
The palette of the collectible.
|
||||
This is only available if ``type`` is
|
||||
:class:`CollectibleType.nameplate`.
|
||||
sku_id: :class:`int`
|
||||
The SKU ID of the collectible.
|
||||
type: :class:`CollectibleType`
|
||||
The type of the collectible.
|
||||
expires_at: Optional[:class:`datetime.datetime`]
|
||||
The expiration date of the collectible. If applicable.
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
'type',
|
||||
'sku_id',
|
||||
'label',
|
||||
'expires_at',
|
||||
'palette',
|
||||
'_state',
|
||||
'_asset',
|
||||
)
|
||||
|
||||
def __init__(self, *, state: ConnectionState, type: str, data: CollectiblePayload) -> None:
|
||||
self._state: ConnectionState = state
|
||||
self.type: CollectibleType = try_enum(CollectibleType, type)
|
||||
self._asset: str = data['asset']
|
||||
self.sku_id: int = int(data['sku_id'])
|
||||
self.label: str = data['label']
|
||||
self.expires_at: Optional[datetime] = parse_time(data.get('expires_at'))
|
||||
|
||||
# nameplate
|
||||
self.palette: Optional[NameplatePalette]
|
||||
try:
|
||||
self.palette = try_enum(NameplatePalette, data['palette']) # type: ignore
|
||||
except KeyError:
|
||||
self.palette = None
|
||||
|
||||
@property
|
||||
def static(self) -> Asset:
|
||||
""":class:`Asset`: The static asset of the collectible."""
|
||||
return Asset._from_user_collectible(self._state, self._asset)
|
||||
|
||||
@property
|
||||
def animated(self) -> Asset:
|
||||
""":class:`Asset`: The animated asset of the collectible."""
|
||||
return Asset._from_user_collectible(self._state, self._asset, animated=True)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
attrs = ['sku_id']
|
||||
if self.palette:
|
||||
attrs.append('palette')
|
||||
|
||||
joined_attrs = ' '.join(f'{attr}={getattr(self, attr)!r}' for attr in attrs)
|
||||
return f'<{self.type.name.title()} {joined_attrs}>'
|
||||
|
|
@ -72,6 +72,12 @@ if TYPE_CHECKING:
|
|||
ContainerComponent as ContainerComponentPayload,
|
||||
UnfurledMediaItem as UnfurledMediaItemPayload,
|
||||
LabelComponent as LabelComponentPayload,
|
||||
FileUploadComponent as FileUploadComponentPayload,
|
||||
RadioGroupComponent as RadioGroupComponentPayload,
|
||||
RadioGroupOption as RadioGroupOptionPayload,
|
||||
CheckboxGroupComponent as CheckboxGroupComponentPayload,
|
||||
CheckboxGroupOption as CheckboxGroupOptionPayload,
|
||||
CheckboxComponent as CheckboxComponentPayload,
|
||||
)
|
||||
|
||||
from .emoji import Emoji
|
||||
|
|
@ -91,6 +97,7 @@ if TYPE_CHECKING:
|
|||
'SectionComponent',
|
||||
'Component',
|
||||
]
|
||||
OptionPayload = Union[SelectOptionPayload, RadioGroupOptionPayload, CheckboxGroupOptionPayload]
|
||||
|
||||
|
||||
__all__ = (
|
||||
|
|
@ -112,6 +119,12 @@ __all__ = (
|
|||
'TextDisplay',
|
||||
'SeparatorComponent',
|
||||
'LabelComponent',
|
||||
'FileUploadComponent',
|
||||
'RadioGroupComponent',
|
||||
'CheckboxGroupComponent',
|
||||
'CheckboxComponent',
|
||||
'RadioGroupOption',
|
||||
'CheckboxGroupOption',
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -132,6 +145,7 @@ class Component:
|
|||
- :class:`SeparatorComponent`
|
||||
- :class:`Container`
|
||||
- :class:`LabelComponent`
|
||||
- :class:`FileUploadComponent`
|
||||
|
||||
This class is abstract and cannot be instantiated.
|
||||
|
||||
|
|
@ -167,6 +181,71 @@ class Component:
|
|||
raise NotImplementedError
|
||||
|
||||
|
||||
class BaseOption:
|
||||
"""Represents a base option for components that have options.
|
||||
|
||||
This currently implements:
|
||||
|
||||
- :class:`SelectOption`
|
||||
- :class:`RadioGroupOption`
|
||||
- :class:`CheckboxGroupOption`
|
||||
|
||||
.. versionadded:: 2.7
|
||||
"""
|
||||
|
||||
__slots__: Tuple[str, ...] = ('label', 'value', 'description', 'default')
|
||||
|
||||
__repr_info__: ClassVar[Tuple[str, ...]] = ('label', 'value', 'description', 'default')
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
label: str,
|
||||
value: str = MISSING,
|
||||
description: Optional[str] = None,
|
||||
default: bool = False,
|
||||
) -> None:
|
||||
self.label: str = label
|
||||
self.value: str = label if value is MISSING else value
|
||||
self.description: Optional[str] = description
|
||||
self.default: bool = default
|
||||
|
||||
def __repr__(self) -> str:
|
||||
attrs = ' '.join(f'{key}={getattr(self, key)!r}' for key in self.__repr_info__)
|
||||
return f'<{self.__class__.__name__} {attrs}>'
|
||||
|
||||
def __str__(self) -> str:
|
||||
base = self.label
|
||||
|
||||
if self.description:
|
||||
return f'{base}\n{self.description}'
|
||||
return base
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, data: OptionPayload) -> Self:
|
||||
return cls(
|
||||
label=data['label'],
|
||||
value=data['value'],
|
||||
description=data.get('description'),
|
||||
default=data.get('default', False),
|
||||
)
|
||||
|
||||
def to_dict(self) -> OptionPayload:
|
||||
payload: OptionPayload = {
|
||||
'label': self.label,
|
||||
'value': self.value,
|
||||
'default': self.default,
|
||||
}
|
||||
|
||||
if self.description:
|
||||
payload['description'] = self.description
|
||||
|
||||
return payload
|
||||
|
||||
def copy(self) -> Self:
|
||||
return self.__class__.from_dict(self.to_dict())
|
||||
|
||||
|
||||
class ActionRow(Component):
|
||||
"""Represents a Discord Bot UI Kit Action Row.
|
||||
|
||||
|
|
@ -413,7 +492,7 @@ class SelectMenu(Component):
|
|||
return payload
|
||||
|
||||
|
||||
class SelectOption:
|
||||
class SelectOption(BaseOption):
|
||||
"""Represents a select menu's option.
|
||||
|
||||
These can be created by users.
|
||||
|
|
@ -451,13 +530,8 @@ class SelectOption:
|
|||
Whether this option is selected by default.
|
||||
"""
|
||||
|
||||
__slots__: Tuple[str, ...] = (
|
||||
'label',
|
||||
'value',
|
||||
'description',
|
||||
'_emoji',
|
||||
'default',
|
||||
)
|
||||
__slots__: Tuple[str, ...] = BaseOption.__slots__ + ('_emoji',)
|
||||
__repr_info__ = BaseOption.__repr_info__ + ('emoji',)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
|
|
@ -468,18 +542,9 @@ class SelectOption:
|
|||
emoji: Optional[Union[str, Emoji, PartialEmoji]] = None,
|
||||
default: bool = False,
|
||||
) -> None:
|
||||
self.label: str = label
|
||||
self.value: str = label if value is MISSING else value
|
||||
self.description: Optional[str] = description
|
||||
super().__init__(label=label, value=value, description=description, default=default)
|
||||
|
||||
self.emoji = emoji
|
||||
self.default: bool = default
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return (
|
||||
f'<SelectOption label={self.label!r} value={self.value!r} description={self.description!r} '
|
||||
f'emoji={self.emoji!r} default={self.default!r}>'
|
||||
)
|
||||
|
||||
def __str__(self) -> str:
|
||||
if self.emoji:
|
||||
|
|
@ -509,7 +574,7 @@ class SelectOption:
|
|||
self._emoji = None
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, data: SelectOptionPayload) -> SelectOption:
|
||||
def from_dict(cls, data: SelectOptionPayload) -> Self:
|
||||
try:
|
||||
emoji = PartialEmoji.from_dict(data['emoji']) # pyright: ignore[reportTypedDictNotRequiredAccess]
|
||||
except KeyError:
|
||||
|
|
@ -519,28 +584,18 @@ class SelectOption:
|
|||
label=data['label'],
|
||||
value=data['value'],
|
||||
description=data.get('description'),
|
||||
emoji=emoji,
|
||||
default=data.get('default', False),
|
||||
emoji=emoji,
|
||||
)
|
||||
|
||||
def to_dict(self) -> SelectOptionPayload:
|
||||
payload: SelectOptionPayload = {
|
||||
'label': self.label,
|
||||
'value': self.value,
|
||||
'default': self.default,
|
||||
}
|
||||
payload: SelectOptionPayload = super().to_dict() # type: ignore
|
||||
|
||||
if self.emoji:
|
||||
payload['emoji'] = self.emoji.to_dict()
|
||||
|
||||
if self.description:
|
||||
payload['description'] = self.description
|
||||
|
||||
return payload
|
||||
|
||||
def copy(self) -> SelectOption:
|
||||
return self.__class__.from_dict(self.to_dict())
|
||||
|
||||
|
||||
class TextInput(Component):
|
||||
"""Represents a text input from the Discord Bot UI Kit.
|
||||
|
|
@ -1385,6 +1440,313 @@ class LabelComponent(Component):
|
|||
return payload
|
||||
|
||||
|
||||
class FileUploadComponent(Component):
|
||||
"""Represents a file upload component from the Discord Bot UI Kit.
|
||||
|
||||
This inherits from :class:`Component`.
|
||||
|
||||
.. note::
|
||||
|
||||
The user constructible and usable type for creating a file upload is
|
||||
:class:`discord.ui.FileUpload` not this one.
|
||||
|
||||
.. versionadded:: 2.7
|
||||
|
||||
Attributes
|
||||
------------
|
||||
custom_id: Optional[:class:`str`]
|
||||
The ID of the component that gets received during an interaction.
|
||||
min_values: :class:`int`
|
||||
The minimum number of files that must be uploaded for this component.
|
||||
Defaults to 1 and must be between 0 and 10.
|
||||
max_values: :class:`int`
|
||||
The maximum number of files that must be uploaded for this component.
|
||||
Defaults to 1 and must be between 1 and 10.
|
||||
id: Optional[:class:`int`]
|
||||
The ID of this component.
|
||||
required: :class:`bool`
|
||||
Whether the component is required.
|
||||
Defaults to ``True``.
|
||||
"""
|
||||
|
||||
__slots__: Tuple[str, ...] = (
|
||||
'custom_id',
|
||||
'min_values',
|
||||
'max_values',
|
||||
'required',
|
||||
'id',
|
||||
)
|
||||
|
||||
__repr_info__: ClassVar[Tuple[str, ...]] = __slots__
|
||||
|
||||
def __init__(self, data: FileUploadComponentPayload, /) -> None:
|
||||
self.custom_id: str = data['custom_id']
|
||||
self.min_values: int = data.get('min_values', 1)
|
||||
self.max_values: int = data.get('max_values', 1)
|
||||
self.required: bool = data.get('required', True)
|
||||
self.id: Optional[int] = data.get('id')
|
||||
|
||||
@property
|
||||
def type(self) -> Literal[ComponentType.file_upload]:
|
||||
""":class:`ComponentType`: The type of component."""
|
||||
return ComponentType.file_upload
|
||||
|
||||
def to_dict(self) -> FileUploadComponentPayload:
|
||||
payload: FileUploadComponentPayload = {
|
||||
'type': self.type.value,
|
||||
'custom_id': self.custom_id,
|
||||
'min_values': self.min_values,
|
||||
'max_values': self.max_values,
|
||||
'required': self.required,
|
||||
}
|
||||
if self.id is not None:
|
||||
payload['id'] = self.id
|
||||
|
||||
return payload
|
||||
|
||||
|
||||
class RadioGroupComponent(Component):
|
||||
"""Represents a radio group component from the Discord Bot UI Kit.
|
||||
|
||||
This inherits from :class:`Component`.
|
||||
|
||||
.. note::
|
||||
|
||||
The user constructible and usable type for creating a radio group is
|
||||
:class:`discord.ui.RadioGroup` not this one.
|
||||
|
||||
.. versionadded:: 2.7
|
||||
|
||||
Attributes
|
||||
------------
|
||||
custom_id: Optional[:class:`str`]
|
||||
The ID of the component that gets received during an interaction.
|
||||
id: Optional[:class:`int`]
|
||||
The ID of this component.
|
||||
required: :class:`bool`
|
||||
Whether the component is required.
|
||||
Defaults to ``True``.
|
||||
options: List[:class:`RadioGroupOption`]
|
||||
A list of options that can be selected in this group.
|
||||
"""
|
||||
|
||||
__slots__: Tuple[str, ...] = ('custom_id', 'required', 'id', 'options')
|
||||
|
||||
__repr_info__: ClassVar[Tuple[str, ...]] = __slots__
|
||||
|
||||
def __init__(self, data: RadioGroupComponentPayload, /) -> None:
|
||||
self.custom_id: str = data['custom_id']
|
||||
self.required: bool = data.get('required', True)
|
||||
self.id: Optional[int] = data.get('id')
|
||||
self.options: List[RadioGroupOption] = [RadioGroupOption.from_dict(option) for option in data.get('options', [])]
|
||||
|
||||
@property
|
||||
def type(self) -> Literal[ComponentType.radio_group]:
|
||||
""":class:`ComponentType`: The type of component."""
|
||||
return ComponentType.radio_group
|
||||
|
||||
def to_dict(self) -> RadioGroupComponentPayload:
|
||||
payload: RadioGroupComponentPayload = {
|
||||
'type': self.type.value,
|
||||
'custom_id': self.custom_id,
|
||||
'required': self.required,
|
||||
}
|
||||
if self.id is not None:
|
||||
payload['id'] = self.id
|
||||
if self.options:
|
||||
payload['options'] = [option.to_dict() for option in self.options]
|
||||
|
||||
return payload
|
||||
|
||||
|
||||
class RadioGroupOption(BaseOption):
|
||||
"""Represents a radio group's option
|
||||
|
||||
These can be created by users.
|
||||
|
||||
.. versionadded:: 2.7
|
||||
|
||||
Parameters
|
||||
-----------
|
||||
label: :class:`str`
|
||||
The label of the option. This is displayed to users.
|
||||
Can only be up to 100 characters.
|
||||
value: :class:`str`
|
||||
The value of the option. This is not displayed to users.
|
||||
If not provided when constructed then it defaults to the label.
|
||||
Can only be up to 100 characters.
|
||||
description: Optional[:class:`str`]
|
||||
An additional description of the option, if any.
|
||||
Can only be up to 100 characters.
|
||||
default: :class:`bool`
|
||||
Whether this option is selected by default.
|
||||
|
||||
Attributes
|
||||
-----------
|
||||
label: :class:`str`
|
||||
The label of the option. This is displayed to users.
|
||||
value: :class:`str`
|
||||
The value of the option. This is not displayed to users.
|
||||
If not provided when constructed then it defaults to the
|
||||
label.
|
||||
description: Optional[:class:`str`]
|
||||
An additional description of the option, if any.
|
||||
default: :class:`bool`
|
||||
Whether this option is selected by default.
|
||||
"""
|
||||
|
||||
|
||||
class CheckboxGroupComponent(Component):
|
||||
"""Represents a checkbox group component from the Discord Bot UI Kit.
|
||||
|
||||
This inherits from :class:`Component`.
|
||||
|
||||
.. note::
|
||||
|
||||
The user constructible and usable type for creating a checkbox group is
|
||||
:class:`discord.ui.CheckboxGroup` not this one.
|
||||
|
||||
.. versionadded:: 2.7
|
||||
|
||||
Attributes
|
||||
------------
|
||||
custom_id: Optional[:class:`str`]
|
||||
The ID of the component that gets received during an interaction.
|
||||
id: Optional[:class:`int`]
|
||||
The ID of this component.
|
||||
required: :class:`bool`
|
||||
Whether the component is required.
|
||||
Defaults to ``True``.
|
||||
min_values: :class:`int`
|
||||
The minimum number of options that must be selected in this component.
|
||||
Must be between 0 and 10. Defaults to 0.
|
||||
max_values: :class:`int`
|
||||
The maximum number of options that can be selected in this component.
|
||||
Must be between 1 and 10. Defaults to 1.
|
||||
options: List[:class:`CheckboxGroupOption`]
|
||||
A list of options that can be selected in this group.
|
||||
"""
|
||||
|
||||
__slots__: Tuple[str, ...] = ('custom_id', 'required', 'id', 'min_values', 'max_values', 'options')
|
||||
|
||||
__repr_info__: ClassVar[Tuple[str, ...]] = __slots__
|
||||
|
||||
def __init__(self, data: CheckboxGroupComponentPayload, /) -> None:
|
||||
self.custom_id: str = data['custom_id']
|
||||
self.required: bool = data.get('required', True)
|
||||
self.id: Optional[int] = data.get('id')
|
||||
self.min_values: int = data.get('min_values', 0)
|
||||
self.max_values: int = data.get('max_values', 1)
|
||||
self.options: List[CheckboxGroupOption] = [
|
||||
CheckboxGroupOption.from_dict(option) for option in data.get('options', [])
|
||||
]
|
||||
|
||||
@property
|
||||
def type(self) -> Literal[ComponentType.checkbox_group]:
|
||||
""":class:`ComponentType`: The type of component."""
|
||||
return ComponentType.checkbox_group
|
||||
|
||||
def to_dict(self) -> CheckboxGroupComponentPayload:
|
||||
payload: CheckboxGroupComponentPayload = {
|
||||
'type': self.type.value,
|
||||
'custom_id': self.custom_id,
|
||||
'min_values': self.min_values,
|
||||
'max_values': self.max_values,
|
||||
'required': self.required,
|
||||
}
|
||||
if self.id is not None:
|
||||
payload['id'] = self.id
|
||||
if self.options:
|
||||
payload['options'] = [option.to_dict() for option in self.options]
|
||||
|
||||
return payload
|
||||
|
||||
|
||||
class CheckboxGroupOption(BaseOption):
|
||||
"""Represents a checkbox group's option
|
||||
|
||||
These can be created by users.
|
||||
|
||||
.. versionadded:: 2.7
|
||||
|
||||
Parameters
|
||||
-----------
|
||||
label: :class:`str`
|
||||
The label of the option. This is displayed to users.
|
||||
Can only be up to 100 characters.
|
||||
value: :class:`str`
|
||||
The value of the option. This is not displayed to users.
|
||||
If not provided when constructed then it defaults to the label.
|
||||
Can only be up to 100 characters.
|
||||
description: Optional[:class:`str`]
|
||||
An additional description of the option, if any.
|
||||
Can only be up to 100 characters.
|
||||
default: :class:`bool`
|
||||
Whether this option is selected by default.
|
||||
|
||||
Attributes
|
||||
-----------
|
||||
label: :class:`str`
|
||||
The label of the option. This is displayed to users.
|
||||
value: :class:`str`
|
||||
The value of the option. This is not displayed to users.
|
||||
If not provided when constructed then it defaults to the
|
||||
label.
|
||||
description: Optional[:class:`str`]
|
||||
An additional description of the option, if any.
|
||||
default: :class:`bool`
|
||||
Whether this option is selected by default.
|
||||
"""
|
||||
|
||||
|
||||
class CheckboxComponent(Component):
|
||||
"""Represents a checkbox component from the Discord Bot UI Kit.
|
||||
|
||||
This inherits from :class:`Component`.
|
||||
|
||||
.. note::
|
||||
|
||||
The user constructible and usable type for creating a checkbox is
|
||||
:class:`discord.ui.Checkbox` not this one.
|
||||
|
||||
.. versionadded:: 2.7
|
||||
|
||||
Attributes
|
||||
------------
|
||||
custom_id: Optional[:class:`str`]
|
||||
The ID of the component that gets received during an interaction.
|
||||
id: Optional[:class:`int`]
|
||||
The ID of this component.
|
||||
default: :class:`bool`
|
||||
Whether this checkbox is selected by default.
|
||||
"""
|
||||
|
||||
__slots__: Tuple[str, ...] = ('custom_id', 'default', 'id')
|
||||
|
||||
__repr_info__: ClassVar[Tuple[str, ...]] = __slots__
|
||||
|
||||
def __init__(self, data: CheckboxComponentPayload, /) -> None:
|
||||
self.custom_id: str = data['custom_id']
|
||||
self.id: Optional[int] = data.get('id')
|
||||
self.default: bool = data.get('default', False)
|
||||
|
||||
@property
|
||||
def type(self) -> Literal[ComponentType.checkbox]:
|
||||
""":class:`ComponentType`: The type of component."""
|
||||
return ComponentType.checkbox
|
||||
|
||||
def to_dict(self) -> CheckboxComponentPayload:
|
||||
payload: CheckboxComponentPayload = {
|
||||
'type': self.type.value,
|
||||
'custom_id': self.custom_id,
|
||||
'default': self.default,
|
||||
}
|
||||
if self.id is not None:
|
||||
payload['id'] = self.id
|
||||
|
||||
return payload
|
||||
|
||||
|
||||
def _component_factory(data: ComponentPayload, state: Optional[ConnectionState] = None) -> Optional[Component]:
|
||||
if data['type'] == 1:
|
||||
return ActionRow(data)
|
||||
|
|
@ -1410,3 +1772,11 @@ def _component_factory(data: ComponentPayload, state: Optional[ConnectionState]
|
|||
return Container(data, state)
|
||||
elif data['type'] == 18:
|
||||
return LabelComponent(data, state)
|
||||
elif data['type'] == 19:
|
||||
return FileUploadComponent(data)
|
||||
elif data['type'] == 21:
|
||||
return RadioGroupComponent(data)
|
||||
elif data['type'] == 22:
|
||||
return CheckboxGroupComponent(data)
|
||||
elif data['type'] == 23:
|
||||
return CheckboxComponent(data)
|
||||
|
|
|
|||
|
|
@ -165,8 +165,8 @@ class Emoji(_EmojiTag, AssetMixin):
|
|||
@property
|
||||
def url(self) -> str:
|
||||
""":class:`str`: Returns the URL of the emoji."""
|
||||
fmt = 'gif' if self.animated else 'png'
|
||||
return f'{Asset.BASE}/emojis/{self.id}.{fmt}'
|
||||
end = 'webp?animated=true' if self.animated else 'png'
|
||||
return f'{Asset.BASE}/emojis/{self.id}.{end}'
|
||||
|
||||
@property
|
||||
def roles(self) -> List[Role]:
|
||||
|
|
|
|||
|
|
@ -85,6 +85,8 @@ __all__ = (
|
|||
'OnboardingMode',
|
||||
'SeparatorSpacing',
|
||||
'MediaItemLoadingState',
|
||||
'CollectibleType',
|
||||
'NameplatePalette',
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -275,6 +277,17 @@ class MessageType(Enum):
|
|||
guild_incident_report_false_alarm = 39
|
||||
purchase_notification = 44
|
||||
poll_result = 46
|
||||
emoji_added = 63
|
||||
|
||||
def is_deletable(self) -> bool:
|
||||
return self not in {
|
||||
MessageType.recipient_add,
|
||||
MessageType.recipient_remove,
|
||||
MessageType.call,
|
||||
MessageType.channel_name_change,
|
||||
MessageType.channel_icon_change,
|
||||
MessageType.thread_starter_message,
|
||||
}
|
||||
|
||||
|
||||
class SpeakingState(Enum):
|
||||
|
|
@ -680,6 +693,11 @@ class ComponentType(Enum):
|
|||
separator = 14
|
||||
container = 17
|
||||
label = 18
|
||||
file_upload = 19
|
||||
# checkpoint = 20
|
||||
radio_group = 21
|
||||
checkbox_group = 22
|
||||
checkbox = 23
|
||||
|
||||
def __int__(self) -> int:
|
||||
return self.value
|
||||
|
|
@ -970,6 +988,24 @@ class MediaItemLoadingState(Enum):
|
|||
not_found = 3
|
||||
|
||||
|
||||
class CollectibleType(Enum):
|
||||
nameplate = 'nameplate'
|
||||
|
||||
|
||||
class NameplatePalette(Enum):
|
||||
crimson = 'crimson'
|
||||
berry = 'berry'
|
||||
sky = 'sky'
|
||||
teal = 'teal'
|
||||
forest = 'forest'
|
||||
bubble_gum = 'bubble_gum'
|
||||
violet = 'violet'
|
||||
cobalt = 'cobalt'
|
||||
clover = 'clover'
|
||||
lemon = 'lemon'
|
||||
white = 'white'
|
||||
|
||||
|
||||
def create_unknown_value(cls: Type[E], val: Any) -> E:
|
||||
value_cls = cls._enum_value_cls_ # type: ignore # This is narrowed below
|
||||
name = f'unknown_{val}'
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ __all__ = (
|
|||
'PrivilegedIntentsRequired',
|
||||
'InteractionResponded',
|
||||
'MissingApplicationID',
|
||||
'FFmpegProcessError',
|
||||
)
|
||||
|
||||
APP_ID_NOT_FOUND = (
|
||||
|
|
@ -74,6 +75,15 @@ class ClientException(DiscordException):
|
|||
pass
|
||||
|
||||
|
||||
class FFmpegProcessError(ClientException):
|
||||
"""Exception that's raised when an FFmpeg process fails.
|
||||
|
||||
.. versionadded:: 2.7
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class GatewayNotFound(DiscordException):
|
||||
"""An exception that is raised when the gateway for Discord could not be found"""
|
||||
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue