diff --git a/discord/abc.py b/discord/abc.py index 3a40dbf4ea..546deea7fd 100644 --- a/discord/abc.py +++ b/discord/abc.py @@ -73,6 +73,7 @@ if TYPE_CHECKING: from datetime import datetime + from .app.state import ConnectionState from .asset import Asset from .channel import ( CategoryChannel, @@ -90,7 +91,6 @@ from .member import Member from .message import Message, MessageReference, PartialMessage from .poll import Poll - from .state import ConnectionState from .threads import Thread from .types.channel import Channel as ChannelPayload from .types.channel import GuildChannel as GuildChannelPayload @@ -345,7 +345,7 @@ def __str__(self) -> str: def _sorting_bucket(self) -> int: raise NotImplementedError - def _update(self, guild: Guild, data: dict[str, Any]) -> None: + async def _update(self, data: dict[str, Any]) -> None: raise NotImplementedError async def _move( @@ -595,8 +595,7 @@ def overwrites_for(self, obj: Role | User) -> PermissionOverwrite: return PermissionOverwrite() - @property - def overwrites(self) -> dict[Role | Member, PermissionOverwrite]: + async def get_overwrites(self) -> dict[Role | Member, PermissionOverwrite]: """Returns all of the channel's overwrites. This is returned as a dictionary where the key contains the target which @@ -618,7 +617,7 @@ def overwrites(self) -> dict[Role | Member, PermissionOverwrite]: if ow.is_role(): target = self.guild.get_role(ow.id) elif ow.is_member(): - target = self.guild.get_member(ow.id) + target = await self.guild.get_member(ow.id) # TODO: There is potential data loss here in the non-chunked # case, i.e. target is None because get_member returned nothing. @@ -1226,7 +1225,7 @@ async def create_invite( target_user_id=target_user.id if target_user else None, target_application_id=target_application_id, ) - invite = Invite.from_incomplete(data=data, state=self._state) + invite = await Invite.from_incomplete(data=data, state=self._state) if target_event: invite.set_scheduled_event(target_event) return invite @@ -1611,7 +1610,7 @@ async def send( ret = state.create_message(channel=channel, data=data) if view: if view.is_dispatchable(): - state.store_view(view, ret.id) + await state.store_view(view, ret.id) view.message = ret view.refresh(ret.components) diff --git a/discord/app/cache.py b/discord/app/cache.py new file mode 100644 index 0000000000..545e1198ee --- /dev/null +++ b/discord/app/cache.py @@ -0,0 +1,395 @@ +""" +The MIT License (MIT) + +Copyright (c) 2021-present Pycord Development + +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 collections import OrderedDict, defaultdict, deque +from typing import TYPE_CHECKING, Deque, Protocol, TypeVar + +from discord import utils +from discord.member import Member +from discord.message import Message + +from ..channel import DMChannel +from ..emoji import AppEmoji, GuildEmoji +from ..guild import Guild +from ..poll import Poll +from ..sticker import GuildSticker, Sticker +from ..types.channel import DMChannel as DMChannelPayload +from ..types.emoji import Emoji as EmojiPayload +from ..types.message import Message as MessagePayload +from ..types.sticker import GuildSticker as GuildStickerPayload +from ..types.user import User as UserPayload +from ..ui.modal import Modal +from ..ui.view import View +from ..user import User + +if TYPE_CHECKING: + from discord.app.state import ConnectionState + + from ..abc import MessageableChannel, PrivateChannel + +T = TypeVar("T") + + +class Cache(Protocol): + def __init__(self): + self.__state: ConnectionState | None = None + + @property + def _state(self) -> "ConnectionState": + if self.__state is None: + raise RuntimeError("Cache state has not been initialized.") + return self.__state + + @_state.setter + def _state(self, state: "ConnectionState") -> None: + self.__state = state + + # users + async def get_all_users(self) -> list[User]: ... + + async def store_user(self, payload: UserPayload) -> User: ... + + async def delete_user(self, user_id: int) -> None: ... + + async def get_user(self, user_id: int) -> User | None: ... + + # stickers + + async def get_all_stickers(self) -> list[GuildSticker]: ... + + async def get_sticker(self, sticker_id: int) -> GuildSticker: ... + + async def store_sticker(self, guild: Guild, data: GuildStickerPayload) -> GuildSticker: ... + + async def delete_sticker(self, sticker_id: int) -> None: ... + + # interactions + + async def store_view(self, view: View, message_id: int | None) -> None: ... + + async def delete_view_on(self, message_id: int) -> None: ... + + async def get_all_views(self) -> list[View]: ... + + async def store_modal(self, modal: Modal, user_id: int) -> None: ... + + async def delete_modal(self, custom_id: str) -> None: ... + + async def get_all_modals(self) -> list[Modal]: ... + + # guilds + + async def get_all_guilds(self) -> list[Guild]: ... + + async def get_guild(self, id: int) -> Guild | None: ... + + async def add_guild(self, guild: Guild) -> None: ... + + async def delete_guild(self, guild: Guild) -> None: ... + + # emojis + + async def store_guild_emoji(self, guild: Guild, data: EmojiPayload) -> GuildEmoji: ... + + async def store_app_emoji(self, application_id: int, data: EmojiPayload) -> AppEmoji: ... + + async def get_all_emojis(self) -> list[GuildEmoji | AppEmoji]: ... + + async def get_emoji(self, emoji_id: int | None) -> GuildEmoji | AppEmoji | None: ... + + async def delete_emoji(self, emoji: GuildEmoji | AppEmoji) -> None: ... + + # polls + + async def get_all_polls(self) -> list[Poll]: ... + + async def get_poll(self, message_id: int) -> Poll: ... + + async def store_poll(self, poll: Poll, message_id: int) -> None: ... + + # private channels + + async def get_private_channels(self) -> "list[PrivateChannel]": ... + + async def get_private_channel(self, channel_id: int) -> "PrivateChannel": ... + + async def get_private_channel_by_user(self, user_id: int) -> "PrivateChannel | None": ... + + async def store_private_channel(self, channel: "PrivateChannel") -> None: ... + + # messages + + async def store_message(self, message: MessagePayload, channel: "MessageableChannel") -> Message: ... + + async def upsert_message(self, message: Message) -> None: ... + + async def delete_message(self, message_id: int) -> None: ... + + async def get_message(self, message_id: int) -> Message | None: ... + + async def get_all_messages(self) -> list[Message]: ... + + # guild members + + async def store_member(self, member: Member) -> None: ... + + async def get_member(self, guild_id: int, user_id: int) -> Member | None: ... + + async def delete_member(self, guild_id: int, user_id: int) -> None: ... + + async def delete_guild_members(self, guild_id: int) -> None: ... + + async def get_guild_members(self, guild_id: int) -> list[Member]: ... + + async def get_all_members(self) -> list[Member]: ... + + async def clear(self, views: bool = True) -> None: ... + + +class MemoryCache(Cache): + def __init__(self, max_messages: int | None = None) -> None: + self.__state: ConnectionState | None = None + self.max_messages = max_messages + self._users: dict[int, User] = {} + self._guilds: dict[int, Guild] = {} + self._polls: dict[int, Poll] = {} + self._stickers: dict[int, list[GuildSticker]] = {} + self._views: dict[str, View] = {} + self._modals: dict[str, Modal] = {} + self._messages: Deque[Message] = deque(maxlen=self.max_messages) + + self._emojis: dict[int, list[GuildEmoji | AppEmoji]] = {} + + self._private_channels: OrderedDict[int, PrivateChannel] = OrderedDict() + self._private_channels_by_user: dict[int, DMChannel] = {} + + self._guild_members: dict[int, dict[int, Member]] = defaultdict(dict) + + def _flatten(self, matrix: list[list[T]]) -> list[T]: + return [item for row in matrix for item in row] + + async def clear(self, views: bool = True) -> None: + self._users: dict[int, User] = {} + self._guilds: dict[int, Guild] = {} + self._polls: dict[int, Poll] = {} + self._stickers: dict[int, list[GuildSticker]] = {} + if views: + self._views: dict[str, View] = {} + self._modals: dict[str, Modal] = {} + self._messages: Deque[Message] = deque(maxlen=self.max_messages) + + self._emojis: dict[int, list[GuildEmoji | AppEmoji]] = {} + + self._private_channels: OrderedDict[int, PrivateChannel] = OrderedDict() + self._private_channels_by_user: dict[int, DMChannel] = {} + + self._guild_members: dict[int, dict[int, Member]] = defaultdict(dict) + + # users + async def get_all_users(self) -> list[User]: + return list(self._users.values()) + + async def store_user(self, payload: UserPayload) -> User: + user_id = int(payload["id"]) + try: + return self._users[user_id] + except KeyError: + user = User(state=self._state, data=payload) + if user.discriminator != "0000": + self._users[user_id] = user + user._stored = True + return user + + async def delete_user(self, user_id: int) -> None: + self._users.pop(user_id, None) + + async def get_user(self, user_id: int) -> User | None: + return self._users.get(user_id) + + # stickers + + async def get_all_stickers(self) -> list[GuildSticker]: + return self._flatten(list(self._stickers.values())) + + async def get_sticker(self, sticker_id: int) -> GuildSticker | None: + stickers = self._flatten(list(self._stickers.values())) + for sticker in stickers: + if sticker.id == sticker_id: + return sticker + + async def store_sticker(self, guild: Guild, data: GuildStickerPayload) -> GuildSticker: + sticker = GuildSticker(state=self._state, data=data) + try: + self._stickers[guild.id].append(sticker) + except KeyError: + self._stickers[guild.id] = [sticker] + return sticker + + async def delete_sticker(self, sticker_id: int) -> None: + self._stickers.pop(sticker_id, None) + + # interactions + + async def delete_view_on(self, message_id: int) -> View | None: + for view in await self.get_all_views(): + if view.message and view.message.id == message_id: + return view + + async def store_view(self, view: View, message_id: int) -> None: + self._views[str(message_id or view.id)] = view + + async def get_all_views(self) -> list[View]: + return list(self._views.values()) + + async def store_modal(self, modal: Modal) -> None: + self._modals[modal.custom_id] = modal + + async def get_all_modals(self) -> list[Modal]: + return list(self._modals.values()) + + # guilds + + async def get_all_guilds(self) -> list[Guild]: + return list(self._guilds.values()) + + async def get_guild(self, id: int) -> Guild | None: + return self._guilds.get(id) + + async def add_guild(self, guild: Guild) -> None: + self._guilds[guild.id] = guild + + async def delete_guild(self, guild: Guild) -> None: + self._guilds.pop(guild.id, None) + + # emojis + + async def store_guild_emoji(self, guild: Guild, data: EmojiPayload) -> GuildEmoji: + emoji = GuildEmoji(guild=guild, state=self._state, data=data) + try: + self._emojis[guild.id].append(emoji) + except KeyError: + self._emojis[guild.id] = [emoji] + return emoji + + async def store_app_emoji(self, application_id: int, data: EmojiPayload) -> AppEmoji: + emoji = AppEmoji(application_id=application_id, state=self._state, data=data) + try: + self._emojis[application_id].append(emoji) + except KeyError: + self._emojis[application_id] = [emoji] + return emoji + + async def get_all_emojis(self) -> list[GuildEmoji | AppEmoji]: + return self._flatten(list(self._emojis.values())) + + async def get_emoji(self, emoji_id: int | None) -> GuildEmoji | AppEmoji | None: + emojis = self._flatten(list(self._emojis.values())) + for emoji in emojis: + if emoji.id == emoji_id: + return emoji + + async def delete_emoji(self, emoji: GuildEmoji | AppEmoji) -> None: + if isinstance(emoji, AppEmoji): + self._emojis[emoji.application_id].remove(emoji) + else: + self._emojis[emoji.guild_id].remove(emoji) + + # polls + + async def get_all_polls(self) -> list[Poll]: + return list(self._polls.values()) + + async def get_poll(self, message_id: int) -> Poll | None: + return self._polls.get(message_id) + + async def store_poll(self, poll: Poll, message_id: int) -> None: + self._polls[message_id] = poll + + # private channels + + async def get_private_channels(self) -> "list[PrivateChannel]": + return list(self._private_channels.values()) + + async def get_private_channel(self, channel_id: int) -> "PrivateChannel | None": + try: + channel = self._private_channels[channel_id] + except KeyError: + return None + else: + self._private_channels.move_to_end(channel_id) + return channel + + async def store_private_channel(self, channel: "PrivateChannel") -> None: + channel_id = channel.id + self._private_channels[channel_id] = channel + + if len(self._private_channels) > 128: + _, to_remove = self._private_channels.popitem(last=False) + if isinstance(to_remove, DMChannel) and to_remove.recipient: + self._private_channels_by_user.pop(to_remove.recipient.id, None) + + if isinstance(channel, DMChannel) and channel.recipient: + self._private_channels_by_user[channel.recipient.id] = channel + + async def get_private_channel_by_user(self, user_id: int) -> "PrivateChannel | None": + return self._private_channels_by_user.get(user_id) + + # messages + + async def upsert_message(self, message: Message) -> None: + self._messages.append(message) + + async def store_message(self, message: MessagePayload, channel: "MessageableChannel") -> Message: + msg = await Message._from_data(state=self._state, channel=channel, data=message) + self._messages.append(msg) + return msg + + async def get_message(self, message_id: int) -> Message | None: + return utils.find(lambda m: m.id == message_id, reversed(self._messages)) + + async def get_all_messages(self) -> list[Message]: + return list(self._messages) + + async def delete_modal(self, custom_id: str) -> None: + self._modals.pop(custom_id, None) + + # guild members + + async def store_member(self, member: Member) -> None: + self._guild_members[member.guild.id][member.id] = member + + async def get_member(self, guild_id: int, user_id: int) -> Member | None: + return self._guild_members[guild_id].get(user_id) + + async def delete_member(self, guild_id: int, user_id: int) -> None: + self._guild_members[guild_id].pop(user_id, None) + + async def delete_guild_members(self, guild_id: int) -> None: + self._guild_members.pop(guild_id, None) + + async def get_guild_members(self, guild_id: int) -> list[Member]: + return list(self._guild_members.get(guild_id, {}).values()) + + async def get_all_members(self) -> list[Member]: + return self._flatten([list(members.values()) for members in self._guild_members.values()]) diff --git a/discord/app/event_emitter.py b/discord/app/event_emitter.py new file mode 100644 index 0000000000..bdcfb25f43 --- /dev/null +++ b/discord/app/event_emitter.py @@ -0,0 +1,102 @@ +""" +The MIT License (MIT) + +Copyright (c) 2021-present Pycord Development + +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. +""" + +import asyncio +from abc import ABC, abstractmethod +from asyncio import Future +from collections import defaultdict +from typing import TYPE_CHECKING, Any, Callable, TypeVar + +from typing_extensions import Self + +if TYPE_CHECKING: + from .state import ConnectionState + +T = TypeVar("T", bound="Event") + + +class Event(ABC): + __event_name__: str + + @classmethod + @abstractmethod + async def __load__(cls, data: Any, state: "ConnectionState") -> Self | None: ... + + +class EventEmitter: + def __init__(self, state: "ConnectionState") -> None: + self._listeners: dict[type[Event], list[Callable]] = {} + self._events: dict[str, list[type[Event]]] + self._wait_fors: dict[type[Event], list[Future]] = defaultdict(list) + self._state = state + + def add_event(self, event: type[Event]) -> None: + try: + self._events[event.__event_name__].append(event) + except KeyError: + self._events[event.__event_name__] = [event] + + def remove_event(self, event: type[Event]) -> list[type[Event]] | None: + return self._events.pop(event.__event_name__, None) + + def add_listener(self, event: type[Event], listener: Callable) -> None: + try: + self._listeners[event].append(listener) + except KeyError: + self.add_event(event) + self._listeners[event] = [listener] + + def remove_listener(self, event: type[Event], listener: Callable) -> None: + self._listeners[event].remove(listener) + + def add_wait_for(self, event: type[T]) -> Future[T]: + fut = Future() + + self._wait_fors[event].append(fut) + + return fut + + def remove_wait_for(self, event: type[Event], fut: Future) -> None: + self._wait_fors[event].remove(fut) + + async def emit(self, event_str: str, data: Any) -> None: + events = self._events.get(event_str, []) + + for event in events: + eve = await event.__load__(data=data, state=self._state) + + if eve is None: + continue + + funcs = self._listeners.get(event, []) + + for func in funcs: + asyncio.create_task(func(eve)) + + wait_fors = self._wait_fors.get(event) + + if wait_fors is not None: + for wait_for in wait_fors: + wait_for.set_result(eve) + self._wait_fors.pop(event) diff --git a/discord/app/state.py b/discord/app/state.py new file mode 100644 index 0000000000..b57ad5e776 --- /dev/null +++ b/discord/app/state.py @@ -0,0 +1,739 @@ +""" +The MIT License (MIT) + +Copyright (c) 2015-2021 Rapptz +Copyright (c) 2021-present Pycord Development + +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 + +import asyncio +import copy +import inspect +import itertools +import logging +import os +from collections import OrderedDict, deque +from typing import ( + TYPE_CHECKING, + Any, + Callable, + Coroutine, + Deque, + Sequence, + TypeVar, + Union, + cast, +) + +from .. import utils +from ..activity import BaseActivity +from ..automod import AutoModRule +from ..channel import * +from ..channel import _channel_factory +from ..emoji import AppEmoji, GuildEmoji +from ..enums import ChannelType, InteractionType, Status, try_enum +from ..flags import ApplicationFlags, Intents, MemberCacheFlags +from ..guild import Guild +from ..interactions import Interaction +from ..invite import Invite +from ..member import Member +from ..mentions import AllowedMentions +from ..message import Message +from ..monetization import Entitlement, Subscription +from ..object import Object +from ..partial_emoji import PartialEmoji +from ..poll import Poll, PollAnswerCount +from ..raw_models import * +from ..role import Role +from ..sticker import GuildSticker +from ..threads import Thread, ThreadMember +from ..ui.modal import Modal +from ..ui.view import View +from ..user import ClientUser, User +from ..utils.private import get_as_snowflake, parse_time, sane_wait_for +from .cache import Cache +from .event_emitter import EventEmitter + +if TYPE_CHECKING: + from ..abc import PrivateChannel + from ..client import Client + from ..gateway import DiscordWebSocket + from ..guild import GuildChannel, VocalGuildChannel + from ..http import HTTPClient + from ..message import MessageableChannel + from ..types.activity import Activity as ActivityPayload + from ..types.channel import DMChannel as DMChannelPayload + from ..types.emoji import Emoji as EmojiPayload + from ..types.guild import Guild as GuildPayload + from ..types.message import Message as MessagePayload + from ..types.poll import Poll as PollPayload + from ..types.sticker import GuildSticker as GuildStickerPayload + from ..types.user import User as UserPayload + from ..voice_client import VoiceClient + + T = TypeVar("T") + CS = TypeVar("CS", bound="ConnectionState") + Channel = GuildChannel | VocalGuildChannel | PrivateChannel | PartialMessageable + + +class ChunkRequest: + def __init__( + self, + guild_id: int, + loop: asyncio.AbstractEventLoop, + resolver: Callable[[int], Any], + *, + cache: bool = True, + ) -> None: + self.guild_id: int = guild_id + self.resolver: Callable[[int], Any] = resolver + self.loop: asyncio.AbstractEventLoop = loop + self.cache: bool = cache + self.nonce: str = os.urandom(16).hex() + self.buffer: list[Member] = [] + self.waiters: list[asyncio.Future[list[Member]]] = [] + + async def add_members(self, members: list[Member]) -> None: + self.buffer.extend(members) + if self.cache: + guild = self.resolver(self.guild_id) + if inspect.isawaitable(guild): + guild = await guild + if guild is None: + return + + for member in members: + existing = await guild.get_member(member.id) + if existing is None or existing.joined_at is None: + await guild._add_member(member) + + async def wait(self) -> list[Member]: + future = self.loop.create_future() + self.waiters.append(future) + try: + return await future + finally: + self.waiters.remove(future) + + def get_future(self) -> asyncio.Future[list[Member]]: + future = self.loop.create_future() + self.waiters.append(future) + return future + + def done(self) -> None: + for future in self.waiters: + if not future.done(): + future.set_result(self.buffer) + + +_log = logging.getLogger(__name__) + + +async def logging_coroutine(coroutine: Coroutine[Any, Any, T], *, info: str) -> None: + try: + await coroutine + except Exception: + _log.exception("Exception occurred during %s", info) + + +class ConnectionState: + if TYPE_CHECKING: + _get_websocket: Callable[..., DiscordWebSocket] + _get_client: Callable[..., Client] + _parsers: dict[str, Callable[[dict[str, Any]], None]] + + def __init__( + self, + *, + cache: Cache, + handlers: dict[str, Callable], + hooks: dict[str, Callable], + http: HTTPClient, + loop: asyncio.AbstractEventLoop, + **options: Any, + ) -> None: + self.loop: asyncio.AbstractEventLoop = loop + self.http: HTTPClient = http + self.max_messages: int | None = options.get("max_messages", 1000) + if self.max_messages is not None and self.max_messages <= 0: + self.max_messages = 1000 + + self.handlers: dict[str, Callable] = handlers + self.hooks: dict[str, Callable] = hooks + self.shard_count: int | None = None + self._ready_task: asyncio.Task | None = None + self.application_id: int | None = get_as_snowflake(options, "application_id") + self.application_flags: ApplicationFlags | None = None + self.heartbeat_timeout: float = options.get("heartbeat_timeout", 60.0) + self.guild_ready_timeout: float = options.get("guild_ready_timeout", 2.0) + if self.guild_ready_timeout < 0: + raise ValueError("guild_ready_timeout cannot be negative") + + allowed_mentions = options.get("allowed_mentions") + + if allowed_mentions is not None and not isinstance(allowed_mentions, AllowedMentions): + raise TypeError("allowed_mentions parameter must be AllowedMentions") + + self.allowed_mentions: AllowedMentions | None = allowed_mentions + self._chunk_requests: dict[int | str, ChunkRequest] = {} + + activity = options.get("activity", None) + if activity: + if not isinstance(activity, BaseActivity): + raise TypeError("activity parameter must derive from BaseActivity.") + + activity = activity.to_dict() + + status = options.get("status", None) + if status: + status = "invisible" if status is Status.offline else str(status) + intents = options.get("intents", None) + if intents is None: + intents = Intents.default() + + elif not isinstance(intents, Intents): + raise TypeError(f"intents parameter must be Intent not {type(intents)!r}") + if not intents.guilds: + _log.warning("Guilds intent seems to be disabled. This may cause state related issues.") + + self._chunk_guilds: bool = options.get("chunk_guilds_at_startup", intents.members) + + # Ensure these two are set properly + if not intents.members and self._chunk_guilds: + raise ValueError("Intents.members must be enabled to chunk guilds at startup.") + + cache_flags = options.get("member_cache_flags", None) + if cache_flags is None: + cache_flags = MemberCacheFlags.from_intents(intents) + elif not isinstance(cache_flags, MemberCacheFlags): + raise TypeError(f"member_cache_flags parameter must be MemberCacheFlags not {type(cache_flags)!r}") + + else: + cache_flags._verify_intents(intents) + + self.member_cache_flags: MemberCacheFlags = cache_flags + self._activity: ActivityPayload | None = activity + self._status: str | None = status + self._intents: Intents = intents + self._voice_clients: dict[int, VoiceClient] = {} + + if not intents.members or cache_flags._empty: + self.store_user = self.create_user # type: ignore + self.deref_user = self.deref_user_no_intents # type: ignore + + self.cache_app_emojis: bool = options.get("cache_app_emojis", False) + + self.emitter = EventEmitter(self) + + self.cache: Cache = cache + self.cache._state = self + + async def clear(self, *, views: bool = True) -> None: + self.user: ClientUser | None = None + await self.cache.clear() + self._voice_clients = {} + + async def process_chunk_requests( + self, guild_id: int, nonce: str | None, members: list[Member], complete: bool + ) -> None: + removed = [] + for key, request in self._chunk_requests.items(): + if request.guild_id == guild_id and request.nonce == nonce: + await request.add_members(members) + if complete: + request.done() + removed.append(key) + + for key in removed: + del self._chunk_requests[key] + + def call_handlers(self, key: str, *args: Any, **kwargs: Any) -> None: + try: + func = self.handlers[key] + except KeyError: + pass + else: + func(*args, **kwargs) + + async def call_hooks(self, key: str, *args: Any, **kwargs: Any) -> None: + try: + coro = self.hooks[key] + except KeyError: + pass + else: + await coro(*args, **kwargs) + + @property + def self_id(self) -> int | None: + u = self.user + return u.id if u else None + + @property + def intents(self) -> Intents: + ret = Intents.none() + ret.value = self._intents.value + return ret + + @property + def voice_clients(self) -> list[VoiceClient]: + return list(self._voice_clients.values()) + + def _get_voice_client(self, guild_id: int | None) -> VoiceClient | None: + # the keys of self._voice_clients are ints + return self._voice_clients.get(guild_id) # type: ignore + + def _add_voice_client(self, guild_id: int, voice: VoiceClient) -> None: + self._voice_clients[guild_id] = voice + + def _remove_voice_client(self, guild_id: int) -> None: + self._voice_clients.pop(guild_id, None) + + def _update_references(self, ws: DiscordWebSocket) -> None: + for vc in self.voice_clients: + vc.main_ws = ws # type: ignore + + async def store_user(self, data: UserPayload) -> User: + return await self.cache.store_user(data) + + async def deref_user(self, user_id: int) -> None: + return await self.cache.delete_user(user_id) + + def create_user(self, data: UserPayload) -> User: + return User(state=self, data=data) + + def deref_user_no_intents(self, user_id: int) -> None: + return + + async def get_user(self, id: int | None) -> User | None: + return await self.cache.get_user(cast(int, id)) + + async def store_emoji(self, guild: Guild, data: EmojiPayload) -> GuildEmoji: + return await self.cache.store_guild_emoji(guild, data) + + async def maybe_store_app_emoji(self, application_id: int, data: EmojiPayload) -> AppEmoji: + # the id will be present here + emoji = AppEmoji(application_id=application_id, state=self, data=data) + if self.cache_app_emojis: + await self.cache.store_app_emoji(application_id, data) + return emoji + + async def store_sticker(self, guild: Guild, data: GuildStickerPayload) -> GuildSticker: + return await self.cache.store_sticker(guild, data) + + async def store_view(self, view: View, message_id: int | None = None) -> None: + await self.cache.store_view(view, message_id) + + async def store_modal(self, modal: Modal, user_id: int) -> None: + await self.cache.store_modal(modal, user_id) + + async def prevent_view_updates_for(self, message_id: int) -> View | None: + return await self.cache.delete_view_on(message_id) + + async def get_persistent_views(self) -> Sequence[View]: + views = await self.cache.get_all_views() + persistent_views = {view.id: view for view in views if view.is_persistent()} + return list(persistent_views.values()) + + async def get_guilds(self) -> list[Guild]: + return await self.cache.get_all_guilds() + + async def _get_guild(self, guild_id: int | None) -> Guild | None: + return await self.cache.get_guild(cast(int, guild_id)) + + async def _add_guild(self, guild: Guild) -> None: + await self.cache.add_guild(guild) + + async def _remove_guild(self, guild: Guild) -> None: + await self.cache.delete_guild(guild) + + for emoji in guild.emojis: + await self.cache.delete_emoji(emoji) + + for sticker in guild.stickers: + await self.cache.delete_sticker(sticker.id) + + del guild + + async def get_emojis(self) -> list[GuildEmoji | AppEmoji]: + return await self.cache.get_all_emojis() + + async def get_stickers(self) -> list[GuildSticker]: + return await self.cache.get_all_stickers() + + async def get_emoji(self, emoji_id: int | None) -> GuildEmoji | AppEmoji | None: + return await self.get_emoji(emoji_id) + + async def _remove_emoji(self, emoji: GuildEmoji | AppEmoji) -> None: + await self.cache.delete_emoji(emoji) + + async def get_sticker(self, sticker_id: int | None) -> GuildSticker | None: + return await self.cache.get_sticker(cast(int, sticker_id)) + + async def get_polls(self) -> list[Poll]: + return await self.cache.get_all_polls() + + async def store_poll(self, poll: Poll, message_id: int): + await self.cache.store_poll(poll, message_id) + + async def get_poll(self, message_id: int): + return await self.cache.get_poll(message_id) + + async def get_private_channels(self) -> list[PrivateChannel]: + return await self.cache.get_private_channels() + + async def _get_private_channel(self, channel_id: int | None) -> PrivateChannel | None: + return await self.cache.get_private_channel(cast(int, channel_id)) + + async def _get_private_channel_by_user(self, user_id: int | None) -> DMChannel | None: + return cast(DMChannel | None, await self.cache.get_private_channel_by_user(cast(int, user_id))) + + async def _add_private_channel(self, channel: PrivateChannel) -> None: + await self.cache.store_private_channel(channel) + + async def add_dm_channel(self, data: DMChannelPayload) -> DMChannel: + # self.user is *always* cached when this is called + channel = DMChannel(me=self.user, state=self, data=data) # type: ignore + await channel._load() + await self._add_private_channel(channel) + return channel + + async def _get_message(self, msg_id: int | None) -> Message | None: + return await self.cache.get_message(cast(int, msg_id)) + + def _guild_needs_chunking(self, guild: Guild) -> bool: + # If presences are enabled then we get back the old guild.large behaviour + return self._chunk_guilds and not guild.chunked and not (self._intents.presences and not guild.large) + + async def _get_guild_channel( + self, data: MessagePayload, guild_id: int | None = None + ) -> tuple[Channel | Thread, Guild | None]: + channel_id = int(data["channel_id"]) + try: + # guild_id is in data + guild = await self._get_guild(int(guild_id or data["guild_id"])) # type: ignore + except KeyError: + channel = DMChannel._from_message(self, channel_id) + guild = None + else: + channel = guild and guild._resolve_channel(channel_id) + + return channel or PartialMessageable(state=self, id=channel_id), guild + + async def chunker( + self, + guild_id: int, + query: str = "", + limit: int = 0, + presences: bool = False, + *, + nonce: str | None = None, + ) -> None: + ws = self._get_websocket(guild_id) # This is ignored upstream + await ws.request_chunks(guild_id, query=query, limit=limit, presences=presences, nonce=nonce) + + async def query_members( + self, + guild: Guild, + query: str | None, + limit: int, + user_ids: list[int] | None, + cache: bool, + presences: bool, + ): + guild_id = guild.id + ws = self._get_websocket(guild_id) + if ws is None: + raise RuntimeError("Somehow do not have a websocket for this guild_id") + + request = ChunkRequest(guild.id, self.loop, self._get_guild, cache=cache) + self._chunk_requests[request.nonce] = request + + try: + # start the query operation + await ws.request_chunks( + guild_id, + query=query, + limit=limit, + user_ids=user_ids, + presences=presences, + nonce=request.nonce, + ) + return await asyncio.wait_for(request.wait(), timeout=30.0) + except asyncio.TimeoutError: + _log.warning( + ("Timed out waiting for chunks with query %r and limit %d for guild_id %d"), + query, + limit, + guild_id, + ) + raise + + def _get_create_guild(self, data): + if data.get("unavailable") is False: + # GUILD_CREATE with unavailable in the response + # usually means that the guild has become available + # and is therefore in the cache + guild = self._get_guild(int(data["id"])) + if guild is not None: + guild.unavailable = False + guild._from_data(data) + return guild + + return self._add_guild_from_data(data) + + def is_guild_evicted(self, guild) -> bool: + return guild.id not in self._guilds + + async def chunk_guild(self, guild, *, wait=True, cache=None): + # Note: This method makes an API call without timeout, and should be used in + # conjunction with `asyncio.wait_for(..., timeout=...)`. + cache = cache or self.member_cache_flags.joined + request = self._chunk_requests.get(guild.id) # nosec B113 + if request is None: + self._chunk_requests[guild.id] = request = ChunkRequest(guild.id, self.loop, self._get_guild, cache=cache) + await self.chunker(guild.id, nonce=request.nonce) + + if wait: + return await request.wait() + return request.get_future() + + async def _chunk_and_dispatch(self, guild, unavailable): + try: + await asyncio.wait_for(self.chunk_guild(guild), timeout=60.0) + except asyncio.TimeoutError: + _log.info("Somehow timed out waiting for chunks.") + + if unavailable is False: + self.dispatch("guild_available", guild) + else: + self.dispatch("guild_join", guild) + + def parse_guild_members_chunk(self, data) -> None: + guild_id = int(data["guild_id"]) + guild = self._get_guild(guild_id) + presences = data.get("presences", []) + + # the guild won't be None here + members = [Member(guild=guild, data=member, state=self) for member in data.get("members", [])] # type: ignore + _log.debug("Processed a chunk for %s members in guild ID %s.", len(members), guild_id) + + if presences: + member_dict = {str(member.id): member for member in members} + for presence in presences: + user = presence["user"] + member_id = user["id"] + member = member_dict.get(member_id) + if member is not None: + member._presence_update(presence, user) + + complete = data.get("chunk_index", 0) + 1 == data.get("chunk_count") + self.process_chunk_requests(guild_id, data.get("nonce"), members, complete) + + async def _get_reaction_user(self, channel: MessageableChannel, user_id: int) -> User | Member | None: + if isinstance(channel, TextChannel): + return await channel.guild.get_member(user_id) + return await self.get_user(user_id) + + async def get_reaction_emoji(self, data) -> GuildEmoji | AppEmoji | PartialEmoji: + emoji_id = get_as_snowflake(data, "id") + + if not emoji_id: + return data["name"] + + try: + return await self.cache.get_emoji(emoji_id) + except KeyError: + return PartialEmoji.with_state( + self, + animated=data.get("animated", False), + id=emoji_id, + name=data["name"], + ) + + async def _upgrade_partial_emoji(self, emoji: PartialEmoji) -> GuildEmoji | AppEmoji | PartialEmoji | str: + emoji_id = emoji.id + if not emoji_id: + return emoji.name + return await self.cache.get_emoji(emoji_id) or emoji + + async def get_channel(self, id: int | None) -> Channel | Thread | None: + if id is None: + return None + + pm = await self._get_private_channel(id) + if pm is not None: + return pm + + for guild in await self.cache.get_all_guilds(): + channel = guild._resolve_channel(id) + if channel is not None: + return channel + + def create_message( + self, + *, + channel: MessageableChannel, + data: MessagePayload, + ) -> Message: + return Message(state=self, channel=channel, data=data) + + +class AutoShardedConnectionState(ConnectionState): + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.shard_ids: list[int] | range = [] + self.shards_launched: asyncio.Event = asyncio.Event() + + def _update_message_references(self) -> None: + # self._messages won't be None when this is called + for msg in self._messages: # type: ignore + if not msg.guild: + continue + + new_guild = self._get_guild(msg.guild.id) + if new_guild is not None and new_guild is not msg.guild: + channel_id = msg.channel.id + channel = new_guild._resolve_channel(channel_id) or Object(id=channel_id) + # channel will either be a TextChannel, Thread or Object + msg._rebind_cached_references(new_guild, channel) # type: ignore + + async def chunker( + self, + guild_id: int, + query: str = "", + limit: int = 0, + presences: bool = False, + *, + shard_id: int | None = None, + nonce: str | None = None, + ) -> None: + ws = self._get_websocket(guild_id, shard_id=shard_id) + await ws.request_chunks(guild_id, query=query, limit=limit, presences=presences, nonce=nonce) + + async def _delay_ready(self) -> None: + await self.shards_launched.wait() + processed = [] + max_concurrency = len(self.shard_ids) * 2 + current_bucket = [] + while True: + # this snippet of code is basically waiting N seconds + # until the last GUILD_CREATE was sent + try: + guild = await asyncio.wait_for(self._ready_state.get(), timeout=self.guild_ready_timeout) + except asyncio.TimeoutError: + break + else: + if self._guild_needs_chunking(guild): + _log.debug( + ("Guild ID %d requires chunking, will be done in the background."), + guild.id, + ) + if len(current_bucket) >= max_concurrency: + try: + await sane_wait_for(current_bucket, timeout=max_concurrency * 70.0) + except asyncio.TimeoutError: + fmt = "Shard ID %s failed to wait for chunks from a sub-bucket with length %d" + _log.warning(fmt, guild.shard_id, len(current_bucket)) + finally: + current_bucket = [] + + # Chunk the guild in the background while we wait for GUILD_CREATE streaming + future = asyncio.ensure_future(self.chunk_guild(guild)) + current_bucket.append(future) + else: + future = self.loop.create_future() + future.set_result([]) + + processed.append((guild, future)) + + guilds = sorted(processed, key=lambda g: g[0].shard_id) + for shard_id, info in itertools.groupby(guilds, key=lambda g: g[0].shard_id): + children, futures = zip(*info, strict=True) + # 110 reqs/minute w/ 1 req/guild plus some buffer + timeout = 61 * (len(children) / 110) + try: + await sane_wait_for(futures, timeout=timeout) + except asyncio.TimeoutError: + _log.warning( + ("Shard ID %s failed to wait for chunks (timeout=%.2f) for %d guilds"), + shard_id, + timeout, + len(guilds), + ) + for guild in children: + if guild.unavailable is False: + self.dispatch("guild_available", guild) + else: + self.dispatch("guild_join", guild) + + self.dispatch("shard_ready", shard_id) + + if self.cache_app_emojis and self.application_id: + data = await self.http.get_all_application_emojis(self.application_id) + for e in data.get("items", []): + await self.maybe_store_app_emoji(self.application_id, e) + + # remove the state + try: + del self._ready_state + except AttributeError: + pass # already been deleted somehow + + # clear the current task + self._ready_task = None + + # dispatch the event + self.call_handlers("ready") + self.dispatch("ready") + + def parse_ready(self, data) -> None: + if not hasattr(self, "_ready_state"): + self._ready_state = asyncio.Queue() + + self.user = user = ClientUser(state=self, data=data["user"]) + # self._users is a list of Users, we're setting a ClientUser + self._users[user.id] = user # type: ignore + + if self.application_id is None: + try: + application = data["application"] + except KeyError: + pass + else: + self.application_id = get_as_snowflake(application, "id") + self.application_flags = ApplicationFlags._from_value(application["flags"]) + + for guild_data in data["guilds"]: + self._add_guild_from_data(guild_data) + + if self._messages: + self._update_message_references() + + self.dispatch("connect") + self.dispatch("shard_connect", data["__shard_id__"]) + + if self._ready_task is None: + self._ready_task = asyncio.create_task(self._delay_ready()) + + def parse_resumed(self, data) -> None: + self.dispatch("resumed") + self.dispatch("shard_resumed", data["__shard_id__"]) diff --git a/discord/appinfo.py b/discord/appinfo.py index bccc9ad883..db950f23e1 100644 --- a/discord/appinfo.py +++ b/discord/appinfo.py @@ -33,8 +33,8 @@ from .utils.private import get_as_snowflake, warn_deprecated if TYPE_CHECKING: + from .app.state import ConnectionState from .guild import Guild - from .state import ConnectionState from .types.appinfo import AppInfo as AppInfoPayload from .types.appinfo import AppInstallParams as AppInstallParamsPayload from .types.appinfo import PartialAppInfo as PartialAppInfoPayload @@ -243,14 +243,13 @@ def cover_image(self) -> Asset | None: return None return Asset._from_cover_image(self._state, self.id, self._cover_image) - @property - def guild(self) -> Guild | None: + async def get_guild(self) -> Guild | None: """If this application is a game sold on Discord, this field will be the guild to which it has been linked. .. versionadded:: 1.3 """ - return self._state._get_guild(self.guild_id) + return await self._state._get_guild(self.guild_id) @property def summary(self) -> str | None: diff --git a/discord/audit_logs.py b/discord/audit_logs.py index 097685565f..e5d0b7a268 100644 --- a/discord/audit_logs.py +++ b/discord/audit_logs.py @@ -27,6 +27,7 @@ import datetime from functools import cached_property +from inspect import isawaitable from typing import TYPE_CHECKING, Any, Callable, ClassVar, Generator, TypeVar from . import enums, utils @@ -48,13 +49,13 @@ if TYPE_CHECKING: from . import abc + from .app.state import ConnectionState from .emoji import GuildEmoji from .guild import Guild from .member import Member from .role import Role from .scheduled_events import ScheduledEvent from .stage_instance import StageInstance - from .state import ConnectionState from .sticker import GuildSticker from .threads import Thread from .types.audit_log import AuditLogChange as AuditLogChangePayload @@ -103,10 +104,10 @@ def _transform_member_id(entry: AuditLogEntry, data: Snowflake | None) -> Member return entry._get_member(int(data)) -def _transform_guild_id(entry: AuditLogEntry, data: Snowflake | None) -> Guild | None: +async def _transform_guild_id(entry: AuditLogEntry, data: Snowflake | None) -> Guild | None: if data is None: return None - return entry._state._get_guild(data) + return await entry._state._get_guild(data) def _transform_overwrites( @@ -277,7 +278,14 @@ class AuditLogChanges: "communication_disabled_until": (None, _transform_communication_disabled_until), } - def __init__( + @staticmethod + async def _maybe_await(func: Any) -> Any: + if isawaitable(func): + return await func + else: + return func + + async def _from_data( self, entry: AuditLogEntry, data: list[AuditLogChangePayload], @@ -340,7 +348,7 @@ def __init__( before = None else: if transformer: - before = transformer(entry, before) + before = await self._maybe_await(transformer(entry, before)) if attr == "location" and hasattr(self.before, "location_type"): from .scheduled_events import ScheduledEventLocation # noqa: PLC0415 @@ -358,7 +366,7 @@ def __init__( after = None else: if transformer: - after = transformer(entry, after) + after = await self._maybe_await(transformer(entry, after)) if attr == "location" and hasattr(self.after, "location_type"): from .scheduled_events import ScheduledEventLocation # noqa: PLC0415 @@ -570,8 +578,8 @@ def _from_data(self, data: AuditLogEntryPayload) -> None: self.user = self._get_member(get_as_snowflake(data, "user_id")) # type: ignore self._target_id = get_as_snowflake(data, "target_id") - def _get_member(self, user_id: int) -> Member | User | None: - return self.guild.get_member(user_id) or self._users.get(user_id) + async def _get_member(self, user_id: int) -> Member | User | None: + return await self.guild.get_member(user_id) or self._users.get(user_id) def __repr__(self) -> str: return f"" @@ -581,8 +589,7 @@ def created_at(self) -> datetime.datetime: """Returns the entry's creation time in UTC.""" return utils.snowflake_time(self.id) - @cached_property - def target( + async def get_target( self, ) -> ( Guild @@ -603,17 +610,19 @@ def target( except AttributeError: return Object(id=self._target_id) else: - return converter(self._target_id) + r = converter(self._target_id) + if isawaitable(r): + r = await r + return r @property def category(self) -> enums.AuditLogActionCategory: """The category of the action, if applicable.""" return self.action.category - @cached_property - def changes(self) -> AuditLogChanges: + async def changes(self) -> AuditLogChanges: """The list of changes this entry has.""" - obj = AuditLogChanges(self, self._changes, state=self._state) + obj = AuditLogChanges().from_data(self, self._changes, state=self._state) del self._changes return obj @@ -633,8 +642,8 @@ def _convert_target_guild(self, target_id: int) -> Guild: def _convert_target_channel(self, target_id: int) -> abc.GuildChannel | Object: return self.guild.get_channel(target_id) or Object(id=target_id) - def _convert_target_user(self, target_id: int) -> Member | User | None: - return self._get_member(target_id) + async def _convert_target_user(self, target_id: int) -> Member | User | None: + return await self._get_member(target_id) def _convert_target_role(self, target_id: int) -> Role | Object: return self.guild.get_role(target_id) or Object(id=target_id) @@ -659,17 +668,17 @@ def _convert_target_invite(self, target_id: int) -> Invite: pass return obj - def _convert_target_emoji(self, target_id: int) -> GuildEmoji | Object: - return self._state.get_emoji(target_id) or Object(id=target_id) + async def _convert_target_emoji(self, target_id: int) -> GuildEmoji | Object: + return (await self._state.get_emoji(target_id)) or Object(id=target_id) - def _convert_target_message(self, target_id: int) -> Member | User | None: - return self._get_member(target_id) + async def _convert_target_message(self, target_id: int) -> Member | User | None: + return await self._get_member(target_id) def _convert_target_stage_instance(self, target_id: int) -> StageInstance | Object: return self.guild.get_stage_instance(target_id) or Object(id=target_id) - def _convert_target_sticker(self, target_id: int) -> GuildSticker | Object: - return self._state.get_sticker(target_id) or Object(id=target_id) + async def _convert_target_sticker(self, target_id: int) -> GuildSticker | Object: + return (await self._state.get_sticker(target_id)) or Object(id=target_id) def _convert_target_thread(self, target_id: int) -> Thread | Object: return self.guild.get_thread(target_id) or Object(id=target_id) diff --git a/discord/automod.py b/discord/automod.py index 9f990d8bbc..2bf7869351 100644 --- a/discord/automod.py +++ b/discord/automod.py @@ -48,11 +48,11 @@ if TYPE_CHECKING: from .abc import Snowflake + from .app.state import ConnectionState from .channel import ForumChannel, TextChannel, VoiceChannel from .guild import Guild from .member import Member from .role import Role - from .state import ConnectionState from .types.automod import AutoModAction as AutoModActionPayload from .types.automod import AutoModActionMetadata as AutoModActionMetadataPayload from .types.automod import AutoModRule as AutoModRulePayload @@ -406,17 +406,15 @@ def __repr__(self) -> str: def __str__(self) -> str: return self.name - @property - def guild(self) -> Guild | None: + async def get_guild(self) -> Guild | None: """The guild this rule belongs to.""" - return self._state._get_guild(self.guild_id) + return await self._state._get_guild(self.guild_id) - @property - def creator(self) -> Member | None: + async def get_creator(self) -> Member | None: """The member who created this rule.""" if self.guild is None: return None - return self.guild.get_member(self.creator_id) + return await self.guild.get_member(self.creator_id) @cached_property def exempt_roles(self) -> list[Role | Object]: diff --git a/discord/channel.py b/discord/channel.py index fb8b196265..57e894b8c4 100644 --- a/discord/channel.py +++ b/discord/channel.py @@ -25,6 +25,7 @@ from __future__ import annotations +import asyncio import datetime from typing import ( TYPE_CHECKING, @@ -86,6 +87,7 @@ if TYPE_CHECKING: from .abc import Snowflake, SnowflakeTime + from .app.state import ConnectionState from .embeds import Embed from .guild import Guild from .guild import GuildChannel as GuildChannelType @@ -93,7 +95,6 @@ from .mentions import AllowedMentions from .message import EmojiInputType, Message, PartialMessage from .role import Role - from .state import ConnectionState from .sticker import GuildSticker, StickerItem from .types.channel import CategoryChannel as CategoryChannelPayload from .types.channel import DMChannel as DMChannelPayload @@ -224,7 +225,7 @@ def __init__( ): self._state: ConnectionState = state self.id: int = int(data["id"]) - self._update(guild, data) + self.guild = guild @property def _repr_attrs(self) -> tuple[str, ...]: @@ -235,9 +236,8 @@ def __repr__(self) -> str: joined = " ".join("%s=%r" % t for t in attrs) return f"<{self.__class__.__name__} {joined}>" - def _update(self, guild: Guild, data: TextChannelPayload | ForumChannelPayload) -> None: + async def _update(self, data: TextChannelPayload | ForumChannelPayload) -> None: # This data will always exist - self.guild: Guild = guild self.name: str = data["name"] self.category_id: int | None = get_as_snowflake(data, "parent_id") self._type: int = data["type"] @@ -289,8 +289,7 @@ def is_nsfw(self) -> bool: """Checks if the channel is NSFW.""" return self.nsfw - @property - def last_message(self) -> Message | None: + async def get_last_message(self) -> Message | None: """Fetches the last message from this channel in cache. The message might not be valid or point to an existing message. @@ -308,7 +307,7 @@ def last_message(self) -> Message | None: Optional[:class:`Message`] The last message in this channel or ``None`` if not found. """ - return self._state._get_message(self.last_message_id) if self.last_message_id else None + return await self._state._get_message(self.last_message_id) if self.last_message_id else None async def edit(self, **options) -> _TextChannel: """Edits the channel.""" @@ -731,8 +730,8 @@ def __init__(self, *, state: ConnectionState, guild: Guild, data: TextChannelPay def _repr_attrs(self) -> tuple[str, ...]: return super()._repr_attrs + ("news",) - def _update(self, guild: Guild, data: TextChannelPayload) -> None: - super()._update(guild, data) + async def _update(self, data: TextChannelPayload) -> None: + super()._update(data) async def _get_channel(self) -> TextChannel: return self @@ -1006,8 +1005,8 @@ class ForumChannel(_TextChannel): def __init__(self, *, state: ConnectionState, guild: Guild, data: ForumChannelPayload): super().__init__(state=state, guild=guild, data=data) - def _update(self, guild: Guild, data: ForumChannelPayload) -> None: - super()._update(guild, data) + async def _update(self, data: ForumChannelPayload) -> None: + super()._update(data) self.available_tags: list[ForumTag] = [ ForumTag.from_data(state=self._state, data=tag) for tag in (data.get("available_tags") or []) ] @@ -1023,7 +1022,9 @@ def _update(self, guild: Guild, data: ForumChannelPayload) -> None: if emoji_name is not None: self.default_reaction_emoji = reaction_emoji_ctx["emoji_name"] else: - self.default_reaction_emoji = self._state.get_emoji(get_as_snowflake(reaction_emoji_ctx, "emoji_id")) + self.default_reaction_emoji = await self._state.get_emoji( + get_as_snowflake(reaction_emoji_ctx, "emoji_id") + ) @property def guidelines(self) -> str | None: @@ -1325,7 +1326,7 @@ async def create_thread( ret = Thread(guild=self.guild, state=self._state, data=data) msg = ret.get_partial_message(int(data["last_message_id"])) if view and view.is_dispatchable(): - state.store_view(view, msg.id) + await state.store_view(view, msg.id) if delete_message_after is not None: await msg.delete(delay=delete_message_after) @@ -1550,7 +1551,8 @@ def __init__( ): self._state: ConnectionState = state self.id: int = int(data["id"]) - self._update(guild, data) + self.guild = guild + self._update(data) def _get_voice_client_key(self) -> tuple[int, str]: return self.guild.id, "guild_id" @@ -1558,9 +1560,8 @@ def _get_voice_client_key(self) -> tuple[int, str]: def _get_voice_state_pair(self) -> tuple[int, int]: return self.guild.id, self.id - def _update(self, guild: Guild, data: VoiceChannelPayload | StageChannelPayload) -> None: + async def _update(self, data: VoiceChannelPayload | StageChannelPayload) -> None: # This data will always exist - self.guild = guild self.name: str = data["name"] self.category_id: int | None = get_as_snowflake(data, "parent_id") @@ -1582,13 +1583,12 @@ def _update(self, guild: Guild, data: VoiceChannelPayload | StageChannelPayload) def _sorting_bucket(self) -> int: return ChannelType.voice.value - @property - def members(self) -> list[Member]: + async def get_members(self) -> list[Member]: """Returns all members that are currently inside this voice channel.""" ret = [] for user_id, state in self.guild._voice_states.items(): if state.channel and state.channel.id == self.id: - member = self.guild.get_member(user_id) + member = await self.guild.get_member(user_id) if member is not None: ret.append(member) return ret @@ -1711,8 +1711,8 @@ def __init__( self.status: str | None = None super().__init__(state=state, guild=guild, data=data) - def _update(self, guild: Guild, data: VoiceChannelPayload): - super()._update(guild, data) + async def _update(self, data: VoiceChannelPayload): + super()._update(data) if data.get("status"): self.status = data.get("status") @@ -1738,8 +1738,7 @@ def is_nsfw(self) -> bool: """Checks if the channel is NSFW.""" return self.nsfw - @property - def last_message(self) -> Message | None: + async def get_last_message(self) -> Message | None: """Fetches the last message from this channel in cache. The message might not be valid or point to an existing message. @@ -1757,7 +1756,7 @@ def last_message(self) -> Message | None: Optional[:class:`Message`] The last message in this channel or ``None`` if not found. """ - return self._state._get_message(self.last_message_id) if self.last_message_id else None + return await self._state._get_message(self.last_message_id) if self.last_message_id else None def get_partial_message(self, message_id: int, /) -> PartialMessage: """Creates a :class:`PartialMessage` from the message ID. @@ -2252,8 +2251,8 @@ class StageChannel(discord.abc.Messageable, VocalGuildChannel): __slots__ = ("topic",) - def _update(self, guild: Guild, data: StageChannelPayload) -> None: - super()._update(guild, data) + async def _update(self, data: StageChannelPayload) -> None: + super()._update(data) self.topic = data.get("topic") def __repr__(self) -> str: @@ -2303,8 +2302,7 @@ def is_nsfw(self) -> bool: """Checks if the channel is NSFW.""" return self.nsfw - @property - def last_message(self) -> Message | None: + async def get_last_message(self) -> Message | None: """Fetches the last message from this channel in cache. The message might not be valid or point to an existing message. @@ -2322,7 +2320,7 @@ def last_message(self) -> Message | None: Optional[:class:`Message`] The last message in this channel or ``None`` if not found. """ - return self._state._get_message(self.last_message_id) if self.last_message_id else None + return await self._state._get_message(self.last_message_id) if self.last_message_id else None def get_partial_message(self, message_id: int, /) -> PartialMessage: """Creates a :class:`PartialMessage` from the message ID. @@ -2794,14 +2792,14 @@ class CategoryChannel(discord.abc.GuildChannel, Hashable): def __init__(self, *, state: ConnectionState, guild: Guild, data: CategoryChannelPayload): self._state: ConnectionState = state self.id: int = int(data["id"]) - self._update(guild, data) + self.guild = guild + self._update(data) def __repr__(self) -> str: return f"" - def _update(self, guild: Guild, data: CategoryChannelPayload) -> None: + async def _update(self, data: CategoryChannelPayload) -> None: # This data will always exist - self.guild: Guild = guild self.name: str = data["name"] self.category_id: int | None = get_as_snowflake(data, "parent_id") @@ -3029,11 +3027,17 @@ class DMChannel(discord.abc.Messageable, Hashable): def __init__(self, *, me: ClientUser, state: ConnectionState, data: DMChannelPayload): self._state: ConnectionState = state + self._recipients = data.get("recipients") self.recipient: User | None = None - if r := data.get("recipients"): - self.recipient = state.store_user(r[0]) self.me: ClientUser = me self.id: int = int(data["id"]) + # there shouldn't be any point in time where a DM channel + # is made without the event loop having started + asyncio.create_task(self._load()) + + async def _load(self) -> None: + if r := self._recipients: + self.recipient = await self._state.store_user(r[0]) async def _get_channel(self): return self @@ -3176,19 +3180,22 @@ class GroupChannel(discord.abc.Messageable, Hashable): "name", "me", "_state", + "_data", ) def __init__(self, *, me: ClientUser, state: ConnectionState, data: GroupChannelPayload): self._state: ConnectionState = state + self._data = data self.id: int = int(data["id"]) self.me: ClientUser = me - self._update_group(data) - def _update_group(self, data: GroupChannelPayload) -> None: - self.owner_id: int | None = get_as_snowflake(data, "owner_id") - self._icon: str | None = data.get("icon") - self.name: str | None = data.get("name") - self.recipients: list[User] = [self._state.store_user(u) for u in data.get("recipients", [])] + async def _update_group(self, data: dict[str, Any] | None = None) -> None: + if data: + self._data = data + self.owner_id: int | None = get_as_snowflake(self._data, "owner_id") + self._icon: str | None = self._data.get("icon") + self.name: str | None = self._data.get("name") + self.recipients: list[User] = [await self._state.store_user(u) for u in self._data.get("recipients", [])] self.owner: BaseUser | None if self.owner_id == self.me.id: diff --git a/discord/client.py b/discord/client.py index 225904bd50..71bd01751e 100644 --- a/discord/client.py +++ b/discord/client.py @@ -31,7 +31,7 @@ import sys import traceback from types import TracebackType -from typing import TYPE_CHECKING, Any, Callable, Coroutine, Generator, Sequence, TypeVar +from typing import TYPE_CHECKING, Any, AsyncGenerator, Callable, Coroutine, Generator, Sequence, TypeVar import aiohttp @@ -39,6 +39,8 @@ from . import utils from .activity import ActivityTypes, BaseActivity, create_activity +from .app.cache import Cache, MemoryCache +from .app.state import ConnectionState from .appinfo import AppInfo, PartialAppInfo from .application_role_connection import ApplicationRoleConnectionMetadata from .backoff import ExponentialBackoff @@ -57,7 +59,6 @@ from .object import Object from .soundboard import SoundboardSound from .stage_instance import StageInstance -from .state import ConnectionState from .sticker import GuildSticker, StandardSticker, StickerPack, _sticker_factory from .template import Template from .threads import Thread @@ -309,6 +310,7 @@ def _get_state(self, **options: Any) -> ConnectionState: hooks=self._hooks, http=self.http, loop=self.loop, + cache=MemoryCache(), **options, ) @@ -342,62 +344,54 @@ def user(self) -> ClientUser | None: """Represents the connected client. ``None`` if not logged in.""" return self._connection.user - @property - def guilds(self) -> list[Guild]: + async def get_guilds(self) -> list[Guild]: """The guilds that the connected client is a member of.""" - return self._connection.guilds + return await self._connection.get_guilds() - @property - def emojis(self) -> list[GuildEmoji | AppEmoji]: + async def get_emojis(self) -> list[GuildEmoji | AppEmoji]: """The emojis that the connected client has. .. note:: This only includes the application's emojis if `cache_app_emojis` is ``True``. """ - return self._connection.emojis + return await self._connection.get_emojis() - @property - def guild_emojis(self) -> list[GuildEmoji]: + async def get_guild_emojis(self) -> list[GuildEmoji]: """The :class:`~discord.GuildEmoji` that the connected client has.""" - return [e for e in self.emojis if isinstance(e, GuildEmoji)] + return [e for e in await self.get_emojis() if isinstance(e, GuildEmoji)] - @property - def app_emojis(self) -> list[AppEmoji]: + async def get_app_emojis(self) -> list[AppEmoji]: """The :class:`~discord.AppEmoji` that the connected client has. .. note:: This is only available if `cache_app_emojis` is ``True``. """ - return [e for e in self.emojis if isinstance(e, AppEmoji)] + return [e for e in await self.get_emojis() if isinstance(e, AppEmoji)] - @property - def stickers(self) -> list[GuildSticker]: + async def get_stickers(self) -> list[GuildSticker]: """The stickers that the connected client has. .. versionadded:: 2.0 """ - return self._connection.stickers + return await self._connection.get_stickers() - @property - def polls(self) -> list[Poll]: + async def get_polls(self) -> list[Poll]: """The polls that the connected client has. .. versionadded:: 2.6 """ - return self._connection.polls + return await self._connection.get_polls() - @property - def cached_messages(self) -> Sequence[Message]: + async def get_cached_messages(self) -> Sequence[Message]: """Read-only list of messages the connected client has cached. .. versionadded:: 1.1 """ - return SequenceProxy(self._connection._messages or []) + return SequenceProxy(await self._connection.cache.get_all_messages()) - @property - def private_channels(self) -> list[PrivateChannel]: + async def get_private_channels(self) -> list[PrivateChannel]: """The private channels that the connected client is participating on. .. note:: @@ -405,7 +399,7 @@ def private_channels(self) -> list[PrivateChannel]: This returns only up to 128 most recent private channels due to an internal working on how Discord deals with private channels. """ - return self._connection.private_channels + return await self._connection.get_private_channels() @property def voice_clients(self) -> list[VoiceProtocol]: @@ -932,10 +926,9 @@ def intents(self) -> Intents: # helpers/getters - @property - def users(self) -> list[User]: + async def get_users(self) -> list[User]: """Returns a list of all the users the bot can see.""" - return list(self._connection._users.values()) + return await self._connection.cache.get_all_users() async def fetch_application(self, application_id: int, /) -> PartialAppInfo: """|coro| @@ -961,7 +954,7 @@ async def fetch_application(self, application_id: int, /) -> PartialAppInfo: data = await self.http.get_application(application_id) return PartialAppInfo(state=self._connection, data=data) - def get_channel(self, id: int, /) -> GuildChannel | Thread | PrivateChannel | None: + async def get_channel(self, id: int, /) -> GuildChannel | Thread | PrivateChannel | None: """Returns a channel or thread with the given ID. Parameters @@ -974,9 +967,9 @@ def get_channel(self, id: int, /) -> GuildChannel | Thread | PrivateChannel | No Optional[Union[:class:`.abc.GuildChannel`, :class:`.Thread`, :class:`.abc.PrivateChannel`]] The returned channel or ``None`` if not found. """ - return self._connection.get_channel(id) + return await self._connection.get_channel(id) - def get_message(self, id: int, /) -> Message | None: + async def get_message(self, id: int, /) -> Message | None: """Returns a message the given ID. This is useful if you have a message_id but don't want to do an API call @@ -992,7 +985,7 @@ def get_message(self, id: int, /) -> Message | None: Optional[:class:`.Message`] The returned message or ``None`` if not found. """ - return self._connection._get_message(id) + return await self._connection._get_message(id) def get_partial_messageable(self, id: int, *, type: ChannelType | None = None) -> PartialMessageable: """Returns a partial messageable with the given channel ID. @@ -1016,7 +1009,7 @@ def get_partial_messageable(self, id: int, *, type: ChannelType | None = None) - """ return PartialMessageable(state=self._connection, id=id, type=type) - def get_stage_instance(self, id: int, /) -> StageInstance | None: + async def get_stage_instance(self, id: int, /) -> StageInstance | None: """Returns a stage instance with the given stage channel ID. .. versionadded:: 2.0 @@ -1031,14 +1024,14 @@ def get_stage_instance(self, id: int, /) -> StageInstance | None: Optional[:class:`.StageInstance`] The stage instance or ``None`` if not found. """ - from .channel import StageChannel # noqa: PLC0415 + from .channel import StageChannel - channel = self._connection.get_channel(id) + channel = await self._connection.get_channel(id) if isinstance(channel, StageChannel): return channel.instance - def get_guild(self, id: int, /) -> Guild | None: + async def get_guild(self, id: int, /) -> Guild | None: """Returns a guild with the given ID. Parameters @@ -1051,9 +1044,9 @@ def get_guild(self, id: int, /) -> Guild | None: Optional[:class:`.Guild`] The guild or ``None`` if not found. """ - return self._connection._get_guild(id) + return await self._connection._get_guild(id) - def get_user(self, id: int, /) -> User | None: + async def get_user(self, id: int, /) -> User | None: """Returns a user with the given ID. Parameters @@ -1066,9 +1059,9 @@ def get_user(self, id: int, /) -> User | None: Optional[:class:`~discord.User`] The user or ``None`` if not found. """ - return self._connection.get_user(id) + return await self._connection.get_user(id) - def get_emoji(self, id: int, /) -> GuildEmoji | AppEmoji | None: + async def get_emoji(self, id: int, /) -> GuildEmoji | AppEmoji | None: """Returns an emoji with the given ID. Parameters @@ -1081,9 +1074,9 @@ def get_emoji(self, id: int, /) -> GuildEmoji | AppEmoji | None: Optional[:class:`.GuildEmoji` | :class:`.AppEmoji`] The custom emoji or ``None`` if not found. """ - return self._connection.get_emoji(id) + return await self._connection.get_emoji(id) - def get_sticker(self, id: int, /) -> GuildSticker | None: + async def get_sticker(self, id: int, /) -> GuildSticker | None: """Returns a guild sticker with the given ID. .. versionadded:: 2.0 @@ -1098,9 +1091,9 @@ def get_sticker(self, id: int, /) -> GuildSticker | None: Optional[:class:`.GuildSticker`] The sticker or ``None`` if not found. """ - return self._connection.get_sticker(id) + return await self._connection.get_sticker(id) - def get_poll(self, id: int, /) -> Poll | None: + async def get_poll(self, id: int, /) -> Poll | None: """Returns a poll attached to the given message ID. Parameters @@ -1113,14 +1106,14 @@ def get_poll(self, id: int, /) -> Poll | None: Optional[:class:`.Poll`] The poll or ``None`` if not found. """ - return self._connection.get_poll(id) + return await self._connection.get_poll(id) - def get_all_channels(self) -> Generator[GuildChannel]: + async def get_all_channels(self) -> AsyncGenerator[GuildChannel]: """A generator that retrieves every :class:`.abc.GuildChannel` the client can 'access'. This is equivalent to: :: - for guild in client.guilds: + for guild in await client.get_guilds(): for channel in guild.channels: yield channel @@ -1136,15 +1129,16 @@ def get_all_channels(self) -> Generator[GuildChannel]: A channel the client can 'access'. """ - for guild in self.guilds: - yield from guild.channels + for guild in await self.get_guilds(): + for channel in guild.channels: + yield channel - def get_all_members(self) -> Generator[Member]: + async def get_all_members(self) -> AsyncGenerator[Member]: """Returns a generator with every :class:`.Member` the client can see. This is equivalent to: :: - for guild in client.guilds: + for guild in await client.get_guilds(): for member in guild.members: yield member @@ -1153,8 +1147,9 @@ def get_all_members(self) -> Generator[Member]: :class:`.Member` A member the client can see. """ - for guild in self.guilds: - yield from guild.members + for guild in await self.get_guilds(): + for member in guild.members: + yield member # listeners/waiters @@ -1480,7 +1475,7 @@ async def change_presence( await self.ws.change_presence(activity=activity, status=status_str) - for guild in self._connection.guilds: + for guild in await self._connection.get_guilds(): me = guild.me if me is None: continue @@ -1581,7 +1576,7 @@ async def fetch_template(self, code: Template | str) -> Template: """ code = resolve_template(code) data = await self.http.get_template(code) - return Template(data=data, state=self._connection) # type: ignore + return await Template.from_data(data=data, state=self._connection) # type: ignore async def fetch_guild(self, guild_id: int, /, *, with_counts=True) -> Guild: """|coro| @@ -1622,7 +1617,7 @@ async def fetch_guild(self, guild_id: int, /, *, with_counts=True) -> Guild: Getting the guild failed. """ data = await self.http.get_guild(guild_id, with_counts=with_counts) - return Guild(data=data, state=self._connection) + return await Guild._from_data(data=data, state=self._connection) async def create_guild( self, @@ -1671,7 +1666,7 @@ async def create_guild( data = await self.http.create_from_template(code, name, icon_base64) else: data = await self.http.create_guild(name, icon_base64) - return Guild(data=data, state=self._connection) + return await Guild._from_data(data=data, state=self._connection) async def fetch_stage_instance(self, channel_id: int, /) -> StageInstance: """|coro| @@ -1762,7 +1757,7 @@ async def fetch_invite( with_expiration=with_expiration, guild_scheduled_event_id=event_id, ) - return Invite.from_incomplete(state=self._connection, data=data) + return await Invite.from_incomplete(state=self._connection, data=data) async def delete_invite(self, invite: Invite | str) -> None: """|coro| @@ -2002,14 +1997,14 @@ async def create_dm(self, user: Snowflake) -> DMChannel: The channel that was created. """ state = self._connection - found = state._get_private_channel_by_user(user.id) + found = await state._get_private_channel_by_user(user.id) if found: return found data = await state.http.start_private_message(user.id) - return state.add_dm_channel(data) + return await state.add_dm_channel(data) - def add_view(self, view: View, *, message_id: int | None = None) -> None: + async def add_view(self, view: View, *, message_id: int | None = None) -> None: """Registers a :class:`~discord.ui.View` for persistent listening. This method should be used for when a view is comprised of components @@ -2041,15 +2036,14 @@ def add_view(self, view: View, *, message_id: int | None = None) -> None: if not view.is_persistent(): raise ValueError("View is not persistent. Items need to have a custom_id set and View must have no timeout") - self._connection.store_view(view, message_id) + await self._connection.store_view(view, message_id) - @property - def persistent_views(self) -> Sequence[View]: + async def get_persistent_views(self) -> Sequence[View]: """A sequence of persistent views added to the client. .. versionadded:: 2.0 """ - return self._connection.persistent_views + return await self._connection.get_persistent_views() async def fetch_role_connection_metadata_records( self, @@ -2205,7 +2199,7 @@ async def fetch_emojis(self) -> list[AppEmoji]: The retrieved emojis. """ data = await self._connection.http.get_all_application_emojis(self.application_id) - return [self._connection.maybe_store_app_emoji(self.application_id, d) for d in data["items"]] + return [await self._connection.maybe_store_app_emoji(self.application_id, d) for d in data["items"]] async def fetch_emoji(self, emoji_id: int, /) -> AppEmoji: """|coro| @@ -2230,7 +2224,7 @@ async def fetch_emoji(self, emoji_id: int, /) -> AppEmoji: An error occurred fetching the emoji. """ data = await self._connection.http.get_application_emoji(self.application_id, emoji_id) - return self._connection.maybe_store_app_emoji(self.application_id, data) + return await self._connection.maybe_store_app_emoji(self.application_id, data) async def create_emoji( self, @@ -2265,7 +2259,7 @@ async def create_emoji( img = bytes_to_base64_data(image) data = await self._connection.http.create_application_emoji(self.application_id, name, img) - return self._connection.maybe_store_app_emoji(self.application_id, data) + return await self._connection.maybe_store_app_emoji(self.application_id, data) async def delete_emoji(self, emoji: Snowflake) -> None: """|coro| @@ -2284,8 +2278,8 @@ async def delete_emoji(self, emoji: Snowflake) -> None: """ await self._connection.http.delete_application_emoji(self.application_id, emoji.id) - if self._connection.cache_app_emojis and self._connection.get_emoji(emoji.id): - self._connection.remove_emoji(emoji) + if self._connection.cache_app_emojis and await self._connection.get_emoji(emoji.id): + await self._connection._remove_emoji(emoji) def get_sound(self, sound_id: int) -> SoundboardSound | None: """Gets a :class:`.Sound` from the bot's sound cache. diff --git a/discord/commands/context.py b/discord/commands/context.py index d7d1500ab9..7d5810e2bd 100644 --- a/discord/commands/context.py +++ b/discord/commands/context.py @@ -39,6 +39,7 @@ import discord from .. import Bot + from ..app.state import ConnectionState from ..client import ClientUser from ..cog import Cog from ..guild import Guild @@ -46,7 +47,6 @@ from ..member import Member from ..message import Message from ..permissions import Permissions - from ..state import ConnectionState from ..user import User from ..voice_client import VoiceClient from ..webhook import WebhookMessage diff --git a/discord/commands/core.py b/discord/commands/core.py index 0351513601..76a90e6d9b 100644 --- a/discord/commands/core.py +++ b/discord/commands/core.py @@ -963,7 +963,7 @@ async def _invoke(self, ctx: ApplicationContext) -> None: # We resolved the user from the user id _data["user"] = _user_data cache_flag = ctx.interaction._state.member_cache_flags.interaction - arg = ctx.guild._get_and_update_member(_data, int(arg), cache_flag) + arg = await ctx.guild._get_and_update_member(_data, int(arg), cache_flag) elif op.input_type is SlashCommandOptionType.mentionable: if (_data := resolved.get("users", {}).get(arg)) is not None: arg = User(state=ctx.interaction._state, data=_data) @@ -1708,7 +1708,7 @@ async def _invoke(self, ctx: ApplicationContext) -> None: user = v member["user"] = user cache_flag = ctx.interaction._state.member_cache_flags.interaction - target = ctx.guild._get_and_update_member(member, user["id"], cache_flag) + target = await ctx.guild._get_and_update_member(member, user["id"], cache_flag) if self.cog is not None: await self.callback(self.cog, ctx, target) else: @@ -1815,7 +1815,7 @@ async def _invoke(self, ctx: ApplicationContext): # we got weird stuff going on, make up a channel channel = PartialMessageable(state=ctx.interaction._state, id=int(message["channel_id"])) - target = Message(state=ctx.interaction._state, channel=channel, data=message) + target = Message._from_data(state=ctx.interaction._state, channel=channel, data=message) if self.cog is not None: await self.callback(self.cog, ctx, target) diff --git a/discord/emoji.py b/discord/emoji.py index b9e487ac3b..bfe44e8d4d 100644 --- a/discord/emoji.py +++ b/discord/emoji.py @@ -43,9 +43,9 @@ from datetime import datetime from .abc import Snowflake + from .app.state import ConnectionState from .guild import Guild from .role import Role - from .state import ConnectionState from .types.emoji import Emoji as EmojiPayload @@ -193,10 +193,9 @@ def roles(self) -> list[Role]: return [role for role in guild.roles if self._roles.has(role.id)] - @property - def guild(self) -> Guild: + async def get_guild(self) -> Guild: """The guild this emoji belongs to.""" - return self._state._get_guild(self.guild_id) + return await self._state._get_guild(self.guild_id) def is_usable(self) -> bool: """Whether the bot can use this emoji. @@ -375,8 +374,8 @@ async def delete(self) -> None: """ await self._state.http.delete_application_emoji(self.application_id, self.id) - if self._state.cache_app_emojis and self._state.get_emoji(self.id): - self._state._remove_emoji(self) + if self._state.cache_app_emojis and await self._state.get_emoji(self.id): + await self._state._remove_emoji(self) async def edit( self, @@ -412,4 +411,4 @@ async def edit( payload["name"] = name data = await self._state.http.edit_application_emoji(self.application_id, self.id, payload=payload) - return self._state.maybe_store_app_emoji(self.application_id, data) + return await self._state.maybe_store_app_emoji(self.application_id, data) diff --git a/discord/enums.py b/discord/enums.py index 5d144d0a07..be7efc48d8 100644 --- a/discord/enums.py +++ b/discord/enums.py @@ -82,6 +82,7 @@ "EntitlementOwnerType", "IntegrationType", "InteractionContextType", + "ApplicationCommandPermissionType", "PollLayoutType", "MessageReferenceType", "ThreadArchiveDuration", @@ -1043,6 +1044,14 @@ def __int__(self): return self.value +class ApplicationCommandPermissionType(Enum): + """The type of permission""" + + role = 1 + user = 2 + channel = 3 + + def try_enum(cls: type[E], val: Any) -> E: """A function that tries to turn the value into enum ``cls``. diff --git a/discord/events/audit_log.py b/discord/events/audit_log.py new file mode 100644 index 0000000000..27b555543b --- /dev/null +++ b/discord/events/audit_log.py @@ -0,0 +1,64 @@ +""" +The MIT License (MIT) + +Copyright (c) 2021-present Pycord Development + +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. +""" + +import logging +from typing import Any, Self + +from discord.app.event_emitter import Event +from discord.app.state import ConnectionState +from discord.audit_logs import AuditLogEntry +from discord.raw_models import RawAuditLogEntryEvent + +_log = logging.getLogger(__name__) + + +class GuildAuditLogEntryCreate(Event, AuditLogEntry): + __event_name__ = "GUILD_AUDIT_LOG_ENTRY_CREATE" + + raw: RawAuditLogEntryEvent + + def __init__(self) -> None: ... + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + guild = await state._get_guild(int(data["guild_id"])) + if guild is None: + _log.debug( + "GUILD_AUDIT_LOG_ENTRY_CREATE referencing an unknown guild ID: %s. Discarding.", + data["guild_id"], + ) + return + + raw = RawAuditLogEntryEvent(data) + raw.guild = guild + + user = await state.get_user(raw.user_id) + if user is not None: + data_copy = data.copy() + data_copy.pop("guild_id", None) + entry = AuditLogEntry(users={data_copy["user_id"]: user}, data=data_copy, guild=guild) + self = cls() + self.raw = raw + self.__dict__.update(entry.__dict__) + return self diff --git a/discord/events/automod.py b/discord/events/automod.py new file mode 100644 index 0000000000..248f0705e0 --- /dev/null +++ b/discord/events/automod.py @@ -0,0 +1,83 @@ +""" +The MIT License (MIT) + +Copyright (c) 2021-present Pycord Development + +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 typing import Any, Self + +from discord.app.state import ConnectionState +from discord.automod import AutoModRule +from discord.raw_models import AutoModActionExecutionEvent + +from ..app.event_emitter import Event + + +class AutoModRuleCreate(Event): + __event_name__ = "AUTO_MODERATION_RULE_CREATE" + __slots__ = ("rule",) + + rule: AutoModRule + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self: + self = cls() + self.rule = AutoModRule(state=state, data=data) + return self + + +class AutoModRuleUpdate(Event): + __event_name__ = "AUTO_MODERATION_RULE_UPDATE" + __slots__ = ("rule",) + + rule: AutoModRule + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self: + self = cls() + self.rule = AutoModRule(state=state, data=data) + return self + + +class AutoModRuleDelete(Event): + __event_name__ = "AUTO_MODERATION_RULE_DELETE" + __slots__ = ("rule",) + + rule: AutoModRule + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self: + self = cls() + self.rule = AutoModRule(state=state, data=data) + return self + + +class AutoModActionExecution(Event, AutoModActionExecutionEvent): + """Represents the `AUTO_MODERATION_ACTION_EXECUTION` event""" + + __event_name__ = "AUTO_MODERATION_ACTION_EXECUTION" + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self: + self = cls() + event = await AutoModActionExecutionEvent.from_data(state, data) + self.__dict__.update(event.__dict__) + return self diff --git a/discord/events/channel.py b/discord/events/channel.py new file mode 100644 index 0000000000..c88579c499 --- /dev/null +++ b/discord/events/channel.py @@ -0,0 +1,160 @@ +""" +The MIT License (MIT) + +Copyright (c) 2021-present Pycord Development + +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 copy import copy +from datetime import datetime +from typing import Any, Self, TypeVar, cast + +from discord.abc import GuildChannel, PrivateChannel +from discord.app.event_emitter import Event +from discord.app.state import ConnectionState +from discord.channel import GroupChannel, _channel_factory +from discord.enums import ChannelType, try_enum +from discord.threads import Thread +from discord.utils.private import get_as_snowflake, parse_time + +T = TypeVar("T") + + +class ChannelCreate(Event, GuildChannel): + __event_name__ = "CHANNEL_CREATE" + + def __init__(self) -> None: ... + + @classmethod + async def __load__(cls, data: dict[str, Any], state: ConnectionState) -> Self | None: + factory, _ = _channel_factory(data["type"]) + if factory is None: + return + + guild_id = get_as_snowflake(data, "guild_id") + guild = await state._get_guild(guild_id) + if guild is not None: + # the factory can't be a DMChannel or GroupChannel here + channel = factory(guild=guild, state=self, data=data) # type: ignore # noqa: F821 # self is unbound + guild._add_channel(channel) # type: ignore + self = cls() + self.__dict__.update(channel.__dict__) + return self + else: + return + + +class PrivateChannelUpdate(Event, PrivateChannel): + __event_name__ = "PRIVATE_CHANNEL_UPDATE" + + old: PrivateChannel | None + + def __init__(self) -> None: ... + + @classmethod + async def __load__(cls, data: tuple[PrivateChannel | None, PrivateChannel], _: ConnectionState) -> Self | None: + self = cls() + self.old = data[0] + self.__dict__.update(data[1].__dict__) + return self + + +class GuildChannelUpdate(Event, PrivateChannel): + __event_name__ = "GUILD_CHANNEL_UPDATE" + + old: GuildChannel | None + + def __init__(self) -> None: ... + + @classmethod + async def __load__(cls, data: tuple[GuildChannel | None, GuildChannel], _: ConnectionState) -> Self | None: + self = cls() + self.old = data[0] + self.__dict__.update(data[1].__dict__) + return self + + +class ChannelUpdate(Event, GuildChannel): + __event_name__ = "CHANNEL_UPDATE" + + def __init__(self) -> None: ... + + @classmethod + async def __load__(cls, data: dict[str, Any], state: ConnectionState) -> Self | None: + channel_type = try_enum(ChannelType, data.get("type")) + channel_id = int(data["id"]) + if channel_type is ChannelType.group: + channel = await state._get_private_channel(channel_id) + old_channel = copy(channel) + # the channel is a GroupChannel + await cast(GroupChannel, channel)._update_group(data) + await state.emitter.emit("PRIVATE_CHANNEL_UPDATE", (old_channel, channel)) + return + + guild_id = get_as_snowflake(data, "guild_id") + guild = await state._get_guild(guild_id) + if guild is not None: + channel = guild.get_channel(channel_id) + if channel is not None: + old_channel = copy.copy(channel) + await channel._update(data) # type: ignore + await state.emitter.emit("GUILD_CHANNEL_UPDATE", (old_channel, channel)) + + +class ChannelDelete(Event, GuildChannel): + __event_name__ = "CHANNEL_DELETE" + + def __init__(self) -> None: ... + + @classmethod + async def __load__(cls, data: dict[str, Any], state: ConnectionState) -> Self | None: + guild = await state._get_guild(get_as_snowflake(data, "guild_id")) + channel_id = int(data["id"]) + if guild is not None: + channel = guild.get_channel(channel_id) + if channel is not None: + guild._remove_channel(channel) + self = cls() + self.__dict__.update(channel.__dict__) + return self + + +class ChannelPinsUpdate(Event): + channel: PrivateChannel | GuildChannel | Thread + last_pin: datetime | None + + @classmethod + async def __load__(cls, data: dict[str, Any], state: ConnectionState) -> Self | None: + channel_id = int(data["channel_id"]) + try: + guild = await state._get_guild(int(data["guild_id"])) + except KeyError: + guild = None + channel = await state._get_private_channel(channel_id) + else: + channel = guild and guild._resolve_channel(channel_id) + + if channel is None: + return + + self = cls() + self.channel = channel + self.last_pin = parse_time(data["last_pin_timestamp"]) if data["last_pin_timestamp"] else None + return self diff --git a/discord/events/entitlement.py b/discord/events/entitlement.py new file mode 100644 index 0000000000..d26bb34857 --- /dev/null +++ b/discord/events/entitlement.py @@ -0,0 +1,70 @@ +""" +The MIT License (MIT) + +Copyright (c) 2021-present Pycord Development + +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 typing import Any, Self + +from discord.types.monetization import Entitlement as EntitlementPayload + +from ..app.event_emitter import Event +from ..app.state import ConnectionState +from ..monetization import Entitlement + + +class EntitlementCreate(Event, Entitlement): + __event_name__ = "ENTITLEMENT_CREATE" + + def __init__(self) -> None: + pass + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self: + self = cls() + self.__dict__.update(Entitlement(data=data, state=state).__dict__) + return self + + +class EntitlementUpdate(Event, Entitlement): + __event_name__ = "ENTITLEMENT_UPDATE" + + def __init__(self) -> None: + pass + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self: + self = cls() + self.__dict__.update(Entitlement(data=data, state=state).__dict__) + return self + + +class EntitlementDelete(Event, Entitlement): + __event_name__ = "ENTITLEMENT_DELETE" + + def __init__(self) -> None: + pass + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self: + self = cls() + self.__dict__.update(Entitlement(data=data, state=state).__dict__) + return self diff --git a/discord/events/gateway.py b/discord/events/gateway.py new file mode 100644 index 0000000000..d653a7dc51 --- /dev/null +++ b/discord/events/gateway.py @@ -0,0 +1,255 @@ +""" +The MIT License (MIT) + +Copyright (c) 2021-present Pycord Development + +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 typing import Any, Self, cast + +from discord.emoji import Emoji +from discord.flags import ApplicationFlags +from discord.guild import Guild, GuildChannel +from discord.member import Member +from discord.role import Role +from discord.sticker import Sticker +from discord.types.user import User as UserPayload +from discord.user import ClientUser, User +from discord.utils.private import get_as_snowflake + +from ..app.event_emitter import Event +from ..app.state import ConnectionState +from ..enums import ApplicationCommandPermissionType +from ..types.guild import Guild as GuildPayload +from ..types.interactions import ( + ApplicationCommandPermissions as ApplicationCommandPermissionsPayload, +) +from ..types.interactions import ( + GuildApplicationCommandPermissions, +) + + +class Resumed(Event): + __event_name__ = "RESUMED" + + @classmethod + async def __load__(cls, _data: Any, _state: ConnectionState) -> Self | None: + return cls() + + +class Ready(Event): + __event_name__ = "READY" + + user: ClientUser + """An instance of :class:`.user.ClientUser` representing the application""" + application_id: int + """A snowflake of the application's id""" + application_flags: ApplicationFlags + """An instance of :class:`.flags.ApplicationFlags` representing the application flags""" + guilds: list[Guild] + """A list of guilds received in this event. Note it may have incomplete data as `GUILD_CREATE` fills up other parts of guild data.""" + + @classmethod + async def __load__(cls, data: dict[str, Any], state: ConnectionState) -> Self: + self = cls() + self.user = ClientUser(state=state, data=data["user"]) + state.user = self.user + await state.store_user(data["user"]) + + if state.application_id is None: + try: + application = data["application"] + except KeyError: + pass + else: + self.application_id = get_as_snowflake(application, "id") # type: ignore + # flags will always be present here + self.application_flags = ApplicationFlags._from_value(application["flags"]) # type: ignore + state.application_id = self.application_id + state.application_flags = self.application_flags + + self.guilds = [] + + for guild_data in data["guilds"]: + guild = await Guild._from_data(guild_data, state) + self.guilds.append(guild) + await state._add_guild(guild) + + await state.emitter.emit("CACHE_APP_EMOJIS", None) + + return self + + +class _CacheAppEmojis(Event): + __event_name__ = "CACHE_APP_EMOJIS" + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + if state.cache_app_emojis and state.application_id: + data = await state.http.get_all_application_emojis(state.application_id) + for e in data.get("items", []): + await state.maybe_store_app_emoji(state.application_id, e) + + +class GuildCreate(Event, Guild): + """An event which represents a guild becoming available via the gateway. Trickles down to the more distinct :class:`.GuildJoin` and :class:`.GuildAvailable` events.""" + + __event_name__ = "GUILD_CREATE" + + guild: Guild + + def __init__(self) -> None: + pass + + @classmethod + async def __load__(cls, data: GuildPayload, state: ConnectionState) -> Self: + self = cls() + guild = await state._get_guild(int(data["id"])) + if guild is None: + guild = await Guild._from_data(data, state) + await state._add_guild(guild) + self.guild = guild + self.__dict__.update(self.guild.__dict__) + if state._guild_needs_chunking(guild): + await state.chunk_guild(guild) + if guild.unavailable: + await state.emitter.emit("GUILD_JOIN", guild) + else: + await state.emitter.emit("GUILD_AVAILABLE", guild) + return self + + +class GuildJoin(Event, Guild): + """An event which represents joining a new guild.""" + + __event_name__ = "GUILD_JOIN" + + guild: Guild + + def __init__(self) -> None: + pass + + @classmethod + async def __load__(cls, data: Guild, _: ConnectionState) -> Self: + self = cls() + self.guild = data + self.__dict__.update(self.guild.__dict__) + return self + + +class GuildAvailable(Event, Guild): + """An event which represents a guild previously joined becoming available.""" + + __event_name__ = "GUILD_AVAILABLE" + + guild: Guild + + def __init__(self) -> None: + pass + + @classmethod + async def __load__(cls, data: Guild, _: ConnectionState) -> Self: + self = cls() + self.guild = data + self.__dict__.update(self.guild.__dict__) + return self + + +class ApplicationCommandPermission: + def __init__(self, data: ApplicationCommandPermissionsPayload) -> None: + self.id = int(data["id"]) + """The id of the user, role, or channel affected by this permission""" + self.type = ApplicationCommandPermissionType(data["type"]) + """Represents what this permission affects""" + self.permission = data["permission"] + """Represents whether the permission is allowed or denied""" + + +class ApplicationCommandPermissionsUpdate(Event): + """Represents an Application Command having permissions updated in a guild""" + + __event_name__ = "APPLICATION_COMMAND_PERMISSIONS_UPDATE" + + id: int + """A snowflake of the application command's id""" + application_id: int + """A snowflake of the application's id""" + guild_id: int + """A snowflake of the guild's id where the permissions have been updated""" + permissions: list[ApplicationCommandPermission] + """A list of permissions this Application Command has""" + + @classmethod + async def __load__(cls, data: GuildApplicationCommandPermissions, state: ConnectionState) -> Self: + self = cls() + self.id = int(data["id"]) + self.application_id = int(data["application_id"]) + self.guild_id = int(data["guild_id"]) + self.permissions = [ApplicationCommandPermission(data) for data in data["permissions"]] + return self + + +class PresenceUpdate(Event): + __event_name__ = "PRESENCE_UPDATE" + + old: Member + new: Member + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + self = cls() + guild_id = get_as_snowflake(data, "guild_id") + guild = await state._get_guild(guild_id) + if guild is None: + return + + user = data["user"] + member_id = int(user["id"]) + member = await guild.get_member(member_id) + if member is None: + return + + self.old = Member._copy(member) + self.new = member + user_update = member._presence_update(data=data, user=user) + await state.emitter.emit("USER_UPDATE", user_update) + return self + + +class UserUpdate(Event, User): + __event_name__ = "USER_UPDATE" + + old: User + + def __init__(self) -> None: ... + + @classmethod + async def __load__(cls, data: tuple[User, User] | Any, state: ConnectionState) -> Self | None: + self = cls() + if isinstance(data, tuple): + self.old = data[0] + self.__dict__.update(data[1].__dict__) + return self + else: + user = cast(ClientUser, state.user) + await user._update(data) # type: ignore + ref = await state.cache.get_user(user.id) + if ref is not None: + await ref._update(data) diff --git a/discord/events/guild.py b/discord/events/guild.py new file mode 100644 index 0000000000..3c4d369faf --- /dev/null +++ b/discord/events/guild.py @@ -0,0 +1,492 @@ +""" +The MIT License (MIT) + +Copyright (c) 2021-present Pycord Development + +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. +""" + +import asyncio +import copy +import logging +from typing import TYPE_CHECKING, Any + +from typing_extensions import Self + +from discord import Role +from discord.app.event_emitter import Event +from discord.app.state import ConnectionState +from discord.emoji import Emoji +from discord.guild import Guild +from discord.member import Member +from discord.raw_models import RawMemberRemoveEvent +from discord.sticker import Sticker + +if TYPE_CHECKING: + from ..types.member import MemberWithUser + +_log = logging.getLogger(__name__) + + +class GuildMemberJoin(Event, Member): + __event_name__ = "GUILD_MEMBER_JOIN" + + def __init__(self) -> None: ... + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + guild = await state._get_guild(int(data["guild_id"])) + if guild is None: + _log.debug( + "GUILD_MEMBER_ADD referencing an unknown guild ID: %s. Discarding.", + data["guild_id"], + ) + return + + member = Member(guild=guild, data=data, state=state) + if state.member_cache_flags.joined: + await guild._add_member(member) + + if guild._member_count is not None: + guild._member_count += 1 + + self = cls() + self.__dict__.update(member.__dict__) + return self + + +class GuildMemberRemove(Event, Member): + __event_name__ = "GUILD_MEMBER_REMOVE" + + def __init__(self) -> None: ... + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + user = await state.store_user(data["user"]) + raw = RawMemberRemoveEvent(data, user) + + guild = await state._get_guild(int(data["guild_id"])) + if guild is not None: + if guild._member_count is not None: + guild._member_count -= 1 + + member = await guild.get_member(user.id) + if member is not None: + raw.user = member + guild._remove_member(member) # type: ignore + self = cls() + self.__dict__.update(member.__dict__) + return self + else: + _log.debug( + "GUILD_MEMBER_REMOVE referencing an unknown guild ID: %s. Discarding.", + data["guild_id"], + ) + + +class GuildMemberUpdate(Event, Member): + __event_name__ = "GUILD_MEMBER_UPDATE" + + old: Member + + def __init__(self) -> None: ... + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + guild = await state._get_guild(int(data["guild_id"])) + user = data["user"] + user_id = int(user["id"]) + if guild is None: + _log.debug( + "GUILD_MEMBER_UPDATE referencing an unknown guild ID: %s. Discarding.", + data["guild_id"], + ) + return + + member = await guild.get_member(user_id) + if member is not None: + old_member = Member._copy(member) + await member._update(data) + user_update = member._update_inner_user(user) + if user_update: + await state.emitter.emit("USER_UPDATE", user_update) + + self = cls() + self.__dict__.update(member.__dict__) + self.old = old_member + return self + else: + if state.member_cache_flags.joined: + member = Member(data=data, guild=guild, state=state) + + # Force an update on the inner user if necessary + user_update = member._update_inner_user(user) + if user_update: + await state.emitter.emit("USER_UPDATE", user_update) + + await guild._add_member(member) + _log.debug( + "GUILD_MEMBER_UPDATE referencing an unknown member ID: %s. Discarding.", + user_id, + ) + + +class GuildEmojisUpdate(Event): + __event_name__ = "GUILD_EMOJIS_UPDATE" + guild: Guild + emojis: list[Emoji] + old_emojis: list[Emoji] + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + guild = await state._get_guild(int(data["guild_id"])) + if guild is None: + _log.debug( + "GUILD_EMOJIS_UPDATE referencing an unknown guild ID: %s. Discarding.", + data["guild_id"], + ) + return + + before_emojis = guild.emojis + for emoji in before_emojis: + await state.cache.delete_emoji(emoji) + # guild won't be None here + emojis = [] + for emoji in data["emojis"]: + emojis.append(await state.store_emoji(guild, emoji)) + guild.emojis = emojis + self = cls() + self.guild = guild + self.old_emojis = guild.emojis + self.emojis = emojis + + +class GuildStickersUpdate(Event): + __event_name__ = "GUILD_STICKERS_UPDATE" + + guild: Guild + stickers: list[Sticker] + old_stickers: list[Sticker] + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + guild = await state._get_guild(int(data["guild_id"])) + if guild is None: + _log.debug( + ("GUILD_STICKERS_UPDATE referencing an unknown guild ID: %s. Discarding."), + data["guild_id"], + ) + return + + before_stickers = guild.stickers + for emoji in before_stickers: + await state.cache.delete_sticker(emoji.id) + stickers = [] + for sticker in data["stickers"]: + stickers.append(await state.store_sticker(guild, sticker)) + # guild won't be None here + guild.stickers = stickers + self = cls() + self.old_stickers = stickers + self.stickers = stickers + self.guild = guild + + +class GuildAvailable(Event, Guild): + __event_name__ = "GUILD_AVAILABLE" + + def __init__(self) -> None: ... + + @classmethod + async def __load__(cls, data: Guild, _: ConnectionState) -> Self: + self = cls() + self.__dict__.update(data.__dict__) + return self + + +class GuildUnavailable(Event, Guild): + __event_name__ = "GUILD_UNAVAILABLE" + + def __init__(self) -> None: ... + + @classmethod + async def __load__(cls, data: Guild, _: ConnectionState) -> Self: + self = cls() + self.__dict__.update(data.__dict__) + return self + + +class GuildJoin(Event, Guild): + __event_name__ = "GUILD_JOIN" + + def __init__(self) -> None: ... + + @classmethod + async def __load__(cls, data: Guild, _: ConnectionState) -> Self: + self = cls() + self.__dict__.update(data.__dict__) + return self + + +class GuildCreate(Event, Guild): + __event_name__ = "GUILD_CREATE" + + def __init__(self) -> None: ... + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + unavailable = data.get("unavailable") + if unavailable is True: + # joined a guild with unavailable == True so.. + return + + guild = await state._get_create_guild(data) + + try: + # Notify the on_ready state, if any, that this guild is complete. + state._ready_state.put_nowait(guild) # type: ignore + except AttributeError: + pass + else: + # If we're waiting for the event, put the rest on hold + return + + # check if it requires chunking + if state._guild_needs_chunking(guild): + asyncio.create_task(state._chunk_and_dispatch(guild, unavailable)) + return + + # Dispatch available if newly available + if unavailable is False: + await state.emitter.emit("GUILD_AVAILABLE", guild) + else: + await state.emitter.emit("GUILD_JOIN", guild) + + self = cls() + self.__dict__.update(data.__dict__) + return self + + +class GuildUpdate(Event, Guild): + __event_name__ = "GUILD_UPDATE" + + old: Guild + + def __init__(self) -> None: ... + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + guild = await state._get_guild(int(data["id"])) + if guild is not None: + old_guild = copy.copy(guild) + guild = await guild._from_data(data, state) + self = cls() + self.__dict__.update(guild.__dict__) + self.old = old_guild + return self + else: + _log.debug( + "GUILD_UPDATE referencing an unknown guild ID: %s. Discarding.", + data["id"], + ) + + +class GuildDelete(Event, Guild): + __event_name__ = "GUILD_DELETE" + + old: Guild + + def __init__(self) -> None: ... + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + guild = await state._get_guild(int(data["id"])) + if guild is None: + _log.debug( + "GUILD_DELETE referencing an unknown guild ID: %s. Discarding.", + data["id"], + ) + return + + if data.get("unavailable", False): + # GUILD_DELETE with unavailable being True means that the + # guild that was available is now currently unavailable + guild.unavailable = True + await state.emitter.emit("GUILD_UNAVAILABLE", guild) + return + + # do a cleanup of the messages cache + messages = await state.cache.get_all_messages() + await asyncio.gather(*[state.cache.delete_message(message.id) for message in messages]) + + await state._remove_guild(guild) + self = cls() + self.__dict__.update(guild.__dict__) + return self + + +class GuildBanAdd(Event, Member): + __event_name__ = "GUILD_BAN_ADD" + + def __init__(self) -> None: ... + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + guild = await state._get_guild(int(data["guild_id"])) + if guild is None: + _log.debug( + "GUILD_BAN_ADD referencing an unknown guild ID: %s. Discarding.", + data["guild_id"], + ) + return + + member = await guild.get_member(int(data["user"]["id"])) + if member is None: + fake_data: MemberWithUser = { + "user": data["user"], + "roles": [], + "joined_at": None, + "deaf": False, + "mute": False, + } + member = Member(guild=guild, data=fake_data, state=state) + + self = cls() + self.__dict__.update(member.__dict__) + return self + + +class GuildBanRemove(Event, Member): + __event_name__ = "GUILD_BAN_REMOVE" + + def __init__(self) -> None: ... + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + guild = await state._get_guild(int(data["guild_id"])) + if guild is None: + _log.debug( + "GUILD_BAN_ADD referencing an unknown guild ID: %s. Discarding.", + data["guild_id"], + ) + return + + member = await guild.get_member(int(data["user"]["id"])) + if member is None: + fake_data: MemberWithUser = { + "user": data["user"], + "roles": [], + "joined_at": None, + "deaf": False, + "mute": False, + } + member = Member(guild=guild, data=fake_data, state=state) + + self = cls() + self.__dict__.update(member.__dict__) + return self + + +class GuildRoleCreate(Event, Role): + __event_name__ = "GUILD_ROLE_CREATE" + + def __init__(self) -> None: ... + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + guild = await state._get_guild(int(data["guild_id"])) + if guild is None: + _log.debug( + "GUILD_ROLE_CREATE referencing an unknown guild ID: %s. Discarding.", + data["guild_id"], + ) + return + + role = Role(guild=guild, data=data["role"], state=state) + guild._add_role(role) + + self = cls() + self.__dict__.update(role.__dict__) + return self + + +class GuildRoleUpdate(Event, Role): + __event_name__ = "GUILD_ROLE_UPDATE" + + old: Role + + def __init__(self) -> None: ... + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + guild = await state._get_guild(int(data["guild_id"])) + if guild is None: + _log.debug( + "GUILD_ROLE_UPDATE referencing an unknown guild ID: %s. Discarding.", + data["guild_id"], + ) + return + + role_id: int = int(data["role"]["id"]) + role = guild.get_role(role_id) + if role is None: + _log.debug( + "GUILD_ROLE_UPDATE referencing an unknown role ID: %s. Discarding.", + data["role"]["id"], + ) + return + + old_role = copy.copy(role) + await role._update(data["role"]) + + self = cls() + self.__dict__.update(role.__dict__) + self.old = old_role + return self + + +class GuildRoleDelete(Event, Role): + __event_name__ = "GUILD_ROLE_DELETE" + + def __init__(self) -> None: ... + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + guild = await state._get_guild(int(data["guild_id"])) + if guild is None: + _log.debug( + "GUILD_ROLE_DELETE referencing an unknown guild ID: %s. Discarding.", + data["guild_id"], + ) + return + + role_id: int = int(data["role_id"]) + role = guild.get_role(role_id) + if role is None: + _log.debug( + "GUILD_ROLE_DELETE referencing an unknown role ID: %s. Discarding.", + data["role_id"], + ) + return + + guild._remove_role(role_id) + + self = cls() + self.__dict__.update(role.__dict__) + return self diff --git a/discord/events/integration.py b/discord/events/integration.py new file mode 100644 index 0000000000..c6dcfe77eb --- /dev/null +++ b/discord/events/integration.py @@ -0,0 +1,127 @@ +""" +The MIT License (MIT) + +Copyright (c) 2021-present Pycord Development + +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. +""" + +import logging +from typing import Any, Self + +from discord.app.event_emitter import Event +from discord.app.state import ConnectionState +from discord.guild import Guild +from discord.integrations import Integration, _integration_factory +from discord.raw_models import RawIntegrationDeleteEvent + +_log = logging.getLogger(__name__) + + +class GuildIntegrationsUpdate(Event): + __event_name__ = "GUILD_INTEGRATIONS_UPDATE" + + guild: Guild + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + guild = await state._get_guild(int(data["guild_id"])) + if guild is None: + _log.debug( + "GUILD_INTEGRATIONS_UPDATE referencing an unknown guild ID: %s. Discarding.", + data["guild_id"], + ) + return + + self = cls() + self.guild = guild + return self + + +class IntegrationCreate(Event, Integration): + __event_name__ = "INTEGRATION_CREATE" + + def __init__(self) -> None: ... + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + data_copy = data.copy() + guild_id = int(data_copy.pop("guild_id")) + guild = await state._get_guild(guild_id) + if guild is None: + _log.debug( + "INTEGRATION_CREATE referencing an unknown guild ID: %s. Discarding.", + guild_id, + ) + return + + integration_cls, _ = _integration_factory(data_copy["type"]) + integration = integration_cls(data=data_copy, guild=guild) + + self = cls() + self.__dict__.update(integration.__dict__) + return self + + +class IntegrationUpdate(Event, Integration): + __event_name__ = "INTEGRATION_UPDATE" + + def __init__(self) -> None: ... + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + data_copy = data.copy() + guild_id = int(data_copy.pop("guild_id")) + guild = await state._get_guild(guild_id) + if guild is None: + _log.debug( + "INTEGRATION_UPDATE referencing an unknown guild ID: %s. Discarding.", + guild_id, + ) + return + + integration_cls, _ = _integration_factory(data_copy["type"]) + integration = integration_cls(data=data_copy, guild=guild) + + self = cls() + self.__dict__.update(integration.__dict__) + return self + + +class IntegrationDelete(Event): + __event_name__ = "INTEGRATION_DELETE" + + raw: RawIntegrationDeleteEvent + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + guild_id = int(data["guild_id"]) + guild = await state._get_guild(guild_id) + if guild is None: + _log.debug( + "INTEGRATION_DELETE referencing an unknown guild ID: %s. Discarding.", + guild_id, + ) + return + + raw = RawIntegrationDeleteEvent(data) + + self = cls() + self.raw = raw + return self diff --git a/discord/events/interaction.py b/discord/events/interaction.py new file mode 100644 index 0000000000..2d4f035b03 --- /dev/null +++ b/discord/events/interaction.py @@ -0,0 +1,76 @@ +""" +The MIT License (MIT) + +Copyright (c) 2021-present Pycord Development + +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 typing import Any, Self + +from discord.enums import InteractionType +from discord.types.interactions import Interaction as InteractionPayload + +from ..app.event_emitter import Event +from ..app.state import ConnectionState +from ..interactions import Interaction + + +class InteractionCreate(Event, Interaction): + __event_name__ = "INTERACTION_CREATE" + + def __init__(self) -> None: + pass + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + interaction = Interaction(data=data, state=state) + if data["type"] == 3: + custom_id = interaction.data["custom_id"] # type: ignore + component_type = interaction.data["component_type"] # type: ignore + views = await state.cache.get_all_views() + for view in views: + if view.id == custom_id: + for item in view.children: + if item.type == component_type: + item.refresh_state(interaction) + view._dispatch_item(item, interaction) + if interaction.type == InteractionType.modal_submit: + custom_id = interaction.data["custom_id"] + for modal in await state.cache.get_all_modals(): + if modal.custom_id != custom_id: + continue + try: + components = [ + component + for parent_component in interaction.data["components"] + for component in parent_component["components"] + ] + for component in components: + for child in modal.children: + if child.custom_id == component["custom_id"]: # type: ignore + child.refresh_state(component) + break + await modal.callback(interaction) + await state.cache.delete_modal(modal.custom_id) + except Exception as e: + return await modal.on_error(e, interaction) + self = cls() + self.__dict__.update(interaction.__dict__) + return self diff --git a/discord/events/invite.py b/discord/events/invite.py new file mode 100644 index 0000000000..713ea66688 --- /dev/null +++ b/discord/events/invite.py @@ -0,0 +1,57 @@ +""" +The MIT License (MIT) + +Copyright (c) 2021-present Pycord Development + +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 typing import Any, Self + +from discord.abc import GuildChannel +from discord.app.event_emitter import Event +from discord.app.state import ConnectionState +from discord.guild import Guild +from discord.invite import Invite, PartialInviteChannel, PartialInviteGuild +from discord.types.invite import GatewayInvite, VanityInvite +from discord.types.invite import Invite as InvitePayload + + +class InviteCreate(Event, Invite): + __event_name__ = "INVITE_CREATE" + + def __init__(self) -> None: ... + + @classmethod + async def __load__(cls, data: GatewayInvite, state: ConnectionState) -> Self | None: + invite = await Invite.from_gateway(state=state, data=data) + self = cls() + self.__dict__.update(invite.__dict__) + + +class InviteDelete(Event, Invite): + __event_name__ = "INVITE_DELETE" + + def __init__(self) -> None: ... + + @classmethod + async def __load__(cls, data: GatewayInvite, state: ConnectionState) -> Self | None: + invite = await Invite.from_gateway(state=state, data=data) + self = cls() + self.__dict__.update(invite.__dict__) diff --git a/discord/events/message.py b/discord/events/message.py new file mode 100644 index 0000000000..fcde0c6b1c --- /dev/null +++ b/discord/events/message.py @@ -0,0 +1,352 @@ +""" +The MIT License (MIT) + +Copyright (c) 2021-present Pycord Development + +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 typing import Any, Self + +from discord.app.state import ConnectionState +from discord.channel import StageChannel, TextChannel, VoiceChannel +from discord.guild import Guild +from discord.member import Member +from discord.partial_emoji import PartialEmoji +from discord.poll import Poll, PollAnswer, PollAnswerCount +from discord.raw_models import ( + RawBulkMessageDeleteEvent, + RawMessageDeleteEvent, + RawMessagePollVoteEvent, + RawMessageUpdateEvent, + RawReactionActionEvent, + RawReactionClearEmojiEvent, + RawReactionClearEvent, +) +from discord.reaction import Reaction +from discord.threads import Thread +from discord.types.message import Reaction as ReactionPayload +from discord.types.raw_models import ReactionActionEvent, ReactionClearEvent +from discord.user import User +from discord.utils import MISSING, Undefined +from discord.utils import private as utils + +from ..app.event_emitter import Event +from ..message import Message, PartialMessage + + +class MessageCreate(Event, Message): + __event_name__ = "MESSAGE_CREATE" + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + channel, _ = await state._get_guild_channel(data) + message = await Message._from_data(channel=channel, data=data, state=state) + self = cls() + self.__dict__.update(message.__dict__) + + await state.cache.store_message(data, channel) + # we ensure that the channel is either a TextChannel, VoiceChannel, StageChannel, or Thread + if channel and channel.__class__ in ( + TextChannel, + VoiceChannel, + StageChannel, + Thread, + ): + channel.last_message_id = message.id # type: ignore + + return self + + +class MessageDelete(Event, Message): + __event_name__ = "MESSAGE_DELETE" + + raw: RawMessageDeleteEvent + is_cached: bool + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + self = cls() + raw = RawMessageDeleteEvent(data) + msg = await state._get_message(raw.message_id) + raw.cached_message = msg + self.raw = raw + self.id = raw.message_id + if msg is not None: + self.is_cached = True + await state.cache.delete_message(raw.message_id) + self.__dict__.update(msg.__dict__) + else: + self.is_cached = False + + return self + + +class MessageDeleteBulk(Event): + __event_name__ = "MESSAGE_DELETE_BULK" + + raw: RawBulkMessageDeleteEvent + messages: list[Message] + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self: + self = cls() + raw = RawBulkMessageDeleteEvent(data) + messages = await state.cache.get_all_messages() + found_messages = [message for message in messages if message.id in raw.message_ids] + raw.cached_messages = found_messages + self.messages = found_messages + for message in messages: + await state.cache.delete_message(message.id) + return self + + +class MessageUpdate(Event, Message): + __event_name__ = "MESSAGE_UPDATE" + + raw: RawMessageUpdateEvent + old: Message | Undefined + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self: + self = cls() + raw = RawMessageUpdateEvent(data) + msg = await state._get_message(raw.message_id) + raw.cached_message = msg + self.raw = raw + if msg is not None: + new_msg = await state.cache.store_message(data, msg.channel) + self.old = msg + self.old.author = new_msg.author + self.__dict__.update(new_msg.__dict__) + else: + self.old = MISSING + if poll_data := data.get("poll"): + channel = await state.get_channel(raw.channel_id) + await state.store_poll( + Poll.from_dict(poll_data, PartialMessage(channel=channel, id=raw.message_id)), + message_id=raw.message_id, + ) + + return self + + +class ReactionAdd(Event): + __event_name__ = "MESSAGE_REACTION_ADD" + + raw: RawReactionActionEvent + user: Member | User | Undefined + reaction: Reaction + + @classmethod + async def __load__(cls, data: ReactionActionEvent, state: ConnectionState) -> Self: + self = cls() + emoji = data["emoji"] + emoji_id = utils.get_as_snowflake(emoji, "id") + emoji = PartialEmoji.with_state(state, id=emoji_id, animated=emoji.get("animated", False), name=emoji["name"]) + raw = RawReactionActionEvent(data, emoji, "REACTION_ADD") + + member_data = data.get("member") + if member_data: + guild = await state._get_guild(raw.guild_id) + if guild is not None: + raw.member = await Member._from_data(data=member_data, guild=guild, state=state) + else: + raw.member = None + else: + raw.member = None + + message = await state._get_message(raw.message_id) + if message is not None: + emoji = await state._upgrade_partial_emoji(emoji) + self.reaction = message._add_reaction(data, emoji, raw.user_id) + await state.cache.upsert_message(message) + user = raw.member or await state._get_reaction_user(message.channel, raw.user_id) + + if user: + self.user = user + else: + self.user = MISSING + + return self + + +class ReactionClear(Event): + __event_name__ = "MESSAGE_REACTION_REMOVE_ALL" + + raw: RawReactionClearEvent + message: Message | Undefined + old_reactions: list[Reaction] | Undefined + + @classmethod + async def __load__(cls, data: ReactionClearEvent, state: ConnectionState) -> Self | None: + self = cls() + self.raw = RawReactionClearEvent(data) + message = await state._get_message(self.raw.message_id) + if message is not None: + old_reactions: list[Reaction] = message.reactions.copy() + message.reactions.clear() + self.message = message + self.old_reactions = old_reactions + else: + self.message = MISSING + self.old_reactions = MISSING + return self + + +class ReactionRemove(Event): + __event_name__ = "MESSAGE_REACTION_REMOVE" + + raw: RawReactionActionEvent + user: Member | User | Undefined + reaction: Reaction + + @classmethod + async def __load__(cls, data: ReactionActionEvent, state: ConnectionState) -> Self: + self = cls() + emoji = data["emoji"] + emoji_id = utils.get_as_snowflake(emoji, "id") + emoji = PartialEmoji.with_state(state, id=emoji_id, animated=emoji.get("animated", False), name=emoji["name"]) + raw = RawReactionActionEvent(data, emoji, "REACTION_ADD") + + member_data = data.get("member") + if member_data: + guild = await state._get_guild(raw.guild_id) + if guild is not None: + raw.member = await Member._from_data(data=member_data, guild=guild, state=state) + else: + raw.member = None + else: + raw.member = None + + message = await state._get_message(raw.message_id) + if message is not None: + emoji = await state._upgrade_partial_emoji(emoji) + try: + self.reaction = message._remove_reaction(data, emoji, raw.user_id) + await state.cache.upsert_message(message) + except (AttributeError, ValueError): # eventual consistency lol + pass + else: + user = await state._get_reaction_user(message.channel, raw.user_id) + if user: + self.user = user + else: + self.user = MISSING + + return self + + +class ReactionRemoveEmoji(Event, Reaction): + __event_name__ = "MESSAGE_REACTION_REMOVE_EMOJI" + + def __init__(self): + pass + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + emoji = data["emoji"] + emoji_id = utils.get_as_snowflake(emoji, "id") + emoji = PartialEmoji.with_state(self, id=emoji_id, name=emoji["name"]) # noqa: F821 # TODO: self is unbound + raw = RawReactionClearEmojiEvent(data, emoji) + + message = await state._get_message(raw.message_id) + if message is not None: + try: + reaction = message._clear_emoji(emoji) + await state.cache.upsert_message(message) + except (AttributeError, ValueError): # evetnaul consistency + pass + else: + if reaction: + self = cls() + self.__dict__.update(reaction.__dict__) + return self + + +class PollVoteAdd(Event): + __event_name__ = "MESSAGE_POLL_VOTE_ADD" + + raw: RawMessagePollVoteEvent + guild: Guild | Undefined + user: User | Member | None + poll: Poll + answer: PollAnswer + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + self = cls() + raw = RawMessagePollVoteEvent(data, False) + self.raw = raw + guild = await state._get_guild(raw.guild_id) + if guild: + self.user = await guild.get_member(raw.user_id) + else: + self.user = await state.get_user(raw.user_id) + poll = await state.get_poll(raw.message_id) + if poll and poll.results: + answer = poll.get_answer(raw.answer_id) + counts = poll.results._answer_counts + if answer is not None: + if answer.id in counts: + counts[answer.id].count += 1 + else: + counts[answer.id] = PollAnswerCount({"id": answer.id, "count": 1, "me_voted": False}) + if poll is not None and self.user is not None: + answer = poll.get_answer(raw.answer_id) + if answer is not None: + self.poll = poll + self.answer = answer + return self + + +class PollVoteRemove(Event): + __event_name__ = "MESSAGE_POLL_VOTE_REMOVE" + + raw: RawMessagePollVoteEvent + guild: Guild | Undefined + user: User | Member | None + poll: Poll + answer: PollAnswer + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + self = cls() + raw = RawMessagePollVoteEvent(data, False) + self.raw = raw + guild = await state._get_guild(raw.guild_id) + if guild: + self.user = await guild.get_member(raw.user_id) + else: + self.user = await state.get_user(raw.user_id) + poll = await state.get_poll(raw.message_id) + if poll and poll.results: + answer = poll.get_answer(raw.answer_id) + counts = poll.results._answer_counts + if answer is not None: + if answer.id in counts: + counts[answer.id].count += 1 + else: + counts[answer.id] = PollAnswerCount({"id": answer.id, "count": 1, "me_voted": False}) + if poll is not None and self.user is not None: + answer = poll.get_answer(raw.answer_id) + if answer is not None: + self.poll = poll + self.answer = answer + return self diff --git a/discord/events/scheduled_event.py b/discord/events/scheduled_event.py new file mode 100644 index 0000000000..4129b06450 --- /dev/null +++ b/discord/events/scheduled_event.py @@ -0,0 +1,178 @@ +""" +The MIT License (MIT) + +Copyright (c) 2021-present Pycord Development + +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. +""" + +import logging +from typing import Any, Self + +from discord.app.event_emitter import Event +from discord.app.state import ConnectionState +from discord.enums import ScheduledEventStatus +from discord.member import Member +from discord.raw_models import RawScheduledEventSubscription +from discord.scheduled_events import ScheduledEvent + +_log = logging.getLogger(__name__) + + +class GuildScheduledEventCreate(Event, ScheduledEvent): + __event_name__ = "GUILD_SCHEDULED_EVENT_CREATE" + + def __init__(self) -> None: ... + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + guild = await state._get_guild(int(data["guild_id"])) + if guild is None: + _log.debug( + "GUILD_SCHEDULED_EVENT_CREATE referencing an unknown guild ID: %s. Discarding.", + data["guild_id"], + ) + return + + creator = None if not data.get("creator", None) else await guild.get_member(data.get("creator_id")) + scheduled_event = ScheduledEvent(state=state, guild=guild, creator=creator, data=data) + guild._add_scheduled_event(scheduled_event) + + self = cls() + self.__dict__.update(scheduled_event.__dict__) + return self + + +class GuildScheduledEventUpdate(Event, ScheduledEvent): + __event_name__ = "GUILD_SCHEDULED_EVENT_UPDATE" + + old: ScheduledEvent | None + + def __init__(self) -> None: ... + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + guild = await state._get_guild(int(data["guild_id"])) + if guild is None: + _log.debug( + "GUILD_SCHEDULED_EVENT_UPDATE referencing an unknown guild ID: %s. Discarding.", + data["guild_id"], + ) + return + + creator = None if not data.get("creator", None) else await guild.get_member(data.get("creator_id")) + scheduled_event = ScheduledEvent(state=state, guild=guild, creator=creator, data=data) + old_event = guild.get_scheduled_event(int(data["id"])) + guild._add_scheduled_event(scheduled_event) + + self = cls() + self.old = old_event + self.__dict__.update(scheduled_event.__dict__) + return self + + +class GuildScheduledEventDelete(Event, ScheduledEvent): + __event_name__ = "GUILD_SCHEDULED_EVENT_DELETE" + + def __init__(self) -> None: ... + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + guild = await state._get_guild(int(data["guild_id"])) + if guild is None: + _log.debug( + "GUILD_SCHEDULED_EVENT_DELETE referencing an unknown guild ID: %s. Discarding.", + data["guild_id"], + ) + return + + creator = None if not data.get("creator", None) else await guild.get_member(data.get("creator_id")) + scheduled_event = ScheduledEvent(state=state, guild=guild, creator=creator, data=data) + scheduled_event.status = ScheduledEventStatus.canceled + guild._remove_scheduled_event(scheduled_event) + + self = cls() + self.__dict__.update(scheduled_event.__dict__) + return self + + +class GuildScheduledEventUserAdd(Event): + __event_name__ = "GUILD_SCHEDULED_EVENT_USER_ADD" + + raw: RawScheduledEventSubscription + event: ScheduledEvent + member: Member + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + guild = await state._get_guild(int(data["guild_id"])) + if guild is None: + _log.debug( + "GUILD_SCHEDULED_EVENT_USER_ADD referencing an unknown guild ID: %s. Discarding.", + data["guild_id"], + ) + return + + raw = RawScheduledEventSubscription(data, "USER_ADD") + raw.guild = guild + + member = await guild.get_member(data["user_id"]) + if member is not None: + event = guild.get_scheduled_event(data["guild_scheduled_event_id"]) + if event: + event.subscriber_count += 1 + guild._add_scheduled_event(event) + self = cls() + self.raw = raw + self.event = event + self.member = member + return self + + +class GuildScheduledEventUserRemove(Event): + __event_name__ = "GUILD_SCHEDULED_EVENT_USER_REMOVE" + + raw: RawScheduledEventSubscription + event: ScheduledEvent + member: Member + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + guild = await state._get_guild(int(data["guild_id"])) + if guild is None: + _log.debug( + "GUILD_SCHEDULED_EVENT_USER_REMOVE referencing an unknown guild ID: %s. Discarding.", + data["guild_id"], + ) + return + + raw = RawScheduledEventSubscription(data, "USER_REMOVE") + raw.guild = guild + + member = await guild.get_member(data["user_id"]) + if member is not None: + event = guild.get_scheduled_event(data["guild_scheduled_event_id"]) + if event: + event.subscriber_count -= 1 + guild._add_scheduled_event(event) + self = cls() + self.raw = raw + self.event = event + self.member = member + return self diff --git a/discord/events/stage_instance.py b/discord/events/stage_instance.py new file mode 100644 index 0000000000..a0740f0dce --- /dev/null +++ b/discord/events/stage_instance.py @@ -0,0 +1,115 @@ +""" +The MIT License (MIT) + +Copyright (c) 2021-present Pycord Development + +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. +""" + +import copy +import logging +from typing import Any, Self + +from discord.app.event_emitter import Event +from discord.app.state import ConnectionState +from discord.stage_instance import StageInstance + +_log = logging.getLogger(__name__) + + +class StageInstanceCreate(Event, StageInstance): + __event_name__ = "STAGE_INSTANCE_CREATE" + + def __init__(self) -> None: ... + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + guild = await state._get_guild(int(data["guild_id"])) + if guild is None: + _log.debug( + "STAGE_INSTANCE_CREATE referencing unknown guild ID: %s. Discarding.", + data["guild_id"], + ) + return + + stage_instance = StageInstance(guild=guild, state=state, data=data) + guild._stage_instances[stage_instance.id] = stage_instance + + self = cls() + self.__dict__.update(stage_instance.__dict__) + return self + + +class StageInstanceUpdate(Event, StageInstance): + __event_name__ = "STAGE_INSTANCE_UPDATE" + + old: StageInstance + + def __init__(self) -> None: ... + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + guild = await state._get_guild(int(data["guild_id"])) + if guild is None: + _log.debug( + "STAGE_INSTANCE_UPDATE referencing unknown guild ID: %s. Discarding.", + data["guild_id"], + ) + return + + stage_instance = guild._stage_instances.get(int(data["id"])) + if stage_instance is None: + _log.debug( + "STAGE_INSTANCE_UPDATE referencing unknown stage instance ID: %s. Discarding.", + data["id"], + ) + return + + old_stage_instance = copy.copy(stage_instance) + stage_instance._update(data) + + self = cls() + self.old = old_stage_instance + self.__dict__.update(stage_instance.__dict__) + return self + + +class StageInstanceDelete(Event, StageInstance): + __event_name__ = "STAGE_INSTANCE_DELETE" + + def __init__(self) -> None: ... + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + guild = await state._get_guild(int(data["guild_id"])) + if guild is None: + _log.debug( + "STAGE_INSTANCE_DELETE referencing unknown guild ID: %s. Discarding.", + data["guild_id"], + ) + return + + try: + stage_instance = guild._stage_instances.pop(int(data["id"])) + except KeyError: + return + + self = cls() + self.__dict__.update(stage_instance.__dict__) + return self diff --git a/discord/events/subscription.py b/discord/events/subscription.py new file mode 100644 index 0000000000..a91b11b799 --- /dev/null +++ b/discord/events/subscription.py @@ -0,0 +1,70 @@ +""" +The MIT License (MIT) + +Copyright (c) 2021-present Pycord Development + +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 typing import Any, Self + +from discord.types.monetization import Entitlement as EntitlementPayload + +from ..app.event_emitter import Event +from ..app.state import ConnectionState +from ..monetization import Subscription + + +class SubscriptionCreate(Event, Subscription): + __event_name__ = "SUBSCRIPTION_CREATE" + + def __init__(self) -> None: + pass + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self: + self = cls() + self.__dict__.update(Subscription(data=data, state=state).__dict__) + return self + + +class SubscriptionUpdate(Event, Subscription): + __event_name__ = "SUBSCRIPTION_UPDATE" + + def __init__(self) -> None: + pass + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self: + self = cls() + self.__dict__.update(Subscription(data=data, state=state).__dict__) + return self + + +class SubscriptionDelete(Event, Subscription): + __event_name__ = "SUBSCRIPTION_DELETE" + + def __init__(self) -> None: + pass + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self: + self = cls() + self.__dict__.update(Subscription(data=data, state=state).__dict__) + return self diff --git a/discord/events/thread.py b/discord/events/thread.py new file mode 100644 index 0000000000..beab97c38f --- /dev/null +++ b/discord/events/thread.py @@ -0,0 +1,304 @@ +""" +The MIT License (MIT) + +Copyright (c) 2021-present Pycord Development + +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. +""" + +import logging +from typing import Any, Self, cast + +from discord import utils +from discord.abc import Snowflake +from discord.app.event_emitter import Event +from discord.app.state import ConnectionState +from discord.raw_models import RawThreadDeleteEvent, RawThreadMembersUpdateEvent, RawThreadUpdateEvent +from discord.threads import Thread, ThreadMember +from discord.types.raw_models import ThreadDeleteEvent, ThreadUpdateEvent +from discord.types.threads import ThreadMember as ThreadMemberPayload + +_log = logging.getLogger(__name__) + + +class ThreadMemberJoin(Event, ThreadMember): + __event_name__ = "THREAD_MEMBER_JOIN" + + def __init__(self) -> None: ... + + @classmethod + async def __load__(cls, data: ThreadMember, _: ConnectionState) -> Self: + self = cls() + self.__dict__.update(data.__dict__) + return self + + +class ThreadJoin(Event, Thread): + __event_name__ = "THREAD_JOIN" + + def __init__(self) -> None: ... + + @classmethod + async def __load__(cls, data: Thread, _: ConnectionState) -> Self: + self = cls() + self.__dict__.update(data.__dict__) + return self + + +class ThreadMemberRemove(Event, ThreadMember): + __event_name__ = "THREAD_MEMBER_REMOVE" + + def __init__(self) -> None: ... + + @classmethod + async def __load__(cls, data: ThreadMember, _: ConnectionState) -> Self: + self = cls() + self.__dict__.update(data.__dict__) + return self + + +class ThreadRemove(Event, Thread): + __event_name__ = "THREAD_REMOVE" + + def __init__(self) -> None: ... + + @classmethod + async def __load__(cls, data: Thread, _: ConnectionState) -> Self: + self = cls() + self.__dict__.update(data.__dict__) + return self + + +class ThreadCreate(Event, Thread): + __event_name__ = "THREAD_CREATE" + + def __init__(self) -> None: ... + + just_joined: bool + + @classmethod + async def __load__(cls, data: dict[str, Any], state: ConnectionState) -> Self | None: + guild_id = int(data["guild_id"]) + guild = await state._get_guild(guild_id) + if guild is None: + return + + cached_thread = guild.get_thread(int(data["id"])) + self = cls() + if not cached_thread: + thread = Thread(guild=guild, state=guild._state, data=data) # type: ignore + guild._add_thread(thread) + if data.get("newly_created"): + thread._add_member( + ThreadMember( + thread, + { + "id": thread.id, + "user_id": data["owner_id"], + "join_timestamp": data["thread_metadata"]["create_timestamp"], + "flags": utils.MISSING, + }, + ) + ) + self.just_joined = False + self.__dict__.update(thread.__dict__) + else: + self.__dict__.update(cached_thread.__dict__) + self.just_joined = True + + if self.just_joined: + await state.emitter.emit("THREAD_JOIN", self) + else: + return self + + +class ThreadUpdate(Event, Thread): + __event_name__ = "THREAD_UPDATE" + + def __init__(self) -> None: ... + + old: Thread + + @classmethod + async def __load__(cls, data: ThreadUpdateEvent, state: ConnectionState) -> Self | None: + guild_id = int(data["guild_id"]) + guild = await state._get_guild(guild_id) + raw = RawThreadUpdateEvent(data) + if guild is None: + return + + self = cls() + + thread = guild.get_thread(raw.thread_id) + if thread: + self.old = thread + await thread._update(thread) + if thread.archived: + guild._remove_thread(cast(Snowflake, raw.thread_id)) + else: + thread = Thread(guild=guild, state=guild._state, data=data) # type: ignore + if not thread.archived: + guild._add_thread(thread) + + self.__dict__.update(thread.__dict__) + return self + + +class ThreadDelete(Event, Thread): + __event_name__ = "THREAD_DELETE" + + def __init__(self) -> None: ... + + @classmethod + async def __load__(cls, data: ThreadDeleteEvent, state: ConnectionState) -> Self | None: + raw = RawThreadDeleteEvent(data) + guild = await state._get_guild(raw.guild_id) + if guild is None: + return + + self = cls() # TODO: self is unused @VincentRPS # noqa: F841 + + thread = guild.get_thread(raw.thread_id) + if thread: + guild._remove_thread(cast(Snowflake, thread.id)) + if (msg := await thread.get_starting_message()) is not None: + msg.thread = None # type: ignore + + return cast(Self, thread) # TODO: this is an incorrect rtype @VincentRPS + + +class ThreadListSync(Event): + __event_name__ = "THREAD_LIST_SYNC" + + @classmethod + async def __load__(cls, data: dict[str, Any], state) -> Self | None: + guild_id = int(data["guild_id"]) + guild = await state._get_guild(guild_id) + if guild is None: + _log.debug( + "THREAD_LIST_SYNC referencing an unknown guild ID: %s. Discarding", + guild_id, + ) + return + + try: + channel_ids = set(data["channel_ids"]) + except KeyError: + # If not provided, then the entire guild is being synced + # So all previous thread data should be overwritten + previous_threads = guild._threads.copy() + guild._clear_threads() + else: + previous_threads = guild._filter_threads(channel_ids) + + threads = {d["id"]: guild._store_thread(d) for d in data.get("threads", [])} + + for member in data.get("members", []): + try: + # note: member['id'] is the thread_id + thread = threads[member["id"]] + except KeyError: + continue + else: + thread._add_member(ThreadMember(thread, member)) + + for thread in threads.values(): + old = previous_threads.pop(thread.id, None) + if old is None: + await state.emitter.emit("THREAD_JOIN", thread) + + for thread in previous_threads.values(): + await state.emitter.emit("THREAD_REMOVE", thread) + + +class ThreadMemberUpdate(Event, ThreadMember): + __event_name__ = "THREAD_MEMBER_UPDATE" + + def __init__(self): ... + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + guild_id = int(data["guild_id"]) + guild = await state._get_guild(guild_id) + if guild is None: + _log.debug( + "THREAD_MEMBER_UPDATE referencing an unknown guild ID: %s. Discarding", + guild_id, + ) + return + + thread_id = int(data["id"]) + thread: Thread | None = guild.get_thread(thread_id) + if thread is None: + _log.debug( + "THREAD_MEMBER_UPDATE referencing an unknown thread ID: %s. Discarding", + thread_id, + ) + return + + member = ThreadMember(thread, data) + thread.me = member + thread._add_member(member) + self = cls() + self.__dict__.update(member.__dict__) + + return self + + +class BulkThreadMemberUpdate(Event): + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + guild_id = int(data["guild_id"]) + guild = await state._get_guild(guild_id) + if guild is None: + _log.debug( + "THREAD_MEMBERS_UPDATE referencing an unknown guild ID: %s. Discarding", + guild_id, + ) + return + + thread_id = int(data["id"]) + thread: Thread | None = guild.get_thread(thread_id) + raw = RawThreadMembersUpdateEvent(data) # TODO: Not used @VincentRPS # noqa: F841 + if thread is None: + _log.debug( + ("THREAD_MEMBERS_UPDATE referencing an unknown thread ID: %s. Discarding"), + thread_id, + ) + return + + added_members = [ThreadMember(thread, d) for d in data.get("added_members", [])] + removed_member_ids = [int(x) for x in data.get("removed_member_ids", [])] + self_id = state.self_id + for member in added_members: + thread._add_member(member) + if member.id != self_id: + await state.emitter.emit("THREAD_MEMBER_JOIN", member) + else: + thread.me = member + await state.emitter.emit("THREAD_JOIN", thread) + + for member_id in removed_member_ids: + member = thread._pop_member(member_id) + if member_id != self_id: + if member is not None: + await state.emitter.emit("thread_member_remove", member) + else: + thread.me = None + await state.emitter.emit("thread_remove", thread) diff --git a/discord/events/typing.py b/discord/events/typing.py new file mode 100644 index 0000000000..198a29f8d8 --- /dev/null +++ b/discord/events/typing.py @@ -0,0 +1,92 @@ +""" +The MIT License (MIT) + +Copyright (c) 2021-present Pycord Development + +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 datetime import datetime +from typing import TYPE_CHECKING, Any, Self + +from discord import utils +from discord.app.event_emitter import Event +from discord.app.state import ConnectionState +from discord.channel import DMChannel, GroupChannel, TextChannel +from discord.member import Member +from discord.raw_models import RawTypingEvent +from discord.threads import Thread +from discord.user import User + +if TYPE_CHECKING: + from discord.message import MessageableChannel + + +class TypingStart(Event): + __event_name__ = "TYPING_START" + + raw: RawTypingEvent + channel: "MessageableChannel" + user: User | Member + when: datetime + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + raw = RawTypingEvent(data) + + member_data = data.get("member") + if member_data: + guild = await state._get_guild(raw.guild_id) + if guild is not None: + raw.member = Member(data=member_data, guild=guild, state=state) + else: + raw.member = None + else: + raw.member = None + + channel, guild = await state._get_guild_channel(data) + if channel is None: + return + + user = raw.member or await _get_typing_user(state, channel, raw.user_id) + if user is None: + return + + self = cls() + self.raw = raw + self.channel = channel # type: ignore + self.user = user + self.when = raw.when + return self + + +async def _get_typing_user( + state: ConnectionState, channel: "MessageableChannel | None", user_id: int +) -> User | Member | None: + """Helper function to get the user who is typing.""" + if isinstance(channel, DMChannel): + return channel.recipient or await state.get_user(user_id) + + elif isinstance(channel, (Thread, TextChannel)) and channel.guild is not None: + return await channel.guild.get_member(user_id) # type: ignore + + elif isinstance(channel, GroupChannel): + return utils.find(lambda x: x.id == user_id, channel.recipients) + + return await state.get_user(user_id) diff --git a/discord/events/voice.py b/discord/events/voice.py new file mode 100644 index 0000000000..99d37f6e41 --- /dev/null +++ b/discord/events/voice.py @@ -0,0 +1,152 @@ +""" +The MIT License (MIT) + +Copyright (c) 2021-present Pycord Development + +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. +""" + +import asyncio +import logging +from typing import TYPE_CHECKING, Any, Self + +from discord.app.event_emitter import Event +from discord.app.state import ConnectionState +from discord.member import Member, VoiceState +from discord.raw_models import RawVoiceChannelStatusUpdateEvent +from discord.utils.private import get_as_snowflake + +if TYPE_CHECKING: + from discord.abc import VocalGuildChannel + +_log = logging.getLogger(__name__) + + +async def logging_coroutine(coroutine, *, info: str) -> None: + """Helper to log exceptions in coroutines.""" + try: + await coroutine + except Exception: + _log.exception("Exception occurred during %s", info) + + +class VoiceStateUpdate(Event): + __event_name__ = "VOICE_STATE_UPDATE" + + member: Member + before: VoiceState + after: VoiceState + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + guild = await state._get_guild(get_as_snowflake(data, "guild_id")) + channel_id = get_as_snowflake(data, "channel_id") + flags = state.member_cache_flags + # state.user is *always* cached when this is called + self_id = state.user.id # type: ignore + + if guild is None: + return + + if int(data["user_id"]) == self_id: + voice = state._get_voice_client(guild.id) + if voice is not None: + coro = voice.on_voice_state_update(data) + asyncio.create_task(logging_coroutine(coro, info="Voice Protocol voice state update handler")) + + member, before, after = await guild._update_voice_state(data, channel_id) # type: ignore + if member is None: + _log.debug( + "VOICE_STATE_UPDATE referencing an unknown member ID: %s. Discarding.", + data["user_id"], + ) + return + + if flags.voice: + if channel_id is None and flags._voice_only and member.id != self_id: + # Only remove from cache if we only have the voice flag enabled + # Member doesn't meet the Snowflake protocol currently + guild._remove_member(member) # type: ignore + elif channel_id is not None: + await guild._add_member(member) + + self = cls() + self.member = member + self.before = before + self.after = after + return self + + +class VoiceServerUpdate(Event): + __event_name__ = "VOICE_SERVER_UPDATE" + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + try: + key_id = int(data["guild_id"]) + except KeyError: + key_id = int(data["channel_id"]) + + vc = state._get_voice_client(key_id) + if vc is not None: + coro = vc.on_voice_server_update(data) + asyncio.create_task(logging_coroutine(coro, info="Voice Protocol voice server update handler")) + + # This event doesn't dispatch to user code, it's internal for voice protocol + return None + + +class VoiceChannelStatusUpdate(Event): + __event_name__ = "VOICE_CHANNEL_STATUS_UPDATE" + + raw: RawVoiceChannelStatusUpdateEvent + channel: "VocalGuildChannel" + old_status: str | None + new_status: str | None + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + raw = RawVoiceChannelStatusUpdateEvent(data) + guild = await state._get_guild(int(data["guild_id"])) + channel_id = int(data["id"]) + + if guild is None: + _log.debug( + "VOICE_CHANNEL_STATUS_UPDATE referencing unknown guild ID: %s. Discarding.", + data["guild_id"], + ) + return + + channel = guild.get_channel(channel_id) + if channel is None: + _log.debug( + "VOICE_CHANNEL_STATUS_UPDATE referencing an unknown channel ID: %s. Discarding.", + channel_id, + ) + return + + old_status = channel.status + channel.status = data.get("status", None) + + self = cls() + self.raw = raw + self.channel = channel # type: ignore + self.old_status = old_status + self.new_status = channel.status + return self diff --git a/discord/events/webhook.py b/discord/events/webhook.py new file mode 100644 index 0000000000..74cf8bbbb8 --- /dev/null +++ b/discord/events/webhook.py @@ -0,0 +1,70 @@ +""" +The MIT License (MIT) + +Copyright (c) 2021-present Pycord Development + +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. +""" + +import logging +from typing import TYPE_CHECKING, Any, Self + +from discord.app.event_emitter import Event +from discord.app.state import ConnectionState + +if TYPE_CHECKING: + from discord.abc import GuildChannel + +_log = logging.getLogger(__name__) + + +class WebhooksUpdate(Event): + __event_name__ = "WEBHOOKS_UPDATE" + + channel: "GuildChannel" + + @classmethod + async def __load__(cls, data: Any, state: ConnectionState) -> Self | None: + guild = await state._get_guild(int(data["guild_id"])) + if guild is None: + _log.debug( + "WEBHOOKS_UPDATE referencing an unknown guild ID: %s. Discarding", + data["guild_id"], + ) + return + + channel_id = data["channel_id"] + if channel_id is None: + _log.debug( + "WEBHOOKS_UPDATE channel ID was null for guild: %s. Discarding.", + data["guild_id"], + ) + return + + channel = guild.get_channel(int(channel_id)) + if channel is None: + _log.debug( + "WEBHOOKS_UPDATE referencing an unknown channel ID: %s. Discarding.", + data["channel_id"], + ) + return + + self = cls() + self.channel = channel # type: ignore + return self diff --git a/discord/ext/commands/context.py b/discord/ext/commands/context.py index a37c3b9504..dcba6f1309 100644 --- a/discord/ext/commands/context.py +++ b/discord/ext/commands/context.py @@ -38,9 +38,9 @@ from typing_extensions import ParamSpec from discord.abc import MessageableChannel + from discord.app.state import ConnectionState from discord.guild import Guild from discord.member import Member - from discord.state import ConnectionState from discord.user import ClientUser, User from discord.voice_client import VoiceProtocol diff --git a/discord/ext/commands/converter.py b/discord/ext/commands/converter.py index d5677a8110..621f744e43 100644 --- a/discord/ext/commands/converter.py +++ b/discord/ext/commands/converter.py @@ -81,9 +81,9 @@ ) -def _get_from_guilds(bot, getter, argument): +async def _get_from_guilds(bot, getter, argument): result = None - for guild in bot.guilds: + for guild in await bot.get_guilds(): result = getattr(guild, getter)(argument) if result: return result @@ -213,7 +213,7 @@ async def query_member_by_id(self, bot, guild, user_id): return None if cache: - guild._add_member(member) + await guild._add_member(member) return member # If we're not being rate limited then we can use the websocket to actually query @@ -233,15 +233,15 @@ async def convert(self, ctx: Context, argument: str) -> discord.Member: if guild: result = guild.get_member_named(argument) else: - result = _get_from_guilds(bot, "get_member_named", argument) + result = await _get_from_guilds(bot, "get_member_named", argument) else: user_id = int(match.group(1)) if guild: - result = guild.get_member(user_id) + result = await guild.get_member(user_id) if ctx.message is not None and result is None: result = discord.utils.find(lambda e: e.id == user_id, ctx.message.mentions) else: - result = _get_from_guilds(bot, "get_member", user_id) + result = await _get_from_guilds(bot, "get_member", user_id) if result is None: if guild is None: @@ -285,7 +285,7 @@ async def convert(self, ctx: Context, argument: str) -> discord.User: if match is not None: user_id = int(match.group(1)) - result = ctx.bot.get_user(user_id) + result = await ctx.bot.get_user(user_id) if ctx.message is not None and result is None: result = discord.utils.find(lambda e: e.id == user_id, ctx.message.mentions) if result is None: @@ -308,12 +308,12 @@ async def convert(self, ctx: Context, argument: str) -> discord.User: discrim = arg[-4:] name = arg[:-5] predicate = lambda u: u.name == name and u.discriminator == discrim - result = discord.utils.find(predicate, state._users.values()) + result = discord.utils.find(predicate, await state.cache.get_all_users()) if result is not None: return result predicate = lambda u: arg in (u.name, u.global_name) - result = discord.utils.find(predicate, state._users.values()) + result = discord.utils.find(predicate, await state.cache.get_all_users()) if result is None: raise UserNotFound(argument) @@ -397,7 +397,7 @@ class MessageConverter(IDConverter[discord.Message]): async def convert(self, ctx: Context, argument: str) -> discord.Message: guild_id, message_id, channel_id = PartialMessageConverter._get_id_matches(ctx, argument) - message = ctx.bot._connection._get_message(message_id) + message = await ctx.bot._connection._get_message(message_id) if message: return message channel = PartialMessageConverter._resolve_channel(ctx, guild_id, channel_id) @@ -427,10 +427,10 @@ class GuildChannelConverter(IDConverter[discord.abc.GuildChannel]): """ async def convert(self, ctx: Context, argument: str) -> discord.abc.GuildChannel: - return self._resolve_channel(ctx, argument, "channels", discord.abc.GuildChannel) + return await self._resolve_channel(ctx, argument, "channels", discord.abc.GuildChannel) @staticmethod - def _resolve_channel(ctx: Context, argument: str, attribute: str, type: type[CT]) -> CT: + async def _resolve_channel(ctx: Context, argument: str, attribute: str, type: type[CT]) -> CT: bot = ctx.bot match = IDConverter._get_id_match(argument) or re.match(r"<#([0-9]{15,20})>$", argument) @@ -453,7 +453,7 @@ def check(c): if guild: result = guild.get_channel(channel_id) else: - result = _get_from_guilds(bot, "get_channel", channel_id) + result = await _get_from_guilds(bot, "get_channel", channel_id) if not isinstance(result, type): raise ChannelNotFound(argument) @@ -760,7 +760,7 @@ async def convert(self, ctx: Context, argument: str) -> discord.Guild: result = ctx.bot.get_guild(guild_id) if result is None: - result = discord.utils.find(lambda e: e.name == argument, ctx.bot.guilds) + result = discord.utils.find(lambda e: e.name == argument, await ctx.bot.get_guilds()) if result is None: raise GuildNotFound(argument) @@ -795,12 +795,12 @@ async def convert(self, ctx: Context, argument: str) -> discord.GuildEmoji: result = discord.utils.find(lambda e: e.name == argument, guild.emojis) if result is None: - result = discord.utils.find(lambda e: e.name == argument, bot.emojis) + result = discord.utils.find(lambda e: e.name == argument, await bot.get_emojis()) else: emoji_id = int(match.group(1)) # Try to look up emoji by id. - result = bot.get_emoji(emoji_id) + result = await bot.get_emoji(emoji_id) if result is None: raise EmojiNotFound(argument) @@ -870,12 +870,12 @@ async def convert(self, ctx: Context, argument: str) -> discord.GuildSticker: result = discord.utils.find(lambda s: s.name == argument, guild.stickers) if result is None: - result = discord.utils.find(lambda s: s.name == argument, bot.stickers) + result = discord.utils.find(lambda s: s.name == argument, await bot.get_stickers()) else: sticker_id = int(match.group(1)) # Try to look up sticker by id. - result = bot.get_sticker(sticker_id) + result = await bot.get_sticker(sticker_id) if result is None: raise GuildStickerNotFound(argument) @@ -936,6 +936,7 @@ def resolve_role(id: int) -> str: else: def resolve_member(id: int) -> str: + # TODO: how tf to fix this??? m = ( None if msg is None else discord.utils.find(lambda e: e.id == id, msg.mentions) ) or ctx.bot.get_user(id) diff --git a/discord/flags.py b/discord/flags.py index 50998e9093..7c9140aa1d 100644 --- a/discord/flags.py +++ b/discord/flags.py @@ -679,7 +679,7 @@ def guilds(self): This also corresponds to the following attributes and classes in terms of cache: - - :attr:`Client.guilds` + - :attr:`Client.get_guilds` - :class:`Guild` and all its attributes. - :meth:`Client.get_channel` - :meth:`Client.get_all_channels` @@ -773,8 +773,8 @@ def emojis_and_stickers(self): - :class:`GuildSticker` - :meth:`Client.get_emoji` - :meth:`Client.get_sticker` - - :meth:`Client.emojis` - - :meth:`Client.stickers` + - :meth:`Client.get_emojis` + - :meth:`Client.get_stickers` - :attr:`Guild.emojis` - :attr:`Guild.stickers` """ @@ -887,7 +887,7 @@ def messages(self): - :class:`Message` - :attr:`Client.cached_messages` - :meth:`Client.get_message` - - :attr:`Client.polls` + - :meth:`Client.get_polls` - :meth:`Client.get_poll` Note that due to an implicit relationship this also corresponds to the following events: @@ -921,7 +921,7 @@ def guild_messages(self): - :class:`Message` - :attr:`Client.cached_messages` (only for guilds) - :meth:`Client.get_message` (only for guilds) - - :attr:`Client.polls` (only for guilds) + - :meth:`Client.get_polls` (only for guilds) - :meth:`Client.get_poll` (only for guilds) Note that due to an implicit relationship this also corresponds to the following events: @@ -962,7 +962,7 @@ def dm_messages(self): - :class:`Message` - :attr:`Client.cached_messages` (only for DMs) - :meth:`Client.get_message` (only for DMs) - - :attr:`Client.polls` (only for DMs) + - :meth:`Client.get_polls` (only for DMs) - :meth:`Client.get_poll` (only for DMs) Note that due to an implicit relationship this also corresponds to the following events: diff --git a/discord/gateway.py b/discord/gateway.py index de25237c71..6ee5f766c5 100644 --- a/discord/gateway.py +++ b/discord/gateway.py @@ -39,7 +39,6 @@ import aiohttp -from . import utils from .activity import BaseActivity from .enums import SpeakingState from .errors import ConnectionClosed, InvalidArgument @@ -290,10 +289,6 @@ def __init__(self, socket, *, loop): self.socket = socket self.loop = loop - # an empty dispatcher to prevent crashes - self._dispatch = lambda *args: None - # generic event listeners - self._dispatch_listeners = [] # the keep alive self._keep_alive = None self.thread_id = threading.get_ident() @@ -314,10 +309,10 @@ def open(self): def is_ratelimited(self): return self._rate_limiter.is_ratelimited() - def debug_log_receive(self, data, /): - self._dispatch("socket_raw_receive", data) + async def debug_log_receive(self, data, /): + await self._emitter.emit("socket_raw_receive", data) - def log_receive(self, _, /): + async def log_receive(self, _, /): pass @classmethod @@ -343,8 +338,7 @@ async def from_client( # dynamically add attributes needed ws.token = client.http.token ws._connection = client._connection - ws._discord_parsers = client._connection.parsers - ws._dispatch = client.dispatch + ws._emitter = client._connection.emitter ws.gateway = gateway ws.call_hooks = client._connection.call_hooks ws._initial_identify = initial @@ -458,13 +452,13 @@ async def received_message(self, msg, /): msg = msg.decode("utf-8") self._buffer = bytearray() - self.log_receive(msg) + await self.log_receive(msg) msg = from_json(msg) _log.debug("For Shard ID %s: WebSocket Event: %s", self.shard_id, msg) event = msg.get("t") if event: - self._dispatch("socket_event_type", event) + await self._emitter.emit("socket_event_type", event) op = msg.get("op") data = msg.get("d") @@ -542,12 +536,7 @@ async def received_message(self, msg, /): ", ".join(trace), ) - try: - func = self._discord_parsers[event] - except KeyError: - _log.debug("Unknown event %s.", event) - else: - func(data) + await self._emitter.emit(event, data) # remove the dispatched listeners removed = [] @@ -637,7 +626,7 @@ async def poll_event(self): async def debug_send(self, data, /): await self._rate_limiter.block() - self._dispatch("socket_raw_send", data) + await self._emitter.emit("socket_raw_send", data) await self.socket.send_str(data) async def send(self, data, /): diff --git a/discord/guild.py b/discord/guild.py index f269e49c5f..9b390a3586 100644 --- a/discord/guild.py +++ b/discord/guild.py @@ -25,6 +25,7 @@ from __future__ import annotations +import asyncio import copy import datetime import unicodedata @@ -38,9 +39,12 @@ Sequence, Tuple, Union, + cast, overload, ) +from typing_extensions import Self + from . import abc, utils from .asset import Asset from .automod import AutoModAction, AutoModRule, AutoModTriggerMetadata @@ -102,6 +106,7 @@ import datetime from .abc import Snowflake, SnowflakeTime + from .app.state import ConnectionState from .channel import ( CategoryChannel, ForumChannel, @@ -111,7 +116,6 @@ ) from .onboarding import OnboardingPrompt from .permissions import Permissions - from .state import ConnectionState from .template import Template from .types.guild import Ban as BanPayload from .types.guild import Guild as GuildPayload @@ -280,7 +284,6 @@ class Guild(Hashable): "preferred_locale", "nsfw_level", "_scheduled_events", - "_members", "_channels", "_icon", "_banner", @@ -311,21 +314,6 @@ class Guild(Hashable): 3: _GuildLimit(emoji=250, stickers=60, soundboard=48, bitrate=384e3, filesize=104_857_600), } - def __init__(self, *, data: GuildPayload, state: ConnectionState): - # NOTE: - # Adding an attribute here and getting an AttributeError saying - # the attr doesn't exist? it has something to do with the order - # of the attr in __slots__ - - self._channels: dict[int, GuildChannel] = {} - self._members: dict[int, Member] = {} - self._scheduled_events: dict[int, ScheduledEvent] = {} - self._voice_states: dict[int, VoiceState] = {} - self._threads: dict[int, Thread] = {} - self._state: ConnectionState = state - self._sounds: dict[int, SoundboardSound] = {} - self._from_data(data) - def _add_channel(self, channel: GuildChannel, /) -> None: self._channels[channel.id] = channel @@ -335,23 +323,24 @@ def _remove_channel(self, channel: Snowflake, /) -> None: def _voice_state_for(self, user_id: int, /) -> VoiceState | None: return self._voice_states.get(user_id) - def _add_member(self, member: Member, /) -> None: - self._members[member.id] = member + async def _add_member(self, member: Member, /) -> None: + await cast(ConnectionState, self._state).cache.store_member(member) - def _get_and_update_member(self, payload: MemberPayload, user_id: int, cache_flag: bool, /) -> Member: + async def _get_and_update_member(self, payload: MemberPayload, user_id: int, cache_flag: bool, /) -> Member: + members = await cast(ConnectionState, self._state).cache.get_guild_members(self.id) # we always get the member, and we only update if the cache_flag (this cache # flag should always be MemberCacheFlag.interaction) is set to True - if user_id in self._members: - member = self.get_member(user_id) - member._update(payload) if cache_flag else None + if user_id in members: + member = cast(Member, await self.get_member(user_id)) + await member._update(payload) if cache_flag else None else: # NOTE: # This is a fallback in case the member is not found in the guild's members. # If this fallback occurs, multiple aspects of the Member # class will be incorrect such as status and activities. - member = Member(guild=self, state=self._state, data=payload) # type: ignore + member = await Member._from_data(guild=self, state=self._state, data=payload) # type: ignore if cache_flag: - self._members[user_id] = member + await cast(ConnectionState, self._state).cache.store_member(member) return member def _store_thread(self, payload: ThreadPayload, /) -> Thread: @@ -359,9 +348,6 @@ def _store_thread(self, payload: ThreadPayload, /) -> Thread: self._threads[thread.id] = thread return thread - def _remove_member(self, member: Snowflake, /) -> None: - self._members.pop(member.id, None) - def _add_scheduled_event(self, event: ScheduledEvent, /) -> None: self._scheduled_events[event.id] = event @@ -407,7 +393,7 @@ def __repr__(self) -> str: inner = " ".join("%s=%r" % t for t in attrs) return f"" - def _update_voice_state( + async def _update_voice_state( self, data: GuildVoiceState, channel_id: int ) -> tuple[Member | None, VoiceState, VoiceState]: user_id = int(data["user_id"]) @@ -420,17 +406,17 @@ def _update_voice_state( after = self._voice_states[user_id] before = copy.copy(after) - after._update(data, channel) + await after._update(data, channel) except KeyError: # if we're here then we're getting added into the cache after = VoiceState(data=data, channel=channel) before = VoiceState(data=data, channel=None) self._voice_states[user_id] = after - member = self.get_member(user_id) + member = await self.get_member(user_id) if member is None: try: - member = Member(data=data["member"], state=self._state, guild=self) + member = await Member._from_data(data=data["member"], state=self._state, guild=self) except KeyError: member = None @@ -459,7 +445,20 @@ def _remove_role(self, role_id: int, /) -> Role: return role - def _from_data(self, guild: GuildPayload) -> None: + @classmethod + async def _from_data(cls, guild: GuildPayload, state: ConnectionState) -> Self: + self = cls() + # NOTE: + # Adding an attribute here and getting an AttributeError saying + # the attr doesn't exist? it has something to do with the order + # of the attr in __slots__ + + self._channels: dict[int, GuildChannel] = {} + self._scheduled_events: dict[int, ScheduledEvent] = {} + self._voice_states: dict[int, VoiceState] = {} + self._threads: dict[int, Thread] = {} + self._sounds: dict[int, SoundboardSound] = {} + self._state = state member_count = guild.get("member_count") # Either the payload includes member_count, or it hasn't been set yet. # Prevents valid _member_count from suddenly changing to None @@ -484,10 +483,14 @@ def _from_data(self, guild: GuildPayload) -> None: self._roles[role.id] = role self.mfa_level: MFALevel = guild.get("mfa_level") - self.emojis: tuple[GuildEmoji, ...] = tuple(map(lambda d: state.store_emoji(self, d), guild.get("emojis", []))) - self.stickers: tuple[GuildSticker, ...] = tuple( - map(lambda d: state.store_sticker(self, d), guild.get("stickers", [])) - ) + emojis = [] + for emoji in guild.get("emojis", []): + emojis.append(await state.store_emoji(self, emoji)) + self.emojis: tuple[GuildEmoji, ...] = tuple(emojis) + stickers = [] + for sticker in guild.get("stickers", []): + stickers.append(await state.store_sticker(self, sticker)) + self.stickers: tuple[GuildSticker, ...] = tuple(stickers) self.features: list[GuildFeature] = guild.get("features", []) self._splash: str | None = guild.get("splash") self._system_channel_id: int | None = get_as_snowflake(guild, "system_channel_id") @@ -515,13 +518,13 @@ def _from_data(self, guild: GuildPayload) -> None: cache_joined = self._state.member_cache_flags.joined self_id = self._state.self_id for mdata in guild.get("members", []): - member = Member(data=mdata, guild=self, state=state) + member = await Member._from_data(data=mdata, guild=self, state=state) if cache_joined or member.id == self_id: - self._add_member(member) + await self._add_member(member) events = [] for event in guild.get("guild_scheduled_events", []): - creator = None if not event.get("creator", None) else self.get_member(event.get("creator_id")) + creator = None if not event.get("creator", None) else await self.get_member(event.get("creator_id")) events.append(ScheduledEvent(state=self._state, guild=self, creator=creator, data=event)) self._scheduled_events_from_list(events) @@ -532,7 +535,7 @@ def _from_data(self, guild: GuildPayload) -> None: self.afk_channel: VoiceChannel | None = self.get_channel(get_as_snowflake(guild, "afk_channel_id")) # type: ignore for obj in guild.get("voice_states", []): - self._update_voice_state(obj, int(obj["channel_id"])) + await self._update_voice_state(obj, int(obj["channel_id"])) for sound in guild.get("soundboard_sounds", []): sound = SoundboardSound(state=state, http=state.http, data=sound) @@ -542,6 +545,7 @@ def _from_data(self, guild: GuildPayload) -> None: self.incidents_data: IncidentsData | None = ( IncidentsData(data=incidents_payload) if incidents_payload is not None else None ) + return self def _add_sound(self, sound: SoundboardSound) -> None: self._sounds[sound.id] = sound @@ -711,15 +715,16 @@ def jump_url(self) -> str: """ return f"https://discord.com/channels/{self.id}" - @property - def large(self) -> bool: + async def is_large(self) -> bool: """Indicates if the guild is a 'large' guild. A large guild is defined as having more than ``large_threshold`` count members, which for this library is set to the maximum of 250. """ if self._large is None: - return (self._member_count or len(self._members)) >= 250 + return ( + self._member_count or len(await cast(ConnectionState, self._state).cache.get_guild_members(self.id)) + ) >= 250 return self._large @property @@ -756,14 +761,13 @@ def forum_channels(self) -> list[ForumChannel]: r.sort(key=lambda c: (c.position or -1, c.id)) return r - @property - def me(self) -> Member: + async def get_me(self) -> Member: """Similar to :attr:`Client.user` except an instance of :class:`Member`. This is essentially used to get the member version of yourself. """ self_id = self._state.user.id # The self member is *always* cached - return self.get_member(self_id) # type: ignore + return await self.get_member(self_id) # type: ignore @property def voice_client(self) -> VoiceClient | None: @@ -969,12 +973,11 @@ def filesize_limit(self) -> int: """The maximum number of bytes files can have when uploaded to this guild.""" return self._PREMIUM_GUILD_LIMITS[self.premium_tier].filesize - @property - def members(self) -> list[Member]: + async def get_members(self) -> list[Member]: """A list of members that belong to this guild.""" - return list(self._members.values()) + return await cast(ConnectionState, self._state).cache.get_guild_members(self.id) - def get_member(self, user_id: int, /) -> Member | None: + async def get_member(self, user_id: int, /) -> Member | None: """Returns a member with the given ID. Parameters @@ -987,7 +990,7 @@ def get_member(self, user_id: int, /) -> Member | None: Optional[:class:`Member`] The member or ``None`` if not found. """ - return self._members.get(user_id) + return await cast(ConnectionState, self._state).cache.get_member(self.id, user_id) @property def premium_subscribers(self) -> list[Member]: @@ -1074,10 +1077,9 @@ def get_stage_instance(self, stage_instance_id: int, /) -> StageInstance | None: """ return self._stage_instances.get(stage_instance_id) - @property - def owner(self) -> Member | None: + async def get_owner(self) -> Member | None: """The member that owns the guild.""" - return self.get_member(self.owner_id) # type: ignore + return await self.get_member(self.owner_id) # type: ignore @property def icon(self) -> Asset | None: @@ -1118,8 +1120,7 @@ def member_count(self) -> int: """ return self._member_count - @property - def chunked(self) -> bool: + async def is_chunked(self) -> bool: """Returns a boolean indicating if the guild is "chunked". A chunked guild means that :attr:`member_count` is equal to the @@ -1130,7 +1131,7 @@ def chunked(self) -> bool: """ if self._member_count is None: return False - return self._member_count == len(self._members) + return self._member_count == len(await cast(ConnectionState, self._state).cache.get_guild_members(self.id)) @property def shard_id(self) -> int: @@ -1362,6 +1363,7 @@ async def create_text_channel( **options, ) channel = TextChannel(state=self._state, guild=self, data=data) + await channel._update() # temporarily add to the cache self._channels[channel.id] = channel @@ -2160,7 +2162,7 @@ async def edit( fields["features"] = features data = await http.edit_guild(self.id, reason=reason, **fields) - return Guild(data=data, state=self._state) + return Guild._from_data(data=data, state=self._state) async def fetch_channels(self) -> Sequence[GuildChannel]: """|coro| @@ -2308,7 +2310,7 @@ async def search_members(self, query: str, *, limit: int = 1000) -> list[Member] """ data = await self._state.http.search_members(self.id, query, limit) - return [Member(data=m, guild=self, state=self._state) for m in data] + return [await Member._from_data(data=m, guild=self, state=self._state) for m in data] async def fetch_member(self, member_id: int, /) -> Member: """|coro| @@ -2338,7 +2340,7 @@ async def fetch_member(self, member_id: int, /) -> Member: Fetching the member failed. """ data = await self._state.http.get_member(self.id, member_id) - return Member(data=data, state=self._state, guild=self) + return await Member._from_data(data=data, state=self._state, guild=self) async def fetch_ban(self, user: Snowflake) -> BanEntry: """|coro| @@ -2564,10 +2566,10 @@ async def templates(self) -> list[Template]: Forbidden You don't have permissions to get the templates. """ - from .template import Template # noqa: PLC0415 + from .template import Template data = await self._state.http.guild_templates(self.id) - return [Template(data=d, state=self._state) for d in data] + return [await Template.from_data(data=d, state=self._state) for d in data] async def webhooks(self) -> list[Webhook]: """|coro| @@ -2587,7 +2589,7 @@ async def webhooks(self) -> list[Webhook]: You don't have permissions to get the webhooks. """ - from .webhook import Webhook # noqa: PLC0415 + from .webhook import Webhook # circular import data = await self._state.http.guild_webhooks(self.id) return [Webhook.from_state(d, state=self._state) for d in data] @@ -2677,7 +2679,7 @@ async def create_template(self, *, name: str, description: str | utils.Undefined description: :class:`str` The description of the template. """ - from .template import Template # noqa: PLC0415 + from .template import Template # circular import payload = {"name": name} @@ -2686,7 +2688,7 @@ async def create_template(self, *, name: str, description: str | utils.Undefined data = await self._state.http.create_template(self.id, payload) - return Template(state=self._state, data=data) + return await Template.from_data(state=self._state, data=data) async def create_integration(self, *, type: str, id: int) -> None: """|coro| @@ -2991,7 +2993,7 @@ async def create_custom_emoji( img = bytes_to_base64_data(image) role_ids = [role.id for role in roles] if roles else [] data = await self._state.http.create_custom_emoji(self.id, name, img, roles=role_ids, reason=reason) - return self._state.store_emoji(self, data) + return await self._state.store_emoji(self, data) async def delete_emoji(self, emoji: Snowflake, *, reason: str | None = None) -> None: """|coro| @@ -3513,7 +3515,7 @@ async def vanity_invite(self) -> Invite | None: return Invite(state=self._state, data=payload, guild=self, channel=channel) # TODO: use MISSING when async iterators get refactored - def audit_logs( + async def audit_logs( self, *, limit: int | None = 100, @@ -3564,12 +3566,12 @@ def audit_logs( Getting the first 100 entries: :: async for entry in guild.audit_logs(limit=100): - print(f"{entry.user} did {entry.action} to {entry.target}") + print(f"{entry.user} did {entry.action} to {await entry.get_target()}") Getting entries for a specific action: :: async for entry in guild.audit_logs(action=discord.AuditLogAction.ban): - print(f"{entry.user} banned {entry.target}") + print(f"{entry.user} banned {await entry.get_target()}") Getting entries made by a specific user: :: @@ -3909,7 +3911,7 @@ async def fetch_scheduled_events(self, *, with_user_count: bool = True) -> list[ data = await self._state.http.get_scheduled_events(self.id, with_user_count=with_user_count) result = [] for event in data: - creator = None if not event.get("creator", None) else self.get_member(event.get("creator_id")) + creator = None if not event.get("creator", None) else await self.get_member(event.get("creator_id")) result.append(ScheduledEvent(state=self._state, guild=self, creator=creator, data=event)) self._scheduled_events_from_list(result) @@ -3949,7 +3951,7 @@ async def fetch_scheduled_event(self, event_id: int, /, *, with_user_count: bool data = await self._state.http.get_scheduled_event( guild_id=self.id, event_id=event_id, with_user_count=with_user_count ) - creator = None if not data.get("creator", None) else self.get_member(data.get("creator_id")) + creator = None if not data.get("creator", None) else await self.get_member(data.get("creator_id")) event = ScheduledEvent(state=self._state, guild=self, creator=creator, data=data) old_event = self._scheduled_events.get(event.id) diff --git a/discord/interactions.py b/discord/interactions.py index 455b70b45a..3ab6cbaff5 100644 --- a/discord/interactions.py +++ b/discord/interactions.py @@ -68,6 +68,7 @@ if TYPE_CHECKING: from aiohttp import ClientSession + from .app.state import ConnectionState from .channel import ( CategoryChannel, DMChannel, @@ -82,7 +83,6 @@ from .embeds import Embed from .mentions import AllowedMentions from .poll import Poll - from .state import ConnectionState from .threads import Thread from .types.interactions import Interaction as InteractionPayload from .types.interactions import InteractionCallback as InteractionCallbackPayload @@ -201,6 +201,7 @@ class Interaction: "command", "view", "modal", + "_data", "attachment_size_limit", "_channel_data", "_message_data", @@ -219,12 +220,14 @@ class Interaction: def __init__(self, *, data: InteractionPayload, state: ConnectionState): self._state: ConnectionState = state + self._data = data self._session: ClientSession = state.http._HTTPClient__session self._original_response: InteractionMessage | None = None self.callback: InteractionCallback | None = None - self._from_data(data) - def _from_data(self, data: InteractionPayload): + async def load_data(self): + data = self._data + self.id: int = int(data["id"]) self.type: InteractionType = try_enum(InteractionType, data["type"]) self.data: InteractionData | None = data.get("data") @@ -263,11 +266,11 @@ def _from_data(self, data: InteractionPayload): self._guild: Guild | None = None self._guild_data = data.get("guild") if self.guild is None and self._guild_data: - self._guild = Guild(data=self._guild_data, state=self._state) + self._guild = await Guild._from_data(data=self._guild_data, state=self._state) # TODO: there's a potential data loss here if self.guild_id: - guild = self.guild or self._state._get_guild(self.guild_id) or Object(id=self.guild_id) + guild = self.guild or await self._state._get_guild(self.guild_id) or Object(id=self.guild_id) try: member = data["member"] # type: ignore except KeyError: @@ -276,9 +279,9 @@ def _from_data(self, data: InteractionPayload): self._permissions = int(member.get("permissions", 0)) if not isinstance(guild, Object): cache_flag = self._state.member_cache_flags.interaction - self.user = guild._get_and_update_member(member, int(member["user"]["id"]), cache_flag) + self.user = await guild._get_and_update_member(member, int(member["user"]["id"]), cache_flag) else: - self.user = Member(state=self._state, data=member, guild=guild) + self.user = await Member._from_data(state=self._state, data=member, guild=guild) else: try: self.user = User(state=self._state, data=data["user"]) @@ -302,7 +305,7 @@ def _from_data(self, data: InteractionPayload): self._channel_data = channel if message_data := data.get("message"): - self.message = Message(state=self._state, channel=self.channel, data=message_data) + self.message = await Message._from_data(state=self._state, channel=self.channel, data=message_data) self._message_data = message_data @@ -311,12 +314,11 @@ def client(self) -> Client: """Returns the client that sent the interaction.""" return self._state._get_client() - @property - def guild(self) -> Guild | None: + async def get_guild(self) -> Guild | None: """The guild the interaction was sent from.""" if self._guild: return self._guild - return self._state and self._state._get_guild(self.guild_id) + return self._state and await self._state._get_guild(self.guild_id) @property def created_at(self) -> datetime.datetime: @@ -592,7 +594,7 @@ async def edit_original_response( view.message = message view.refresh(message.components) if view.is_dispatchable(): - self._state.store_view(view, message.id) + await self._state.store_view(view, message.id) if delete_after is not None: await self.delete_original_response(delay=delete_after) @@ -1153,7 +1155,7 @@ async def edit_message( payload["attachments"] = [a.to_dict() for a in attachments] if view is not MISSING: - state.prevent_view_updates_for(message_id) + await state.prevent_view_updates_for(message_id) payload["components"] = [] if view is None else view.to_components() if file is not MISSING and files is not MISSING: @@ -1212,7 +1214,7 @@ async def edit_message( if view and not view.is_finished(): view.message = msg - state.store_view(view, message_id) + await state.store_view(view, message_id) self._responded = True await self._process_callback_response(callback_response) @@ -1304,7 +1306,7 @@ async def send_modal(self, modal: Modal) -> Interaction: ) self._responded = True await self._process_callback_response(callback_response) - self._parent._state.store_modal(modal, self._parent.user.id) + await self._parent._state.store_modal(modal, int(self._parent._data["user"]["id"])) # type: ignore return self._parent @deprecated("a button with type ButtonType.premium", "2.6") @@ -1382,8 +1384,8 @@ def __init__(self, interaction: Interaction, parent: ConnectionState): self._interaction: Interaction = interaction self._parent: ConnectionState = parent - def _get_guild(self, guild_id): - return self._parent._get_guild(guild_id) + async def _get_guild(self, guild_id): + return await self._parent._get_guild(guild_id) def store_user(self, data): return self._parent.store_user(data) @@ -1593,8 +1595,6 @@ class InteractionMetadata: "interacted_message_id", "triggering_interaction_metadata", "_state", - "_cs_original_response_message", - "_cs_interacted_message", ) def __init__(self, *, data: InteractionMetadataPayload, state: ConnectionState): @@ -1614,23 +1614,21 @@ def __init__(self, *, data: InteractionMetadataPayload, state: ConnectionState): def __repr__(self): return f"" - @cached_slot_property("_cs_original_response_message") - def original_response_message(self) -> Message | None: + async def get_original_response_message(self) -> Message | None: """Optional[:class:`Message`]: The original response message. Returns ``None`` if the message is not in cache, or if :attr:`original_response_message_id` is ``None``. """ if not self.original_response_message_id: return None - return self._state._get_message(self.original_response_message_id) + return await self._state._get_message(self.original_response_message_id) - @cached_slot_property("_cs_interacted_message") - def interacted_message(self) -> Message | None: + async def get_interacted_message(self) -> Message | None: """Optional[:class:`Message`]: The message that triggered the interaction. Returns ``None`` if the message is not in cache, or if :attr:`interacted_message_id` is ``None``. """ if not self.interacted_message_id: return None - return self._state._get_message(self.interacted_message_id) + return await self._state._get_message(self.interacted_message_id) class AuthorizingIntegrationOwners: @@ -1648,7 +1646,7 @@ class AuthorizingIntegrationOwners: from the user in the bot's DMs. """ - __slots__ = ("user_id", "guild_id", "_state", "_cs_user", "_cs_guild") + __slots__ = ("user_id", "guild_id", "_state") def __init__(self, data: dict[str, Any], state: ConnectionState): self._state = state @@ -1669,23 +1667,21 @@ def __eq__(self, other): def __ne__(self, other): return not self.__eq__(other) - @cached_slot_property("_cs_user") - def user(self) -> User | None: + async def get_user(self) -> User | None: """Optional[:class:`User`]: The user that authorized the integration. Returns ``None`` if the user is not in cache, or if :attr:`user_id` is ``None``. """ if not self.user_id: return None - return self._state.get_user(self.user_id) + return await self._state.get_user(self.user_id) - @cached_slot_property("_cs_guild") - def guild(self) -> Guild | None: + async def get_guild(self) -> Guild | None: """Optional[:class:`Guild`]: The guild that authorized the integration. Returns ``None`` if the guild is not in cache, or if :attr:`guild_id` is ``0`` or ``None``. """ if not self.guild_id: return None - return self._state._get_guild(self.guild_id) + return await self._state._get_guild(self.guild_id) class InteractionCallback: diff --git a/discord/invite.py b/discord/invite.py index 28771d6048..83f53fa16e 100644 --- a/discord/invite.py +++ b/discord/invite.py @@ -43,9 +43,9 @@ if TYPE_CHECKING: from .abc import GuildChannel + from .app.state import ConnectionState from .guild import Guild from .scheduled_events import ScheduledEvent - from .state import ConnectionState from .types.channel import PartialChannel as InviteChannelPayload from .types.invite import GatewayInvite as GatewayInvitePayload from .types.invite import Invite as InvitePayload @@ -389,7 +389,7 @@ def __init__( ) @classmethod - def from_incomplete(cls: type[I], *, state: ConnectionState, data: InvitePayload) -> I: + async def from_incomplete(cls: type[I], *, state: ConnectionState, data: InvitePayload) -> I: guild: Guild | PartialInviteGuild | None try: guild_data = data["guild"] @@ -398,7 +398,7 @@ def from_incomplete(cls: type[I], *, state: ConnectionState, data: InvitePayload guild = None else: guild_id = int(guild_data["id"]) - guild = state._get_guild(guild_id) + guild = await state._get_guild(guild_id) if guild is None: # If it's not cached, then it has to be a partial guild guild = PartialInviteGuild(state, guild_data, guild_id) @@ -413,9 +413,9 @@ def from_incomplete(cls: type[I], *, state: ConnectionState, data: InvitePayload return cls(state=state, data=data, guild=guild, channel=channel) @classmethod - def from_gateway(cls: type[I], *, state: ConnectionState, data: GatewayInvitePayload) -> I: + async def from_gateway(cls: type[I], *, state: ConnectionState, data: GatewayInvitePayload) -> I: guild_id: int | None = get_as_snowflake(data, "guild_id") - guild: Guild | Object | None = state._get_guild(guild_id) + guild: Guild | Object | None = await state._get_guild(guild_id) channel_id = int(data["channel_id"]) if guild is not None: channel = guild.get_channel(channel_id) or Object(id=channel_id) # type: ignore diff --git a/discord/iterators.py b/discord/iterators.py index a8957ee716..d61cbd2695 100644 --- a/discord/iterators.py +++ b/discord/iterators.py @@ -225,7 +225,7 @@ async def fill_users(self): await self.users.put(User(state=self.state, data=element)) else: member_id = int(element["id"]) - member = self.guild.get_member(member_id) + member = await self.guild.get_member(member_id) if member is not None: await self.users.put(member) else: @@ -280,7 +280,7 @@ async def fill_users(self): await self.users.put(User(state=self.state, data=element)) else: member_id = int(element["id"]) - member = self.guild.get_member(member_id) + member = await self.guild.get_member(member_id) if member is not None: await self.users.put(member) else: @@ -610,10 +610,10 @@ def _get_retrieve(self): self.retrieve = r return r > 0 - def create_guild(self, data): + async def create_guild(self, data): from .guild import Guild # noqa: PLC0415 - return Guild(state=self.state, data=data) + return await Guild._from_data(state=self.state, data=data) async def fill_guilds(self): if self._get_retrieve(): @@ -625,7 +625,7 @@ async def fill_guilds(self): data = filter(self._filter, data) for element in data: - await self.guilds.put(self.create_guild(element)) + await self.guilds.put(await self.create_guild(element)) async def _retrieve_guilds(self, retrieve) -> list[Guild]: """Retrieve guilds and update next parameters.""" @@ -698,12 +698,12 @@ async def fill_members(self): self.after = Object(id=int(data[-1]["user"]["id"])) for element in reversed(data): - await self.members.put(self.create_member(element)) + await self.members.put(await self.create_member(element)) - def create_member(self, data): + async def create_member(self, data): from .member import Member # noqa: PLC0415 - return Member(data=data, guild=self.guild, state=self.state) + return await Member._from_data(data=data, guild=self.guild, state=self.state) class BanIterator(_AsyncIterator["BanEntry"]): @@ -894,7 +894,7 @@ def _get_retrieve(self): self.retrieve = r return r > 0 - def member_from_payload(self, data): + async def member_from_payload(self, data): from .member import Member # noqa: PLC0415 user = data.pop("user") @@ -902,7 +902,7 @@ def member_from_payload(self, data): member = data.pop("member") member["user"] = user - return Member(data=member, guild=self.event.guild, state=self.event._state) + return await Member._from_data(data=member, guild=self.event.guild, state=self.event._state) def user_from_payload(self, data): from .user import User # noqa: PLC0415 @@ -936,7 +936,7 @@ async def fill_subs(self): for element in reversed(data): if "member" in element: - await self.subscribers.put(self.member_from_payload(element)) + await self.subscribers.put(await self.member_from_payload(element)) else: await self.subscribers.put(self.user_from_payload(element)) diff --git a/discord/member.py b/discord/member.py index eeb50dae9c..7e411884b7 100644 --- a/discord/member.py +++ b/discord/member.py @@ -32,6 +32,8 @@ from operator import attrgetter from typing import TYPE_CHECKING, Any, TypeVar, Union +from typing_extensions import Self + import discord.abc from . import utils @@ -55,12 +57,12 @@ if TYPE_CHECKING: from .abc import Snowflake + from .app.state import ConnectionState from .channel import DMChannel, StageChannel, VoiceChannel from .flags import PublicUserFlags from .guild import Guild from .message import Message from .role import Role - from .state import ConnectionState from .types.activity import PartialPresenceUpdate from .types.member import Member as MemberPayload from .types.member import MemberWithUser as MemberWithUserPayload @@ -138,7 +140,7 @@ def __init__( self.session_id: str = data.get("session_id") self._update(data, channel) - def _update( + async def _update( self, data: VoiceStatePayload | GuildVoiceStatePayload, channel: VocalGuildChannel | None, @@ -313,7 +315,6 @@ class Member(discord.abc.Messageable, _UserTag): def __init__(self, *, data: MemberWithUserPayload, guild: Guild, state: ConnectionState): self._state: ConnectionState = state - self._user: User = state.store_user(data["user"]) self.guild: Guild = guild self.joined_at: datetime.datetime | None = parse_time(data.get("joined_at")) self.premium_since: datetime.datetime | None = parse_time(data.get("premium_since")) @@ -329,6 +330,12 @@ def __init__(self, *, data: MemberWithUserPayload, guild: Guild, state: Connecti ) self.flags: MemberFlags = MemberFlags._from_value(data.get("flags", 0)) + @classmethod + async def _from_data(cls, data: MemberWithUserPayload, guild: Guild, state: ConnectionState) -> Self: + self = cls(data=data, guild=guild, state=state) + self._user = await state.store_user(data["user"]) + return self + def __str__(self) -> str: return str(self._user) @@ -415,7 +422,7 @@ async def _get_channel(self): ch = await self.create_dm() return ch - def _update(self, data: MemberPayload) -> None: + async def _update(self, data: MemberPayload) -> None: # the nickname change is optional, # if it isn't in the payload then it didn't change try: @@ -951,7 +958,7 @@ async def edit( else: return None - return Member(data=data, guild=self.guild, state=self._state) + return await Member._from_data(data=data, guild=self.guild, state=self._state) async def timeout(self, until: datetime.datetime | None, *, reason: str | None = None) -> None: """|coro| diff --git a/discord/message.py b/discord/message.py index 9c140538ca..e6aa2e15ad 100644 --- a/discord/message.py +++ b/discord/message.py @@ -28,6 +28,7 @@ import datetime import io import re +from inspect import isawaitable from os import PathLike from typing import ( TYPE_CHECKING, @@ -41,6 +42,8 @@ ) from urllib.parse import parse_qs, urlparse +from typing_extensions import Self + from . import utils from .channel import PartialMessageable from .components import _component_factory @@ -69,12 +72,12 @@ PartialMessageableChannel, Snowflake, ) + from .app.state import ConnectionState from .channel import TextChannel from .components import Component from .interactions import MessageInteraction from .mentions import AllowedMentions from .role import Role - from .state import ConnectionState from .types.components import Component as ComponentPayload from .types.embed import Embed as EmbedPayload from .types.member import Member as MemberPayload @@ -591,10 +594,9 @@ def from_message( self._state = message._state return self - @property - def cached_message(self) -> Message | None: + async def get_cached_message(self) -> Message | None: """The cached message, if found in the internal message cache.""" - return self._state and self._state._get_message(self.message_id) + return self._state and await self._state._get_message(self.message_id) @property def jump_url(self) -> str: @@ -636,14 +638,13 @@ def __init__(self, state: ConnectionState, data: MessageCallPayload): self._participants: SnowflakeList = data.get("participants", []) self._ended_timestamp: datetime.datetime | None = parse_time(data["ended_timestamp"]) - @property - def participants(self) -> list[User | Object]: + async def get_participants(self) -> list[User | Object]: """A list of :class:`User` that participated in this call. If a user is not found in the client's cache, then it will be returned as an :class:`Object`. """ - return [self._state.get_user(int(i)) or Object(i) for i in self._participants] + return [await self._state.get_user(int(i)) or Object(i) for i in self._participants] @property def ended_at(self) -> datetime.datetime | None: @@ -755,21 +756,6 @@ def __repr__(self) -> str: return f"" -def flatten_handlers(cls): - prefix = len("_handle_") - handlers = [ - (key[prefix:], value) - for key, value in cls.__dict__.items() - if key.startswith("_handle_") and key != "_handle_member" - ] - - # store _handle_member last - handlers.append(("member", cls._handle_member)) - cls._HANDLERS = handlers - cls._CACHED_SLOTS = [attr for attr in cls.__slots__ if attr.startswith("_cs_")] - return cls - - class MessagePin: """Represents information about a pinned message. @@ -800,7 +786,6 @@ def __repr__(self) -> str: return f"" -@flatten_handlers class Message(Hashable): r"""Represents a message from Discord. @@ -992,39 +977,41 @@ class Message(Hashable): author: User | Member role_mentions: list[Role] - def __init__( - self, + @classmethod + async def _from_data( + cls, *, state: ConnectionState, channel: MessageableChannel, data: MessagePayload, - ): - self._state: ConnectionState = state - self._raw_data: MessagePayload = data - self.id: int = int(data["id"]) - self.webhook_id: int | None = get_as_snowflake(data, "webhook_id") - self.reactions: list[Reaction] = [Reaction(message=self, data=d) for d in data.get("reactions", [])] - self.attachments: list[Attachment] = [Attachment(data=a, state=self._state) for a in data["attachments"]] - self.embeds: list[Embed] = [Embed.from_dict(a) for a in data["embeds"]] - self.application: MessageApplicationPayload | None = data.get("application") - self.activity: MessageActivityPayload | None = data.get("activity") - self.channel: MessageableChannel = channel - self._edited_timestamp: datetime.datetime | None = parse_time(data["edited_timestamp"]) - self.type: MessageType = try_enum(MessageType, data["type"]) - self.pinned: bool = data["pinned"] - self.flags: MessageFlags = MessageFlags._from_value(data.get("flags", 0)) - self.mention_everyone: bool = data["mention_everyone"] - self.tts: bool = data["tts"] - self.content: str = data["content"] - self.nonce: int | str | None = data.get("nonce") - self.stickers: list[StickerItem] = [StickerItem(data=d, state=state) for d in data.get("sticker_items", [])] - self.components: list[Component] = [_component_factory(d, state=state) for d in data.get("components", [])] + ) -> Self: + self = cls() + self._state = state + self._raw_data = data + self.id = int(data["id"]) + self.webhook_id = get_as_snowflake(data, "webhook_id") + self.reactions = [Reaction(message=self, data=d) for d in data.get("reactions", [])] + self.attachments = [Attachment(data=a, state=self._state) for a in data["attachments"]] + self.embeds = [Embed.from_dict(a) for a in data["embeds"]] + self.application = data.get("application") + self.activity = data.get("activity") + self.channel = channel + self._edited_timestamp = parse_time(data["edited_timestamp"]) + self.type = try_enum(MessageType, data["type"]) + self.pinned = data["pinned"] + self.flags = MessageFlags._from_value(data.get("flags", 0)) + self.mention_everyone = data["mention_everyone"] + self.tts = data["tts"] + self.content = data["content"] + self.nonce = data.get("nonce") + self.stickers = [StickerItem(data=d, state=state) for d in data.get("sticker_items", [])] + self.components = [_component_factory(d, state=state) for d in data.get("components", [])] try: # if the channel doesn't have a guild attribute, we handle that self.guild = channel.guild # type: ignore except AttributeError: - self.guild = state._get_guild(get_as_snowflake(data, "guild_id")) + self.guild = await state._get_guild(get_as_snowflake(data, "guild_id")) try: ref = data["message_reference"] @@ -1044,7 +1031,7 @@ def __init__( if ref.channel_id == channel.id: chan = channel else: - chan, _ = state._get_guild_channel(resolved, guild_id=self.guild.id) + chan, _ = await state._get_guild_channel(resolved, guild_id=self.guild.id) # the channel will be the correct type here ref.resolved = self.__class__(channel=chan, data=resolved, state=state) # type: ignore @@ -1062,7 +1049,7 @@ def __init__( except KeyError: self.snapshots = [] - from .interactions import InteractionMetadata, MessageInteraction # noqa: PLC0415 + from .interactions import InteractionMetadata, MessageInteraction # noqa: PLC0415 # circular import self._interaction: MessageInteraction | None try: @@ -1077,7 +1064,7 @@ def __init__( self._poll: Poll | None try: self._poll = Poll.from_dict(data["poll"], self) - self._state.store_poll(self._poll, self.id) + await self._state.store_poll(self._poll, self.id) except KeyError: self._poll = None @@ -1093,11 +1080,40 @@ def __init__( except KeyError: self.call = None - for handler in ("author", "member", "mentions", "mention_roles"): - try: - getattr(self, f"_handle_{handler}")(data[handler]) - except KeyError: - continue + self.author = await self._state.store_user(data["author"]) + if isinstance(self.guild, Guild): + found = await self.guild.get_member(self.author.id) + if found is not None: + self.author = found + + try: + # Update member reference + self.author._update_from_message(member) # type: ignore # noqa: F821 # TODO: member is unbound + except AttributeError: + # It's a user here + # TODO: consider adding to cache here + self.author = Member._from_message(message=self, data=data["member"]) + + self.mentions = r = [] + if not isinstance(self.guild, Guild): + self.mentions = [await state.store_user(m) for m in data["mentions"]] + else: + for mention in filter(None, data["mentions"]): + id_search = int(mention["id"]) + member = await self.guild.get_member(id_search) + if member is not None: + r.append(member) + else: + r.append(Member._try_upgrade(data=mention, guild=self.guild, state=state)) + + self.role_mentions = [] + if isinstance(self.guild, Guild): + for role_id in map(int, data["mention_roles"]): + role = self.guild.get_role(role_id) + if role is not None: + self.role_mentions.append(role) + + return self def __repr__(self) -> str: name = self.__class__.__name__ @@ -1162,116 +1178,6 @@ def _clear_emoji(self, emoji) -> Reaction | None: del self.reactions[index] return reaction - def _update(self, data): - # In an update scheme, 'author' key has to be handled before 'member' - # otherwise they overwrite each other which is undesirable. - # Since there's no good way to do this we have to iterate over every - # handler rather than iterating over the keys which is a little slower - for key, handler in self._HANDLERS: - try: - value = data[key] - except KeyError: - continue - else: - handler(self, value) - - # clear the cached properties - for attr in self._CACHED_SLOTS: - try: - delattr(self, attr) - except AttributeError: - pass - - def _handle_edited_timestamp(self, value: str) -> None: - self._edited_timestamp = parse_time(value) - - def _handle_pinned(self, value: bool) -> None: - self.pinned = value - - def _handle_flags(self, value: int) -> None: - self.flags = MessageFlags._from_value(value) - - def _handle_application(self, value: MessageApplicationPayload) -> None: - self.application = value - - def _handle_activity(self, value: MessageActivityPayload) -> None: - self.activity = value - - def _handle_mention_everyone(self, value: bool) -> None: - self.mention_everyone = value - - def _handle_tts(self, value: bool) -> None: - self.tts = value - - def _handle_type(self, value: int) -> None: - self.type = try_enum(MessageType, value) - - def _handle_content(self, value: str) -> None: - self.content = value - - def _handle_attachments(self, value: list[AttachmentPayload]) -> None: - self.attachments = [Attachment(data=a, state=self._state) for a in value] - - def _handle_embeds(self, value: list[EmbedPayload]) -> None: - self.embeds = [Embed.from_dict(data) for data in value] - - def _handle_nonce(self, value: str | int) -> None: - self.nonce = value - - def _handle_poll(self, value: PollPayload) -> None: - self._poll = Poll.from_dict(value, self) - self._state.store_poll(self._poll, self.id) - - def _handle_author(self, author: UserPayload) -> None: - self.author = self._state.store_user(author) - if isinstance(self.guild, Guild): - found = self.guild.get_member(self.author.id) - if found is not None: - self.author = found - - def _handle_member(self, member: MemberPayload) -> None: - # The gateway now gives us full Member objects sometimes with the following keys - # deaf, mute, joined_at, roles - # For the sake of performance I'm going to assume that the only - # field that needs *updating* would be the joined_at field. - # If there is no Member object (for some strange reason), then we can upgrade - # ourselves to a more "partial" member object. - author = self.author - try: - # Update member reference - author._update_from_message(member) # type: ignore - except AttributeError: - # It's a user here - # TODO: consider adding to cache here - self.author = Member._from_message(message=self, data=member) - - def _handle_mentions(self, mentions: list[UserWithMemberPayload]) -> None: - self.mentions = r = [] - guild = self.guild - state = self._state - if not isinstance(guild, Guild): - self.mentions = [state.store_user(m) for m in mentions] - return - - for mention in filter(None, mentions): - id_search = int(mention["id"]) - member = guild.get_member(id_search) - if member is not None: - r.append(member) - else: - r.append(Member._try_upgrade(data=mention, guild=guild, state=state)) - - def _handle_mention_roles(self, role_mentions: list[int]) -> None: - self.role_mentions = [] - if isinstance(self.guild, Guild): - for role_id in map(int, role_mentions): - role = self.guild.get_role(role_id) - if role is not None: - self.role_mentions.append(role) - - def _handle_components(self, components: list[ComponentPayload]): - self.components = [_component_factory(d, state=self._state) for d in components] - def _rebind_cached_references(self, new_guild: Guild, new_channel: TextChannel | Thread) -> None: self.guild = new_guild self.channel = new_channel @@ -1700,7 +1606,7 @@ async def edit( payload["attachments"] = [a.to_dict() for a in attachments] if view is not MISSING: - self._state.prevent_view_updates_for(self.id) + await self._state.prevent_view_updates_for(self.id) payload["components"] = view.to_components() if view else [] if view and view.is_components_v2(): flags.is_components_v2 = True @@ -1736,13 +1642,13 @@ async def edit( f.close() else: data = await self._state.http.edit_message(self.channel.id, self.id, **payload) - message = Message(state=self._state, channel=self.channel, data=data) + message = await Message._from_data(state=self._state, channel=self.channel, data=data) if view and not view.is_finished(): view.message = message view.refresh(message.components) if view.is_dispatchable(): - self._state.store_view(view, self.id) + await self._state.store_view(view, self.id) if delete_after is not None: await self.delete(delay=delete_after) @@ -2085,7 +1991,7 @@ async def end_poll(self) -> Message: self.channel.id, self.id, ) - message = Message(state=self._state, channel=self.channel, data=data) + message = await Message._from_data(state=self._state, channel=self.channel, data=data) return message @@ -2204,7 +2110,7 @@ def __init__(self, *, channel: PartialMessageableChannel, id: int): self._state: ConnectionState = channel._state self.id: int = id - def _update(self, data) -> None: + async def _update(self, data) -> None: # This is used for duck typing purposes. # Just do nothing with the data. pass @@ -2348,7 +2254,7 @@ async def edit(self, **fields: Any) -> Message | None: view = fields.pop("view", MISSING) if view is not MISSING: - self._state.prevent_view_updates_for(self.id) + await self._state.prevent_view_updates_for(self.id) fields["components"] = view.to_components() if view else [] if fields: @@ -2364,7 +2270,7 @@ async def edit(self, **fields: Any) -> Message | None: view.message = msg view.refresh(msg.components) if view.is_dispatchable(): - self._state.store_view(view, self.id) + await self._state.store_view(view, self.id) return msg async def end_poll(self) -> Message: diff --git a/discord/monetization.py b/discord/monetization.py index 18b55894d0..8f708b47e6 100644 --- a/discord/monetization.py +++ b/discord/monetization.py @@ -38,7 +38,7 @@ from datetime import datetime from .abc import Snowflake, SnowflakeTime - from .state import ConnectionState + from .app.state import ConnectionState from .types.monetization import SKU as SKUPayload from .types.monetization import Entitlement as EntitlementPayload from .types.monetization import Subscription as SubscriptionPayload @@ -337,7 +337,6 @@ def __repr__(self) -> str: def __eq__(self, other: object) -> bool: return isinstance(other, self.__class__) and other.id == self.id - @property - def user(self): + async def get_user(self): """Optional[:class:`User`]: The user that owns this subscription.""" - return self._state.get_user(self.user_id) + return await self._state.get_user(self.user_id) diff --git a/discord/onboarding.py b/discord/onboarding.py index d79fa6b07e..83c52466c5 100644 --- a/discord/onboarding.py +++ b/discord/onboarding.py @@ -243,7 +243,7 @@ def __init__(self, data: OnboardingPayload, guild: Guild): def __repr__(self): return f"" - def _update(self, data: OnboardingPayload): + async def _update(self, data: OnboardingPayload): self.guild_id: Snowflake = data["guild_id"] self.prompts: list[OnboardingPrompt] = [ OnboardingPrompt._from_dict(prompt, self.guild) for prompt in data.get("prompts", []) diff --git a/discord/partial_emoji.py b/discord/partial_emoji.py index 1244cb4353..6d6a62187e 100644 --- a/discord/partial_emoji.py +++ b/discord/partial_emoji.py @@ -38,7 +38,7 @@ if TYPE_CHECKING: from datetime import datetime - from .state import ConnectionState + from .app.state import ConnectionState from .types.message import PartialEmoji as PartialEmojiPayload diff --git a/discord/poll.py b/discord/poll.py index 122d131066..278baaf047 100644 --- a/discord/poll.py +++ b/discord/poll.py @@ -92,12 +92,12 @@ def to_dict(self) -> PollMediaPayload: return dict_ @classmethod - def from_dict(cls, data: PollMediaPayload, message: Message | PartialMessage | None = None) -> PollMedia: + async def from_dict(cls, data: PollMediaPayload, message: Message | PartialMessage | None = None) -> PollMedia: _emoji: dict[str, Any] = data.get("emoji") or {} if isinstance(_emoji, dict) and _emoji.get("name"): emoji = PartialEmoji.from_dict(_emoji) if emoji.id and message: - emoji = message._state.get_emoji(emoji.id) or emoji + emoji = (await message._state.get_emoji(emoji.id)) or emoji else: emoji = _emoji or None return cls( diff --git a/discord/raw_models.py b/discord/raw_models.py index 4f9e207ca8..9a91c3ce35 100644 --- a/discord/raw_models.py +++ b/discord/raw_models.py @@ -28,6 +28,8 @@ import datetime from typing import TYPE_CHECKING +from typing_extensions import Self + from .automod import AutoModAction, AutoModTriggerType from .enums import ( AuditLogAction, @@ -39,12 +41,12 @@ if TYPE_CHECKING: from .abc import MessageableChannel + from .app.state import ConnectionState from .guild import Guild from .member import Member from .message import Message from .partial_emoji import PartialEmoji from .soundboard import PartialSoundboardSound, SoundboardSound - from .state import ConnectionState from .threads import Thread from .types.channel import VoiceChannelEffectSendEvent as VoiceChannelEffectSend from .types.raw_models import ( @@ -657,19 +659,21 @@ class AutoModActionExecutionEvent: "data", ) - def __init__(self, state: ConnectionState, data: AutoModActionExecution) -> None: + @classmethod + async def from_data(cls, state: ConnectionState, data: AutoModActionExecution) -> Self: + self = cls() self.action: AutoModAction = AutoModAction.from_dict(data["action"]) self.rule_id: int = int(data["rule_id"]) self.rule_trigger_type: AutoModTriggerType = try_enum(AutoModTriggerType, int(data["rule_trigger_type"])) self.guild_id: int = int(data["guild_id"]) - self.guild: Guild | None = state._get_guild(self.guild_id) + self.guild: Guild | None = await state._get_guild(self.guild_id) self.user_id: int = int(data["user_id"]) self.content: str | None = data.get("content", None) self.matched_keyword: str = data["matched_keyword"] self.matched_content: str | None = data.get("matched_content", None) if self.guild: - self.member: Member | None = self.guild.get_member(self.user_id) + self.member: Member | None = await self.guild.get_member(self.user_id) else: self.member: Member | None = None @@ -684,18 +688,19 @@ def __init__(self, state: ConnectionState, data: AutoModActionExecution) -> None try: self.message_id: int | None = int(data["message_id"]) - self.message: Message | None = state._get_message(self.message_id) + self.message: Message | None = await state._get_message(self.message_id) except KeyError: self.message_id: int | None = None self.message: Message | None = None try: self.alert_system_message_id: int | None = int(data["alert_system_message_id"]) - self.alert_system_message: Message | None = state._get_message(self.alert_system_message_id) + self.alert_system_message: Message | None = await state._get_message(self.alert_system_message_id) except KeyError: self.alert_system_message_id: int | None = None self.alert_system_message: Message | None = None self.data: AutoModActionExecution = data + return self def __repr__(self) -> str: return ( diff --git a/discord/role.py b/discord/role.py index f65bd9fad5..9a1d69d3eb 100644 --- a/discord/role.py +++ b/discord/role.py @@ -44,9 +44,9 @@ if TYPE_CHECKING: import datetime + from .app.state import ConnectionState from .guild import Guild from .member import Member - from .state import ConnectionState from .types.guild import RolePositionUpdate from .types.role import Role as RolePayload from .types.role import RoleColours as RoleColoursPayload @@ -376,7 +376,7 @@ def __ge__(self: R, other: R) -> bool: return NotImplemented return not r - def _update(self, data: RolePayload): + async def _update(self, data: RolePayload): self.name: str = data["name"] self._permissions: int = int(data.get("permissions", 0)) self.position: int = data.get("position", 0) diff --git a/discord/scheduled_events.py b/discord/scheduled_events.py index d2af4b770e..0f657fca84 100644 --- a/discord/scheduled_events.py +++ b/discord/scheduled_events.py @@ -48,10 +48,10 @@ if TYPE_CHECKING: from .abc import Snowflake + from .app.state import ConnectionState from .guild import Guild from .iterators import AsyncIterator from .member import Member - from .state import ConnectionState from .types.channel import StageChannel, VoiceChannel from .types.scheduled_events import ScheduledEvent as ScheduledEventPayload @@ -90,12 +90,12 @@ def __init__( self, *, state: ConnectionState, - value: str | int | StageChannel | VoiceChannel, + value: str | Object, ): self._state = state self.value: str | StageChannel | VoiceChannel | Object if isinstance(value, int): - self.value = self._state.get_channel(id=int(value)) or Object(id=int(value)) + self.value = Object(id=int(value)) else: self.value = value diff --git a/discord/shard.py b/discord/shard.py index 2e59baa198..dc03ee4859 100644 --- a/discord/shard.py +++ b/discord/shard.py @@ -31,6 +31,7 @@ import aiohttp +from .app.state import AutoShardedConnectionState from .backoff import ExponentialBackoff from .client import Client from .enums import Status @@ -42,14 +43,12 @@ PrivilegedIntentsRequired, ) from .gateway import * -from .state import AutoShardedConnectionState if TYPE_CHECKING: from .activity import BaseActivity from .gateway import DiscordWebSocket EI = TypeVar("EI", bound="EventItem") - __all__ = ( "AutoShardedClient", "ShardInfo", @@ -98,7 +97,7 @@ def __init__( ) -> None: self.ws: DiscordWebSocket = ws self._client: Client = client - self._dispatch: Callable[..., None] = client.dispatch + self._dispatch: Callable[..., None] = client._connection.emitter.emit self._queue_put: Callable[[EventItem], None] = queue_put self.loop: asyncio.AbstractEventLoop = self._client.loop self._disconnect: bool = False @@ -132,11 +131,11 @@ async def close(self) -> None: async def disconnect(self) -> None: await self.close() - self._dispatch("shard_disconnect", self.id) + await self._dispatch("shard_disconnect", self.id) async def _handle_disconnect(self, e: Exception) -> None: - self._dispatch("disconnect") - self._dispatch("shard_disconnect", self.id) + await self._dispatch("disconnect") + await self._dispatch("shard_disconnect", self.id) if not self._reconnect: self._queue_put(EventItem(EventType.close, self, e)) return @@ -187,8 +186,8 @@ async def worker(self) -> None: async def reidentify(self, exc: ReconnectWebSocket) -> None: self._cancel_task() - self._dispatch("disconnect") - self._dispatch("shard_disconnect", self.id) + await self._dispatch("disconnect") + await self._dispatch("shard_disconnect", self.id) _log.info("Got a request to %s the websocket at Shard ID %s.", exc.op, self.id) try: coro = DiscordWebSocket.from_client( @@ -533,11 +532,11 @@ async def change_presence( for shard in self.__shards.values(): await shard.ws.change_presence(activity=activity, status=status_value) - guilds = self._connection.guilds + guilds = await self._connection.get_guilds() else: shard = self.__shards[shard_id] await shard.ws.change_presence(activity=activity, status=status_value) - guilds = [g for g in self._connection.guilds if g.shard_id == shard_id] + guilds = [g for g in await self._connection.get_guilds() if g.shard_id == shard_id] activities = () if activity is None else (activity,) for guild in guilds: diff --git a/discord/stage_instance.py b/discord/stage_instance.py index 8fdc508f41..e5ea31f0e0 100644 --- a/discord/stage_instance.py +++ b/discord/stage_instance.py @@ -36,9 +36,9 @@ __all__ = ("StageInstance",) if TYPE_CHECKING: + from .app.state import ConnectionState from .channel import StageChannel from .guild import Guild - from .state import ConnectionState from .types.channel import StageInstance as StageInstancePayload @@ -88,7 +88,6 @@ class StageInstance(Hashable): "privacy_level", "discoverable_disabled", "scheduled_event", - "_cs_channel", ) def __init__(self, *, state: ConnectionState, guild: Guild, data: StageInstancePayload) -> None: @@ -96,7 +95,7 @@ def __init__(self, *, state: ConnectionState, guild: Guild, data: StageInstanceP self.guild = guild self._update(data) - def _update(self, data: StageInstancePayload): + async def _update(self, data: StageInstancePayload): self.id: int = int(data["id"]) self.channel_id: int = int(data["channel_id"]) self.topic: str = data["topic"] @@ -110,11 +109,10 @@ def _update(self, data: StageInstancePayload): def __repr__(self) -> str: return f"" - @cached_slot_property("_cs_channel") - def channel(self) -> StageChannel | None: + async def get_channel(self) -> StageChannel | None: """The channel that stage instance is running in.""" # the returned channel will always be a StageChannel or None - return self._state.get_channel(self.channel_id) # type: ignore + return await self._state.get_channel(self.channel_id) # type: ignore def is_public(self) -> bool: return False diff --git a/discord/state.py b/discord/state.py deleted file mode 100644 index 177981b76a..0000000000 --- a/discord/state.py +++ /dev/null @@ -1,2108 +0,0 @@ -""" -The MIT License (MIT) - -Copyright (c) 2015-2021 Rapptz -Copyright (c) 2021-present Pycord Development - -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 - -import asyncio -import copy -import inspect -import itertools -import logging -import os -from collections import OrderedDict, deque -from typing import ( - TYPE_CHECKING, - Any, - Callable, - Coroutine, - Deque, - Sequence, - TypeVar, - Union, -) - -from . import utils -from .activity import BaseActivity -from .audit_logs import AuditLogEntry -from .automod import AutoModRule -from .channel import * -from .channel import _channel_factory -from .emoji import AppEmoji, GuildEmoji -from .enums import ChannelType, InteractionType, ScheduledEventStatus, Status, try_enum -from .flags import ApplicationFlags, Intents, MemberCacheFlags -from .guild import Guild -from .integrations import _integration_factory -from .interactions import Interaction -from .invite import Invite -from .member import Member -from .mentions import AllowedMentions -from .message import Message -from .monetization import Entitlement, Subscription -from .object import Object -from .partial_emoji import PartialEmoji -from .poll import Poll, PollAnswerCount -from .raw_models import * -from .role import Role -from .scheduled_events import ScheduledEvent -from .soundboard import PartialSoundboardSound, SoundboardSound -from .stage_instance import StageInstance -from .sticker import GuildSticker -from .threads import Thread, ThreadMember -from .ui.modal import Modal, ModalStore -from .ui.view import View, ViewStore -from .user import ClientUser, User -from .utils.private import get_as_snowflake, parse_time, sane_wait_for - -if TYPE_CHECKING: - from .abc import PrivateChannel - from .client import Client - from .gateway import DiscordWebSocket - from .guild import GuildChannel, VocalGuildChannel - from .http import HTTPClient - from .message import MessageableChannel - from .types.activity import Activity as ActivityPayload - from .types.channel import DMChannel as DMChannelPayload - from .types.emoji import Emoji as EmojiPayload - from .types.guild import Guild as GuildPayload - from .types.message import Message as MessagePayload - from .types.poll import Poll as PollPayload - from .types.sticker import GuildSticker as GuildStickerPayload - from .types.user import User as UserPayload - from .voice_client import VoiceClient - - T = TypeVar("T") - CS = TypeVar("CS", bound="ConnectionState") - Channel = GuildChannel | VocalGuildChannel | PrivateChannel | P | rtialMessageable - - -class ChunkRequest: - def __init__( - self, - guild_id: int, - loop: asyncio.AbstractEventLoop, - resolver: Callable[[int], Any], - *, - cache: bool = True, - ) -> None: - self.guild_id: int = guild_id - self.resolver: Callable[[int], Any] = resolver - self.loop: asyncio.AbstractEventLoop = loop - self.cache: bool = cache - self.nonce: str = os.urandom(16).hex() - self.buffer: list[Member] = [] - self.waiters: list[asyncio.Future[list[Member]]] = [] - - def add_members(self, members: list[Member]) -> None: - self.buffer.extend(members) - if self.cache: - guild = self.resolver(self.guild_id) - if guild is None: - return - - for member in members: - existing = guild.get_member(member.id) - if existing is None or existing.joined_at is None: - guild._add_member(member) - - async def wait(self) -> list[Member]: - future = self.loop.create_future() - self.waiters.append(future) - try: - return await future - finally: - self.waiters.remove(future) - - def get_future(self) -> asyncio.Future[list[Member]]: - future = self.loop.create_future() - self.waiters.append(future) - return future - - def done(self) -> None: - for future in self.waiters: - if not future.done(): - future.set_result(self.buffer) - - -_log = logging.getLogger(__name__) - - -async def logging_coroutine(coroutine: Coroutine[Any, Any, T], *, info: str) -> None: - try: - await coroutine - except Exception: - _log.exception("Exception occurred during %s", info) - - -class ConnectionState: - if TYPE_CHECKING: - _get_websocket: Callable[..., DiscordWebSocket] - _get_client: Callable[..., Client] - _parsers: dict[str, Callable[[dict[str, Any]], None]] - - def __init__( - self, - *, - dispatch: Callable, - handlers: dict[str, Callable], - hooks: dict[str, Callable], - http: HTTPClient, - loop: asyncio.AbstractEventLoop, - **options: Any, - ) -> None: - self.loop: asyncio.AbstractEventLoop = loop - self.http: HTTPClient = http - self.max_messages: int | None = options.get("max_messages", 1000) - if self.max_messages is not None and self.max_messages <= 0: - self.max_messages = 1000 - - self.dispatch: Callable = dispatch - self.handlers: dict[str, Callable] = handlers - self.hooks: dict[str, Callable] = hooks - self.shard_count: int | None = None - self._ready_task: asyncio.Task | None = None - self.application_id: int | None = get_as_snowflake(options, "application_id") - self.heartbeat_timeout: float = options.get("heartbeat_timeout", 60.0) - self.guild_ready_timeout: float = options.get("guild_ready_timeout", 2.0) - if self.guild_ready_timeout < 0: - raise ValueError("guild_ready_timeout cannot be negative") - - allowed_mentions = options.get("allowed_mentions") - - if allowed_mentions is not None and not isinstance(allowed_mentions, AllowedMentions): - raise TypeError("allowed_mentions parameter must be AllowedMentions") - - self.allowed_mentions: AllowedMentions | None = allowed_mentions - self._chunk_requests: dict[int | str, ChunkRequest] = {} - - activity = options.get("activity", None) - if activity: - if not isinstance(activity, BaseActivity): - raise TypeError("activity parameter must derive from BaseActivity.") - - activity = activity.to_dict() - - status = options.get("status", None) - if status: - status = "invisible" if status is Status.offline else str(status) - intents = options.get("intents", None) - if intents is None: - intents = Intents.default() - - elif not isinstance(intents, Intents): - raise TypeError(f"intents parameter must be Intent not {type(intents)!r}") - if not intents.guilds: - _log.warning("Guilds intent seems to be disabled. This may cause state related issues.") - - self._chunk_guilds: bool = options.get("chunk_guilds_at_startup", intents.members) - - # Ensure these two are set properly - if not intents.members and self._chunk_guilds: - raise ValueError("Intents.members must be enabled to chunk guilds at startup.") - - cache_flags = options.get("member_cache_flags", None) - if cache_flags is None: - cache_flags = MemberCacheFlags.from_intents(intents) - elif not isinstance(cache_flags, MemberCacheFlags): - raise TypeError(f"member_cache_flags parameter must be MemberCacheFlags not {type(cache_flags)!r}") - - else: - cache_flags._verify_intents(intents) - - self.member_cache_flags: MemberCacheFlags = cache_flags - self._activity: ActivityPayload | None = activity - self._status: str | None = status - self._intents: Intents = intents - - if not intents.members or cache_flags._empty: - self.store_user = self.create_user # type: ignore - self.deref_user = self.deref_user_no_intents # type: ignore - - self.cache_app_emojis: bool = options.get("cache_app_emojis", False) - - self.parsers = parsers = {} - for attr, func in inspect.getmembers(self): - if attr.startswith("parse_"): - parsers[attr[6:].upper()] = func - - self.clear() - - def clear(self, *, views: bool = True) -> None: - self.user: ClientUser | None = None - # Originally, this code used WeakValueDictionary to maintain references to the - # global user mapping. - - # However, profiling showed that this came with two cons: - - # 1. The __weakref__ slot caused a non-trivial increase in memory - # 2. The performance of the mapping caused store_user to be a bottleneck. - - # Since this is undesirable, a mapping is now used instead with stored - # references now using a regular dictionary with eviction being done - # using __del__. Testing this for memory leaks led to no discernible leaks, - # though more testing will have to be done. - self._users: dict[int, User] = {} - self._emojis: dict[int, (GuildEmoji, AppEmoji)] = {} - self._stickers: dict[int, GuildSticker] = {} - self._guilds: dict[int, Guild] = {} - self._polls: dict[int, Poll] = {} - if views: - self._view_store: ViewStore = ViewStore(self) - self._modal_store: ModalStore = ModalStore(self) - self._voice_clients: dict[int, VoiceClient] = {} - self._sounds: dict[int, SoundboardSound] = {} - - # LRU of max size 128 - self._private_channels: OrderedDict[int, PrivateChannel] = OrderedDict() - # extra dict to look up private channels by user id - self._private_channels_by_user: dict[int, DMChannel] = {} - if self.max_messages is not None: - self._messages: Deque[Message] | None = deque(maxlen=self.max_messages) - else: - self._messages: Deque[Message] | None = None - - def process_chunk_requests(self, guild_id: int, nonce: str | None, members: list[Member], complete: bool) -> None: - removed = [] - for key, request in self._chunk_requests.items(): - if request.guild_id == guild_id and request.nonce == nonce: - request.add_members(members) - if complete: - request.done() - removed.append(key) - - for key in removed: - del self._chunk_requests[key] - - def call_handlers(self, key: str, *args: Any, **kwargs: Any) -> None: - try: - func = self.handlers[key] - except KeyError: - pass - else: - func(*args, **kwargs) - - async def call_hooks(self, key: str, *args: Any, **kwargs: Any) -> None: - try: - coro = self.hooks[key] - except KeyError: - pass - else: - await coro(*args, **kwargs) - - @property - def self_id(self) -> int | None: - u = self.user - return u.id if u else None - - @property - def intents(self) -> Intents: - ret = Intents.none() - ret.value = self._intents.value - return ret - - @property - def voice_clients(self) -> list[VoiceClient]: - return list(self._voice_clients.values()) - - def _get_voice_client(self, guild_id: int | None) -> VoiceClient | None: - # the keys of self._voice_clients are ints - return self._voice_clients.get(guild_id) # type: ignore - - def _add_voice_client(self, guild_id: int, voice: VoiceClient) -> None: - self._voice_clients[guild_id] = voice - - def _remove_voice_client(self, guild_id: int) -> None: - self._voice_clients.pop(guild_id, None) - - def _update_references(self, ws: DiscordWebSocket) -> None: - for vc in self.voice_clients: - vc.main_ws = ws # type: ignore - - def store_user(self, data: UserPayload) -> User: - user_id = int(data["id"]) - try: - user = self._users[user_id] - except KeyError: - user = User(state=self, data=data) - if user.discriminator != "0000": - self._users[user_id] = user - user._stored = True - return user - else: - # Making sure we don't mutate the cached user - # because we cannot make sure it's up to date. - # but still return the updated version of the user. - # This make sure data like banner, etc are updated. - copied_user = user._copy(user) - copied_user._update(data) - return copied_user - - def deref_user(self, user_id: int) -> None: - self._users.pop(user_id, None) - - def create_user(self, data: UserPayload) -> User: - return User(state=self, data=data) - - def deref_user_no_intents(self, user_id: int) -> None: - return - - def get_user(self, id: int | None) -> User | None: - # the keys of self._users are ints - return self._users.get(id) # type: ignore - - def store_emoji(self, guild: Guild, data: EmojiPayload) -> GuildEmoji: - # the id will be present here - emoji_id = int(data["id"]) # type: ignore - self._emojis[emoji_id] = emoji = GuildEmoji(guild=guild, state=self, data=data) - return emoji - - def maybe_store_app_emoji(self, application_id: int, data: EmojiPayload) -> AppEmoji: - # the id will be present here - emoji = AppEmoji(application_id=application_id, state=self, data=data) - if self.cache_app_emojis: - emoji_id = int(data["id"]) # type: ignore - self._emojis[emoji_id] = emoji - return emoji - - def store_sticker(self, guild: Guild, data: GuildStickerPayload) -> GuildSticker: - sticker_id = int(data["id"]) - self._stickers[sticker_id] = sticker = GuildSticker(state=self, data=data) - return sticker - - def store_view(self, view: View, message_id: int | None = None) -> None: - self._view_store.add_view(view, message_id) - - def store_modal(self, modal: Modal, message_id: int) -> None: - self._modal_store.add_modal(modal, message_id) - - def prevent_view_updates_for(self, message_id: int) -> View | None: - return self._view_store.remove_message_tracking(message_id) - - @property - def persistent_views(self) -> Sequence[View]: - return self._view_store.persistent_views - - @property - def guilds(self) -> list[Guild]: - return list(self._guilds.values()) - - def _get_guild(self, guild_id: int | None) -> Guild | None: - # the keys of self._guilds are ints - return self._guilds.get(guild_id) # type: ignore - - def _add_guild(self, guild: Guild) -> None: - self._guilds[guild.id] = guild - - def _remove_guild(self, guild: Guild) -> None: - self._guilds.pop(guild.id, None) - - for emoji in guild.emojis: - self._remove_emoji(emoji) - - for sticker in guild.stickers: - self._stickers.pop(sticker.id, None) - - del guild - - @property - def emojis(self) -> list[GuildEmoji | AppEmoji]: - return list(self._emojis.values()) - - @property - def stickers(self) -> list[GuildSticker]: - return list(self._stickers.values()) - - def get_emoji(self, emoji_id: int | None) -> GuildEmoji | AppEmoji | None: - # the keys of self._emojis are ints - return self._emojis.get(emoji_id) # type: ignore - - def _remove_emoji(self, emoji: GuildEmoji | AppEmoji) -> None: - self._emojis.pop(emoji.id, None) - - def get_sticker(self, sticker_id: int | None) -> GuildSticker | None: - # the keys of self._stickers are ints - return self._stickers.get(sticker_id) # type: ignore - - @property - def polls(self) -> list[Poll]: - return list(self._polls.values()) - - def store_raw_poll(self, poll: PollPayload, raw): - channel = self.get_channel(raw.channel_id) or PartialMessageable(state=self, id=raw.channel_id) - message = channel.get_partial_message(raw.message_id) - p = Poll.from_dict(poll, message) - self._polls[message.id] = p - return p - - def store_poll(self, poll: Poll, message_id: int): - self._polls[message_id] = poll - - def get_poll(self, message_id): - return self._polls.get(message_id) - - @property - def private_channels(self) -> list[PrivateChannel]: - return list(self._private_channels.values()) - - def _get_private_channel(self, channel_id: int | None) -> PrivateChannel | None: - try: - # the keys of self._private_channels are ints - value = self._private_channels[channel_id] # type: ignore - except KeyError: - return None - else: - self._private_channels.move_to_end(channel_id) # type: ignore - return value - - def _get_private_channel_by_user(self, user_id: int | None) -> DMChannel | None: - # the keys of self._private_channels are ints - return self._private_channels_by_user.get(user_id) # type: ignore - - def _add_private_channel(self, channel: PrivateChannel) -> None: - channel_id = channel.id - self._private_channels[channel_id] = channel - - if len(self._private_channels) > 128: - _, to_remove = self._private_channels.popitem(last=False) - if isinstance(to_remove, DMChannel) and to_remove.recipient: - self._private_channels_by_user.pop(to_remove.recipient.id, None) - - if isinstance(channel, DMChannel) and channel.recipient: - self._private_channels_by_user[channel.recipient.id] = channel - - def add_dm_channel(self, data: DMChannelPayload) -> DMChannel: - # self.user is *always* cached when this is called - channel = DMChannel(me=self.user, state=self, data=data) # type: ignore - self._add_private_channel(channel) - return channel - - def _remove_private_channel(self, channel: PrivateChannel) -> None: - self._private_channels.pop(channel.id, None) - if isinstance(channel, DMChannel): - recipient = channel.recipient - if recipient is not None: - self._private_channels_by_user.pop(recipient.id, None) - - def _get_message(self, msg_id: int | None) -> Message | None: - return utils.find(lambda m: m.id == msg_id, reversed(self._messages)) if self._messages else None - - def _add_guild_from_data(self, data: GuildPayload) -> Guild: - guild = Guild(data=data, state=self) - self._add_guild(guild) - return guild - - def _guild_needs_chunking(self, guild: Guild) -> bool: - # If presences are enabled then we get back the old guild.large behaviour - return self._chunk_guilds and not guild.chunked and not (self._intents.presences and not guild.large) - - def _get_guild_channel( - self, data: MessagePayload, guild_id: int | None = None - ) -> tuple[Channel | Thread, Guild | None]: - channel_id = int(data["channel_id"]) - try: - guild = self._get_guild(int(guild_id or data["guild_id"])) - except KeyError: - channel = DMChannel._from_message(self, channel_id) - guild = None - else: - channel = guild and guild._resolve_channel(channel_id) - - return channel or PartialMessageable(state=self, id=channel_id), guild - - async def chunker( - self, - guild_id: int, - query: str = "", - limit: int = 0, - presences: bool = False, - *, - nonce: str | None = None, - ) -> None: - ws = self._get_websocket(guild_id) # This is ignored upstream - await ws.request_chunks(guild_id, query=query, limit=limit, presences=presences, nonce=nonce) - - async def query_members( - self, - guild: Guild, - query: str | None, - limit: int, - user_ids: list[int] | None, - cache: bool, - presences: bool, - ): - guild_id = guild.id - ws = self._get_websocket(guild_id) - if ws is None: - raise RuntimeError("Somehow do not have a websocket for this guild_id") - - request = ChunkRequest(guild.id, self.loop, self._get_guild, cache=cache) - self._chunk_requests[request.nonce] = request - - try: - # start the query operation - await ws.request_chunks( - guild_id, - query=query, - limit=limit, - user_ids=user_ids, - presences=presences, - nonce=request.nonce, - ) - return await asyncio.wait_for(request.wait(), timeout=30.0) - except asyncio.TimeoutError: - _log.warning( - ("Timed out waiting for chunks with query %r and limit %d for guild_id %d"), - query, - limit, - guild_id, - ) - raise - - async def _delay_ready(self) -> None: - if self.cache_app_emojis and self.application_id: - data = await self.http.get_all_application_emojis(self.application_id) - for e in data.get("items", []): - self.maybe_store_app_emoji(self.application_id, e) - try: - states = [] - while True: - # this snippet of code is basically waiting N seconds - # until the last GUILD_CREATE was sent - try: - guild = await asyncio.wait_for(self._ready_state.get(), timeout=self.guild_ready_timeout) - except asyncio.TimeoutError: - break - else: - if self._guild_needs_chunking(guild): - future = await self.chunk_guild(guild, wait=False) - states.append((guild, future)) - elif guild.unavailable is False: - self.dispatch("guild_available", guild) - else: - self.dispatch("guild_join", guild) - - for guild, future in states: - try: - await asyncio.wait_for(future, timeout=5.0) - except asyncio.TimeoutError: - _log.warning( - "Shard ID %s timed out waiting for chunks for guild_id %s.", - guild.shard_id, - guild.id, - ) - - if guild.unavailable is False: - self.dispatch("guild_available", guild) - else: - self.dispatch("guild_join", guild) - - # remove the state - try: - del self._ready_state - except AttributeError: - pass # already been deleted somehow - - except asyncio.CancelledError: - pass - else: - await self._add_default_sounds() - # dispatch the event - self.call_handlers("ready") - self.dispatch("ready") - finally: - self._ready_task = None - - def parse_ready(self, data) -> None: - if self._ready_task is not None: - self._ready_task.cancel() - - self._ready_state = asyncio.Queue() - self.clear(views=False) - self.user = ClientUser(state=self, data=data["user"]) - self.store_user(data["user"]) - - if self.application_id is None: - try: - application = data["application"] - except KeyError: - pass - else: - self.application_id = get_as_snowflake(application, "id") - # flags will always be present here - self.application_flags = ApplicationFlags._from_value(application["flags"]) # type: ignore - - for guild_data in data["guilds"]: - self._add_guild_from_data(guild_data) - - self.dispatch("connect") - self._ready_task = asyncio.create_task(self._delay_ready()) - - def parse_resumed(self, data) -> None: - self.dispatch("resumed") - - def parse_application_command_permissions_update(self, data) -> None: - # unsure what the implementation would be like - pass - - def parse_auto_moderation_rule_create(self, data) -> None: - rule = AutoModRule(state=self, data=data) - self.dispatch("auto_moderation_rule_create", rule) - - def parse_auto_moderation_rule_update(self, data) -> None: - # somehow get a 'before' object? - rule = AutoModRule(state=self, data=data) - self.dispatch("auto_moderation_rule_update", rule) - - def parse_auto_moderation_rule_delete(self, data) -> None: - rule = AutoModRule(state=self, data=data) - self.dispatch("auto_moderation_rule_delete", rule) - - def parse_auto_moderation_action_execution(self, data) -> None: - event = AutoModActionExecutionEvent(self, data) - self.dispatch("auto_moderation_action_execution", event) - - def parse_entitlement_create(self, data) -> None: - event = Entitlement(data=data, state=self) - self.dispatch("entitlement_create", event) - - def parse_entitlement_update(self, data) -> None: - event = Entitlement(data=data, state=self) - self.dispatch("entitlement_update", event) - - def parse_entitlement_delete(self, data) -> None: - event = Entitlement(data=data, state=self) - self.dispatch("entitlement_delete", event) - - def parse_subscription_create(self, data) -> None: - event = Subscription(data=data, state=self) - self.dispatch("subscription_create", event) - - def parse_subscription_update(self, data) -> None: - event = Subscription(data=data, state=self) - self.dispatch("subscription_update", event) - - def parse_subscription_delete(self, data) -> None: - event = Subscription(data=data, state=self) - self.dispatch("subscription_delete", event) - - def parse_message_create(self, data) -> None: - channel, _ = self._get_guild_channel(data) - # channel would be the correct type here - message = Message(channel=channel, data=data, state=self) # type: ignore - self.dispatch("message", message) - if self._messages is not None: - self._messages.append(message) - # we ensure that the channel is either a TextChannel, VoiceChannel, StageChannel, or Thread - if channel and channel.__class__ in ( - TextChannel, - VoiceChannel, - StageChannel, - Thread, - ): - channel.last_message_id = message.id # type: ignore - - def parse_message_delete(self, data) -> None: - raw = RawMessageDeleteEvent(data) - found = self._get_message(raw.message_id) - raw.cached_message = found - self.dispatch("raw_message_delete", raw) - if self._messages is not None and found is not None: - self.dispatch("message_delete", found) - self._messages.remove(found) - - def parse_message_delete_bulk(self, data) -> None: - raw = RawBulkMessageDeleteEvent(data) - if self._messages: - found_messages = [message for message in self._messages if message.id in raw.message_ids] - else: - found_messages = [] - raw.cached_messages = found_messages - self.dispatch("raw_bulk_message_delete", raw) - if found_messages: - self.dispatch("bulk_message_delete", found_messages) - for msg in found_messages: - # self._messages won't be None here - self._messages.remove(msg) # type: ignore - - def parse_message_update(self, data) -> None: - raw = RawMessageUpdateEvent(data) - message = self._get_message(raw.message_id) - if message is not None: - older_message = copy.copy(message) - raw.cached_message = older_message - self.dispatch("raw_message_edit", raw) - message._update(data) - # Coerce the `after` parameter to take the new updated Member - # ref: #5999 - older_message.author = message.author - self.dispatch("message_edit", older_message, message) - else: - if poll_data := data.get("poll"): - self.store_raw_poll(poll_data, raw) - self.dispatch("raw_message_edit", raw) - - if "components" in data and self._view_store.is_message_tracked(raw.message_id): - self._view_store.update_from_message(raw.message_id, data["components"]) - - def parse_message_reaction_add(self, data) -> None: - emoji = data["emoji"] - emoji_id = get_as_snowflake(emoji, "id") - emoji = PartialEmoji.with_state(self, id=emoji_id, animated=emoji.get("animated", False), name=emoji["name"]) - raw = RawReactionActionEvent(data, emoji, "REACTION_ADD") - - member_data = data.get("member") - if member_data: - guild = self._get_guild(raw.guild_id) - if guild is not None: - raw.member = Member(data=member_data, guild=guild, state=self) - else: - raw.member = None - else: - raw.member = None - self.dispatch("raw_reaction_add", raw) - - # rich interface here - message = self._get_message(raw.message_id) - if message is not None: - emoji = self._upgrade_partial_emoji(emoji) - reaction = message._add_reaction(data, emoji, raw.user_id) - user = raw.member or self._get_reaction_user(message.channel, raw.user_id) - - if user: - self.dispatch("reaction_add", reaction, user) - - def parse_message_reaction_remove_all(self, data) -> None: - raw = RawReactionClearEvent(data) - self.dispatch("raw_reaction_clear", raw) - - message = self._get_message(raw.message_id) - if message is not None: - old_reactions = message.reactions.copy() - message.reactions.clear() - self.dispatch("reaction_clear", message, old_reactions) - - def parse_message_reaction_remove(self, data) -> None: - emoji = data["emoji"] - emoji_id = get_as_snowflake(emoji, "id") - emoji = PartialEmoji.with_state(self, id=emoji_id, name=emoji["name"]) - raw = RawReactionActionEvent(data, emoji, "REACTION_REMOVE") - - member_data = data.get("member") - if member_data: - guild = self._get_guild(raw.guild_id) - if guild is not None: - raw.member = Member(data=member_data, guild=guild, state=self) - else: - raw.member = None - else: - raw.member = None - - self.dispatch("raw_reaction_remove", raw) - - message = self._get_message(raw.message_id) - if message is not None: - emoji = self._upgrade_partial_emoji(emoji) - try: - reaction = message._remove_reaction(data, emoji, raw.user_id) - except (AttributeError, ValueError): # eventual consistency lol - pass - else: - user = self._get_reaction_user(message.channel, raw.user_id) - if user: - self.dispatch("reaction_remove", reaction, user) - - def parse_message_reaction_remove_emoji(self, data) -> None: - emoji = data["emoji"] - emoji_id = get_as_snowflake(emoji, "id") - emoji = PartialEmoji.with_state(self, id=emoji_id, name=emoji["name"]) - raw = RawReactionClearEmojiEvent(data, emoji) - self.dispatch("raw_reaction_clear_emoji", raw) - - message = self._get_message(raw.message_id) - if message is not None: - try: - reaction = message._clear_emoji(emoji) - except (AttributeError, ValueError): # eventual consistency lol - pass - else: - if reaction: - self.dispatch("reaction_clear_emoji", reaction) - - def parse_message_poll_vote_add(self, data) -> None: - raw = RawMessagePollVoteEvent(data, True) - guild = self._get_guild(raw.guild_id) - if guild: - user = guild.get_member(raw.user_id) - else: - user = self.get_user(raw.user_id) - self.dispatch("raw_poll_vote_add", raw) - - self._get_message(raw.message_id) - poll = self.get_poll(raw.message_id) - # if message was cached, poll has already updated but votes haven't - if poll and poll.results: - answer = poll.get_answer(raw.answer_id) - counts = poll.results._answer_counts - if answer is not None: - if answer.id in counts: - counts[answer.id].count += 1 - else: - counts[answer.id] = PollAnswerCount({"id": answer.id, "count": 1, "me_voted": False}) - if poll is not None and user is not None: - answer = poll.get_answer(raw.answer_id) - if answer is not None: - self.dispatch("poll_vote_add", poll, user, answer) - - def parse_message_poll_vote_remove(self, data) -> None: - raw = RawMessagePollVoteEvent(data, False) - guild = self._get_guild(raw.guild_id) - if guild: - user = guild.get_member(raw.user_id) - else: - user = self.get_user(raw.user_id) - self.dispatch("raw_poll_vote_remove", raw) - - self._get_message(raw.message_id) - poll = self.get_poll(raw.message_id) - # if message was cached, poll has already updated but votes haven't - if poll and poll.results: - answer = poll.get_answer(raw.answer_id) - counts = poll.results._answer_counts - if answer is not None: - if answer.id in counts: - counts[answer.id].count -= 1 - if poll is not None and user is not None: - answer = poll.get_answer(raw.answer_id) - if answer is not None: - self.dispatch("poll_vote_remove", poll, user, answer) - - def parse_interaction_create(self, data) -> None: - interaction = Interaction(data=data, state=self) - if data["type"] == 3: # interaction component - custom_id = interaction.data["custom_id"] # type: ignore - component_type = interaction.data["component_type"] # type: ignore - self._view_store.dispatch(component_type, custom_id, interaction) - if interaction.type == InteractionType.modal_submit: - user_id, custom_id = ( - interaction.user.id, - interaction.data["custom_id"], - ) - asyncio.create_task(self._modal_store.dispatch(user_id, custom_id, interaction)) - - self.dispatch("interaction", interaction) - - def parse_presence_update(self, data) -> None: - guild_id = get_as_snowflake(data, "guild_id") - # guild_id won't be None here - guild = self._get_guild(guild_id) - if guild is None: - _log.debug( - "PRESENCE_UPDATE referencing an unknown guild ID: %s. Discarding.", - guild_id, - ) - return - - user = data["user"] - member_id = int(user["id"]) - member = guild.get_member(member_id) - if member is None: - _log.debug( - "PRESENCE_UPDATE referencing an unknown member ID: %s. Discarding", - member_id, - ) - return - - old_member = Member._copy(member) - user_update = member._presence_update(data=data, user=user) - if user_update: - self.dispatch("user_update", user_update[0], user_update[1]) - - self.dispatch("presence_update", old_member, member) - - def parse_user_update(self, data) -> None: - # self.user is *always* cached when this is called - user: ClientUser = self.user # type: ignore - user._update(data) - ref = self._users.get(user.id) - if ref: - ref._update(data) - - def parse_invite_create(self, data) -> None: - invite = Invite.from_gateway(state=self, data=data) - self.dispatch("invite_create", invite) - - def parse_invite_delete(self, data) -> None: - invite = Invite.from_gateway(state=self, data=data) - self.dispatch("invite_delete", invite) - - def parse_channel_delete(self, data) -> None: - guild = self._get_guild(get_as_snowflake(data, "guild_id")) - channel_id = int(data["id"]) - if guild is not None: - channel = guild.get_channel(channel_id) - if channel is not None: - guild._remove_channel(channel) - self.dispatch("guild_channel_delete", channel) - - def parse_channel_update(self, data) -> None: - channel_type = try_enum(ChannelType, data.get("type")) - channel_id = int(data["id"]) - if channel_type is ChannelType.group: - channel = self._get_private_channel(channel_id) - old_channel = copy.copy(channel) - # the channel is a GroupChannel - channel._update_group(data) # type: ignore - self.dispatch("private_channel_update", old_channel, channel) - return - - guild_id = get_as_snowflake(data, "guild_id") - guild = self._get_guild(guild_id) - if guild is not None: - channel = guild.get_channel(channel_id) - if channel is not None: - old_channel = copy.copy(channel) - channel._update(guild, data) - self.dispatch("guild_channel_update", old_channel, channel) - else: - _log.debug( - "CHANNEL_UPDATE referencing an unknown channel ID: %s. Discarding.", - channel_id, - ) - else: - _log.debug( - "CHANNEL_UPDATE referencing an unknown guild ID: %s. Discarding.", - guild_id, - ) - - def parse_channel_create(self, data) -> None: - factory, _ch_type = _channel_factory(data["type"]) - if factory is None: - _log.debug( - "CHANNEL_CREATE referencing an unknown channel type %s. Discarding.", - data["type"], - ) - return - - guild_id = get_as_snowflake(data, "guild_id") - guild = self._get_guild(guild_id) - if guild is not None: - # the factory can't be a DMChannel or GroupChannel here - channel = factory(guild=guild, state=self, data=data) # type: ignore - guild._add_channel(channel) # type: ignore - self.dispatch("guild_channel_create", channel) - else: - _log.debug( - "CHANNEL_CREATE referencing an unknown guild ID: %s. Discarding.", - guild_id, - ) - return - - def parse_channel_pins_update(self, data) -> None: - channel_id = int(data["channel_id"]) - try: - guild = self._get_guild(int(data["guild_id"])) - except KeyError: - guild = None - channel = self._get_private_channel(channel_id) - else: - channel = guild and guild._resolve_channel(channel_id) - - if channel is None: - _log.debug( - ("CHANNEL_PINS_UPDATE referencing an unknown channel ID: %s. Discarding."), - channel_id, - ) - return - - last_pin = parse_time(data["last_pin_timestamp"]) if data["last_pin_timestamp"] else None - - if guild is None: - self.dispatch("private_channel_pins_update", channel, last_pin) - else: - self.dispatch("guild_channel_pins_update", channel, last_pin) - - def parse_thread_create(self, data) -> None: - guild_id = int(data["guild_id"]) - guild: Guild | None = self._get_guild(guild_id) - if guild is None: - _log.debug( - "THREAD_CREATE referencing an unknown guild ID: %s. Discarding", - guild_id, - ) - return - - cached_thread = guild.get_thread(int(data["id"])) - if not cached_thread: - thread = Thread(guild=guild, state=guild._state, data=data) - guild._add_thread(thread) - if data.get("newly_created"): - thread._add_member( - ThreadMember( - thread, - { - "id": thread.id, - "user_id": data["owner_id"], - "join_timestamp": data["thread_metadata"]["create_timestamp"], - "flags": utils.MISSING, - }, - ) - ) - self.dispatch("thread_create", thread) - else: - self.dispatch("thread_join", cached_thread) - - def parse_thread_update(self, data) -> None: - guild_id = int(data["guild_id"]) - guild = self._get_guild(guild_id) - raw = RawThreadUpdateEvent(data) - if guild is None: - _log.debug( - "THREAD_UPDATE referencing an unknown guild ID: %s. Discarding", - guild_id, - ) - return - else: - thread = guild.get_thread(raw.thread_id) - if thread is not None: - old = copy.copy(thread) - thread._update(data) - if thread.archived: - guild._remove_thread(thread) - self.dispatch("thread_update", old, thread) - else: - thread = Thread(guild=guild, state=guild._state, data=data) - if not thread.archived: - guild._add_thread(thread) - self.dispatch("thread_join", thread) - raw.thread = thread - self.dispatch("raw_thread_update", raw) - - def parse_thread_delete(self, data) -> None: - guild_id = int(data["guild_id"]) - guild = self._get_guild(guild_id) - - if guild is None: - _log.debug( - "THREAD_DELETE referencing an unknown guild ID: %s. Discarding", - guild_id, - ) - return - - raw = RawThreadDeleteEvent(data) - thread = guild.get_thread(raw.thread_id) - raw.thread = thread - - self.dispatch("raw_thread_delete", raw) - - if thread is not None: - guild._remove_thread(thread) # type: ignore - self.dispatch("thread_delete", thread) - - if (msg := thread.starting_message) is not None: - msg.thread = None - - def parse_thread_list_sync(self, data) -> None: - guild_id = int(data["guild_id"]) - guild: Guild | None = self._get_guild(guild_id) - if guild is None: - _log.debug( - "THREAD_LIST_SYNC referencing an unknown guild ID: %s. Discarding", - guild_id, - ) - return - - try: - channel_ids = set(data["channel_ids"]) - except KeyError: - # If not provided, then the entire guild is being synced - # So all previous thread data should be overwritten - previous_threads = guild._threads.copy() - guild._clear_threads() - else: - previous_threads = guild._filter_threads(channel_ids) - - threads = {d["id"]: guild._store_thread(d) for d in data.get("threads", [])} - - for member in data.get("members", []): - try: - # note: member['id'] is the thread_id - thread = threads[member["id"]] - except KeyError: - continue - else: - thread._add_member(ThreadMember(thread, member)) - - for thread in threads.values(): - old = previous_threads.pop(thread.id, None) - if old is None: - self.dispatch("thread_join", thread) - - for thread in previous_threads.values(): - self.dispatch("thread_remove", thread) - - def parse_thread_member_update(self, data) -> None: - guild_id = int(data["guild_id"]) - guild: Guild | None = self._get_guild(guild_id) - if guild is None: - _log.debug( - "THREAD_MEMBER_UPDATE referencing an unknown guild ID: %s. Discarding", - guild_id, - ) - return - - thread_id = int(data["id"]) - thread: Thread | None = guild.get_thread(thread_id) - if thread is None: - _log.debug( - "THREAD_MEMBER_UPDATE referencing an unknown thread ID: %s. Discarding", - thread_id, - ) - return - - member = ThreadMember(thread, data) - thread.me = member - thread._add_member(member) - - def parse_thread_members_update(self, data) -> None: - guild_id = int(data["guild_id"]) - guild: Guild | None = self._get_guild(guild_id) - if guild is None: - _log.debug( - "THREAD_MEMBERS_UPDATE referencing an unknown guild ID: %s. Discarding", - guild_id, - ) - return - - thread_id = int(data["id"]) - thread: Thread | None = guild.get_thread(thread_id) - raw = RawThreadMembersUpdateEvent(data) - if thread is None: - _log.debug( - ("THREAD_MEMBERS_UPDATE referencing an unknown thread ID: %s. Discarding"), - thread_id, - ) - return - - added_members = [ThreadMember(thread, d) for d in data.get("added_members", [])] - removed_member_ids = [int(x) for x in data.get("removed_member_ids", [])] - self_id = self.self_id - for member in added_members: - thread._add_member(member) - if member.id != self_id: - self.dispatch("thread_member_join", member) - else: - thread.me = member - self.dispatch("thread_join", thread) - - for member_id in removed_member_ids: - member = thread._pop_member(member_id) - if member_id != self_id: - self.dispatch("raw_thread_member_remove", raw) - if member is not None: - self.dispatch("thread_member_remove", member) - else: - thread.me = None - self.dispatch("thread_remove", thread) - - def parse_guild_member_add(self, data) -> None: - guild = self._get_guild(int(data["guild_id"])) - if guild is None: - _log.debug( - "GUILD_MEMBER_ADD referencing an unknown guild ID: %s. Discarding.", - data["guild_id"], - ) - return - - member = Member(guild=guild, data=data, state=self) - if self.member_cache_flags.joined: - guild._add_member(member) - - if guild._member_count is not None: - guild._member_count += 1 - - self.dispatch("member_join", member) - - def parse_guild_member_remove(self, data) -> None: - user = self.store_user(data["user"]) - raw = RawMemberRemoveEvent(data, user) - - guild = self._get_guild(int(data["guild_id"])) - if guild is not None: - if guild._member_count is not None: - guild._member_count -= 1 - - member = guild.get_member(user.id) - if member is not None: - raw.user = member - guild._remove_member(member) # type: ignore - self.dispatch("member_remove", member) - else: - _log.debug( - "GUILD_MEMBER_REMOVE referencing an unknown guild ID: %s. Discarding.", - data["guild_id"], - ) - self.dispatch("raw_member_remove", raw) - - def parse_guild_member_update(self, data) -> None: - guild = self._get_guild(int(data["guild_id"])) - user = data["user"] - user_id = int(user["id"]) - if guild is None: - _log.debug( - "GUILD_MEMBER_UPDATE referencing an unknown guild ID: %s. Discarding.", - data["guild_id"], - ) - return - - member = guild.get_member(user_id) - if member is not None: - old_member = Member._copy(member) - member._update(data) - user_update = member._update_inner_user(user) - if user_update: - self.dispatch("user_update", user_update[0], user_update[1]) - - self.dispatch("member_update", old_member, member) - else: - if self.member_cache_flags.joined: - member = Member(data=data, guild=guild, state=self) - - # Force an update on the inner user if necessary - user_update = member._update_inner_user(user) - if user_update: - self.dispatch("user_update", user_update[0], user_update[1]) - - guild._add_member(member) - _log.debug( - "GUILD_MEMBER_UPDATE referencing an unknown member ID: %s. Discarding.", - user_id, - ) - - def parse_guild_emojis_update(self, data) -> None: - guild = self._get_guild(int(data["guild_id"])) - if guild is None: - _log.debug( - "GUILD_EMOJIS_UPDATE referencing an unknown guild ID: %s. Discarding.", - data["guild_id"], - ) - return - - before_emojis = guild.emojis - for emoji in before_emojis: - self._emojis.pop(emoji.id, None) - # guild won't be None here - guild.emojis = tuple(map(lambda d: self.store_emoji(guild, d), data["emojis"])) # type: ignore - self.dispatch("guild_emojis_update", guild, before_emojis, guild.emojis) - - def parse_guild_stickers_update(self, data) -> None: - guild = self._get_guild(int(data["guild_id"])) - if guild is None: - _log.debug( - ("GUILD_STICKERS_UPDATE referencing an unknown guild ID: %s. Discarding."), - data["guild_id"], - ) - return - - before_stickers = guild.stickers - for emoji in before_stickers: - self._stickers.pop(emoji.id, None) - # guild won't be None here - guild.stickers = tuple(map(lambda d: self.store_sticker(guild, d), data["stickers"])) # type: ignore - self.dispatch("guild_stickers_update", guild, before_stickers, guild.stickers) - - def _get_create_guild(self, data): - if data.get("unavailable") is False: - # GUILD_CREATE with unavailable in the response - # usually means that the guild has become available - # and is therefore in the cache - guild = self._get_guild(int(data["id"])) - if guild is not None: - guild.unavailable = False - guild._from_data(data) - return guild - - return self._add_guild_from_data(data) - - def is_guild_evicted(self, guild) -> bool: - return guild.id not in self._guilds - - async def chunk_guild(self, guild, *, wait=True, cache=None): - # Note: This method makes an API call without timeout, and should be used in - # conjunction with `asyncio.wait_for(..., timeout=...)`. - cache = cache or self.member_cache_flags.joined - request = self._chunk_requests.get(guild.id) # nosec B113 - if request is None: - self._chunk_requests[guild.id] = request = ChunkRequest(guild.id, self.loop, self._get_guild, cache=cache) - await self.chunker(guild.id, nonce=request.nonce) - - if wait: - return await request.wait() - return request.get_future() - - async def _chunk_and_dispatch(self, guild, unavailable): - try: - await asyncio.wait_for(self.chunk_guild(guild), timeout=60.0) - except asyncio.TimeoutError: - _log.info("Somehow timed out waiting for chunks.") - - if unavailable is False: - self.dispatch("guild_available", guild) - else: - self.dispatch("guild_join", guild) - - def parse_guild_create(self, data) -> None: - unavailable = data.get("unavailable") - if unavailable is True: - # joined a guild with unavailable == True so.. - return - - guild = self._get_create_guild(data) - - try: - # Notify the on_ready state, if any, that this guild is complete. - self._ready_state.put_nowait(guild) - except AttributeError: - pass - else: - # If we're waiting for the event, put the rest on hold - return - - # check if it requires chunking - if self._guild_needs_chunking(guild): - asyncio.create_task(self._chunk_and_dispatch(guild, unavailable)) - return - - # Dispatch available if newly available - if unavailable is False: - self.dispatch("guild_available", guild) - else: - self.dispatch("guild_join", guild) - - def parse_guild_update(self, data) -> None: - guild = self._get_guild(int(data["id"])) - if guild is not None: - old_guild = copy.copy(guild) - guild._from_data(data) - self.dispatch("guild_update", old_guild, guild) - else: - _log.debug( - "GUILD_UPDATE referencing an unknown guild ID: %s. Discarding.", - data["id"], - ) - - def parse_guild_delete(self, data) -> None: - guild = self._get_guild(int(data["id"])) - if guild is None: - _log.debug( - "GUILD_DELETE referencing an unknown guild ID: %s. Discarding.", - data["id"], - ) - return - - if data.get("unavailable", False): - # GUILD_DELETE with unavailable being True means that the - # guild that was available is now currently unavailable - guild.unavailable = True - self.dispatch("guild_unavailable", guild) - return - - # do a cleanup of the messages cache - if self._messages is not None: - self._messages: Deque[Message] | None = deque( - (msg for msg in self._messages if msg.guild != guild), - maxlen=self.max_messages, - ) - - self._remove_guild(guild) - self.dispatch("guild_remove", guild) - - def parse_guild_audit_log_entry_create(self, data) -> None: - guild = self._get_guild(int(data["guild_id"])) - if guild is None: - _log.debug( - ("GUILD_AUDIT_LOG_ENTRY_CREATE referencing an unknown guild ID: %s. Discarding."), - data["guild_id"], - ) - return - payload = RawAuditLogEntryEvent(data) - payload.guild = guild - self.dispatch("raw_audit_log_entry", payload) - user = self.get_user(payload.user_id) - if user is not None: - data.pop("guild_id") - entry = AuditLogEntry(users={data["user_id"]: user}, data=data, guild=guild) - self.dispatch("audit_log_entry", entry) - - def parse_guild_ban_add(self, data) -> None: - # we make the assumption that GUILD_BAN_ADD is done - # before GUILD_MEMBER_REMOVE is called - # hence we don't remove it from cache or do anything - # strange with it, the main purpose of this event - # is mainly to dispatch to another event worth listening to for logging - guild = self._get_guild(int(data["guild_id"])) - if guild is not None: - try: - user = User(data=data["user"], state=self) - except KeyError: - pass - else: - member = guild.get_member(user.id) or user - self.dispatch("member_ban", guild, member) - - def parse_guild_ban_remove(self, data) -> None: - guild = self._get_guild(int(data["guild_id"])) - if guild is not None and "user" in data: - user = self.store_user(data["user"]) - self.dispatch("member_unban", guild, user) - - def parse_guild_role_create(self, data) -> None: - guild = self._get_guild(int(data["guild_id"])) - if guild is None: - _log.debug( - "GUILD_ROLE_CREATE referencing an unknown guild ID: %s. Discarding.", - data["guild_id"], - ) - return - - role_data = data["role"] - role = Role(guild=guild, data=role_data, state=self) - guild._add_role(role) - self.dispatch("guild_role_create", role) - - def parse_guild_role_delete(self, data) -> None: - guild = self._get_guild(int(data["guild_id"])) - if guild is not None: - role_id = int(data["role_id"]) - try: - role = guild._remove_role(role_id) - except KeyError: - return - else: - self.dispatch("guild_role_delete", role) - else: - _log.debug( - "GUILD_ROLE_DELETE referencing an unknown guild ID: %s. Discarding.", - data["guild_id"], - ) - - def parse_guild_role_update(self, data) -> None: - guild = self._get_guild(int(data["guild_id"])) - if guild is not None: - role_data = data["role"] - role_id = int(role_data["id"]) - role = guild.get_role(role_id) - if role is not None: - old_role = copy.copy(role) - role._update(role_data) - self.dispatch("guild_role_update", old_role, role) - else: - _log.debug( - "GUILD_ROLE_UPDATE referencing an unknown guild ID: %s. Discarding.", - data["guild_id"], - ) - - def parse_guild_members_chunk(self, data) -> None: - guild_id = int(data["guild_id"]) - guild = self._get_guild(guild_id) - presences = data.get("presences", []) - - # the guild won't be None here - members = [Member(guild=guild, data=member, state=self) for member in data.get("members", [])] # type: ignore - _log.debug("Processed a chunk for %s members in guild ID %s.", len(members), guild_id) - - if presences: - member_dict = {str(member.id): member for member in members} - for presence in presences: - user = presence["user"] - member_id = user["id"] - member = member_dict.get(member_id) - if member is not None: - member._presence_update(presence, user) - - complete = data.get("chunk_index", 0) + 1 == data.get("chunk_count") - self.process_chunk_requests(guild_id, data.get("nonce"), members, complete) - - def parse_guild_scheduled_event_create(self, data) -> None: - guild = self._get_guild(int(data["guild_id"])) - if guild is None: - _log.debug( - ("GUILD_SCHEDULED_EVENT_CREATE referencing an unknown guild ID: %s. Discarding."), - data["guild_id"], - ) - return - - creator = None if not data.get("creator", None) else guild.get_member(data.get("creator_id")) - scheduled_event = ScheduledEvent(state=self, guild=guild, creator=creator, data=data) - guild._add_scheduled_event(scheduled_event) - self.dispatch("scheduled_event_create", scheduled_event) - - def parse_guild_scheduled_event_update(self, data) -> None: - guild = self._get_guild(int(data["guild_id"])) - if guild is None: - _log.debug( - ("GUILD_SCHEDULED_EVENT_UPDATE referencing an unknown guild ID: %s. Discarding."), - data["guild_id"], - ) - return - - creator = None if not data.get("creator", None) else guild.get_member(data.get("creator_id")) - scheduled_event = ScheduledEvent(state=self, guild=guild, creator=creator, data=data) - old_event = guild.get_scheduled_event(int(data["id"])) - guild._add_scheduled_event(scheduled_event) - self.dispatch("scheduled_event_update", old_event, scheduled_event) - - def parse_guild_scheduled_event_delete(self, data) -> None: - guild = self._get_guild(int(data["guild_id"])) - if guild is None: - _log.debug( - ("GUILD_SCHEDULED_EVENT_DELETE referencing an unknown guild ID: %s. Discarding."), - data["guild_id"], - ) - return - - creator = None if not data.get("creator", None) else guild.get_member(data.get("creator_id")) - scheduled_event = ScheduledEvent(state=self, guild=guild, creator=creator, data=data) - scheduled_event.status = ScheduledEventStatus.canceled - guild._remove_scheduled_event(scheduled_event) - self.dispatch("scheduled_event_delete", scheduled_event) - - def parse_guild_scheduled_event_user_add(self, data) -> None: - guild = self._get_guild(int(data["guild_id"])) - if guild is None: - _log.debug( - ("GUILD_SCHEDULED_EVENT_USER_ADD referencing an unknown guild ID: %s. Discarding."), - data["guild_id"], - ) - return - - payload = RawScheduledEventSubscription(data, "USER_ADD") - payload.guild = guild - self.dispatch("raw_scheduled_event_user_add", payload) - - member = guild.get_member(data["user_id"]) - if member is not None: - event = guild.get_scheduled_event(data["guild_scheduled_event_id"]) - if event: - event.subscriber_count += 1 - guild._add_scheduled_event(event) - self.dispatch("scheduled_event_user_add", event, member) - - def parse_guild_scheduled_event_user_remove(self, data) -> None: - guild = self._get_guild(int(data["guild_id"])) - if guild is None: - _log.debug( - ("GUILD_SCHEDULED_EVENT_USER_REMOVE referencing an unknown guild ID: %s. Discarding."), - data["guild_id"], - ) - return - - payload = RawScheduledEventSubscription(data, "USER_REMOVE") - payload.guild = guild - self.dispatch("raw_scheduled_event_user_remove", payload) - - member = guild.get_member(data["user_id"]) - if member is not None: - event = guild.get_scheduled_event(data["guild_scheduled_event_id"]) - if event: - event.subscriber_count += 1 - guild._add_scheduled_event(event) - self.dispatch("scheduled_event_user_remove", event, member) - - def parse_guild_integrations_update(self, data) -> None: - guild = self._get_guild(int(data["guild_id"])) - if guild is not None: - self.dispatch("guild_integrations_update", guild) - else: - _log.debug( - ("GUILD_INTEGRATIONS_UPDATE referencing an unknown guild ID: %s. Discarding."), - data["guild_id"], - ) - - def parse_integration_create(self, data) -> None: - guild_id = int(data.pop("guild_id")) - guild = self._get_guild(guild_id) - if guild is not None: - cls, _ = _integration_factory(data["type"]) - integration = cls(data=data, guild=guild) - self.dispatch("integration_create", integration) - else: - _log.debug( - "INTEGRATION_CREATE referencing an unknown guild ID: %s. Discarding.", - guild_id, - ) - - def parse_integration_update(self, data) -> None: - guild_id = int(data.pop("guild_id")) - guild = self._get_guild(guild_id) - if guild is not None: - cls, _ = _integration_factory(data["type"]) - integration = cls(data=data, guild=guild) - self.dispatch("integration_update", integration) - else: - _log.debug( - "INTEGRATION_UPDATE referencing an unknown guild ID: %s. Discarding.", - guild_id, - ) - - def parse_integration_delete(self, data) -> None: - guild_id = int(data["guild_id"]) - guild = self._get_guild(guild_id) - if guild is not None: - raw = RawIntegrationDeleteEvent(data) - self.dispatch("raw_integration_delete", raw) - else: - _log.debug( - "INTEGRATION_DELETE referencing an unknown guild ID: %s. Discarding.", - guild_id, - ) - - def parse_webhooks_update(self, data) -> None: - guild = self._get_guild(int(data["guild_id"])) - if guild is None: - _log.debug( - "WEBHOOKS_UPDATE referencing an unknown guild ID: %s. Discarding", - data["guild_id"], - ) - return - - channel_id = data["channel_id"] - if channel_id is not None: - channel = guild.get_channel(int(channel_id)) - if channel is not None: - self.dispatch("webhooks_update", channel) - else: - _log.debug( - "WEBHOOKS_UPDATE referencing an unknown channel ID: %s. Discarding.", - data["channel_id"], - ) - else: - _log.debug( - "WEBHOOKS_UPDATE channel ID was null for guild: %s. Discarding.", - data["guild_id"], - ) - - def parse_stage_instance_create(self, data) -> None: - guild = self._get_guild(int(data["guild_id"])) - if guild is not None: - stage_instance = StageInstance(guild=guild, state=self, data=data) - guild._stage_instances[stage_instance.id] = stage_instance - self.dispatch("stage_instance_create", stage_instance) - else: - _log.debug( - "STAGE_INSTANCE_CREATE referencing unknown guild ID: %s. Discarding.", - data["guild_id"], - ) - - def parse_stage_instance_update(self, data) -> None: - guild = self._get_guild(int(data["guild_id"])) - if guild is not None: - stage_instance = guild._stage_instances.get(int(data["id"])) - if stage_instance is not None: - old_stage_instance = copy.copy(stage_instance) - stage_instance._update(data) - self.dispatch("stage_instance_update", old_stage_instance, stage_instance) - else: - _log.debug( - ("STAGE_INSTANCE_UPDATE referencing unknown stage instance ID: %s. Discarding."), - data["id"], - ) - else: - _log.debug( - "STAGE_INSTANCE_UPDATE referencing unknown guild ID: %s. Discarding.", - data["guild_id"], - ) - - def parse_stage_instance_delete(self, data) -> None: - guild = self._get_guild(int(data["guild_id"])) - if guild is not None: - try: - stage_instance = guild._stage_instances.pop(int(data["id"])) - except KeyError: - pass - else: - self.dispatch("stage_instance_delete", stage_instance) - else: - _log.debug( - "STAGE_INSTANCE_DELETE referencing unknown guild ID: %s. Discarding.", - data["guild_id"], - ) - - def parse_voice_state_update(self, data) -> None: - guild = self._get_guild(get_as_snowflake(data, "guild_id")) - channel_id = get_as_snowflake(data, "channel_id") - flags = self.member_cache_flags - # self.user is *always* cached when this is called - self_id = self.user.id # type: ignore - if guild is not None: - if int(data["user_id"]) == self_id: - voice = self._get_voice_client(guild.id) - if voice is not None: - coro = voice.on_voice_state_update(data) - asyncio.create_task(logging_coroutine(coro, info="Voice Protocol voice state update handler")) - member, before, after = guild._update_voice_state(data, channel_id) # type: ignore - if member is not None: - if flags.voice: - if channel_id is None and flags._voice_only and member.id != self_id: - # Only remove from cache if we only have the voice flag enabled - # Member doesn't meet the Snowflake protocol currently - guild._remove_member(member) # type: ignore - elif channel_id is not None: - guild._add_member(member) - - self.dispatch("voice_state_update", member, before, after) - else: - _log.debug( - ("VOICE_STATE_UPDATE referencing an unknown member ID: %s. Discarding."), - data["user_id"], - ) - - def parse_voice_server_update(self, data) -> None: - try: - key_id = int(data["guild_id"]) - except KeyError: - key_id = int(data["channel_id"]) - - vc = self._get_voice_client(key_id) - if vc is not None: - coro = vc.on_voice_server_update(data) - asyncio.create_task(logging_coroutine(coro, info="Voice Protocol voice server update handler")) - - def parse_voice_channel_status_update(self, data) -> None: - raw = RawVoiceChannelStatusUpdateEvent(data) - self.dispatch("raw_voice_channel_status_update", raw) - guild = self._get_guild(int(data["guild_id"])) - channel_id = int(data["id"]) - if guild is not None: - channel = guild.get_channel(channel_id) - if channel is not None: - old_status = channel.status - channel.status = data.get("status", None) - self.dispatch("voice_channel_status_update", channel, old_status, channel.status) - else: - _log.debug( - "VOICE_CHANNEL_STATUS_UPDATE referencing an unknown channel ID: %s. Discarding.", - channel_id, - ) - else: - _log.debug( - "VOICE_CHANNEL_STATUS_UPDATE referencing unknown guild ID: %s. Discarding.", - data["guild_id"], - ) - - def parse_typing_start(self, data) -> None: - raw = RawTypingEvent(data) - - member_data = data.get("member") - if member_data: - guild = self._get_guild(raw.guild_id) - if guild is not None: - raw.member = Member(data=member_data, guild=guild, state=self) - else: - raw.member = None - else: - raw.member = None - self.dispatch("raw_typing", raw) - - channel, guild = self._get_guild_channel(data) - if channel is not None: - user = raw.member or self._get_typing_user(channel, raw.user_id) - - if user is not None: - self.dispatch("typing", channel, user, raw.when) - - def _get_typing_user(self, channel: MessageableChannel | None, user_id: int) -> User | Member | None: - if isinstance(channel, DMChannel): - return channel.recipient or self.get_user(user_id) - - elif isinstance(channel, (Thread, TextChannel)) and channel.guild is not None: - return channel.guild.get_member(user_id) # type: ignore - - elif isinstance(channel, GroupChannel): - return utils.find(lambda x: x.id == user_id, channel.recipients) - - return self.get_user(user_id) - - def _get_reaction_user(self, channel: MessageableChannel, user_id: int) -> User | Member | None: - if isinstance(channel, TextChannel): - return channel.guild.get_member(user_id) - return self.get_user(user_id) - - def get_reaction_emoji(self, data) -> GuildEmoji | AppEmoji | PartialEmoji: - emoji_id = get_as_snowflake(data, "id") - - if not emoji_id: - return data["name"] - - try: - return self._emojis[emoji_id] - except KeyError: - return PartialEmoji.with_state( - self, - animated=data.get("animated", False), - id=emoji_id, - name=data["name"], - ) - - def _upgrade_partial_emoji(self, emoji: PartialEmoji) -> GuildEmoji | AppEmoji | PartialEmoji | str: - emoji_id = emoji.id - if not emoji_id: - return emoji.name - try: - return self._emojis[emoji_id] - except KeyError: - return emoji - - def get_channel(self, id: int | None) -> Channel | Thread | None: - if id is None: - return None - - pm = self._get_private_channel(id) - if pm is not None: - return pm - - for guild in self.guilds: - channel = guild._resolve_channel(id) - if channel is not None: - return channel - - def create_message( - self, - *, - channel: MessageableChannel, - data: MessagePayload, - ) -> Message: - return Message(state=self, channel=channel, data=data) - - def parse_voice_channel_effect_send(self, data) -> None: - if sound_id := int(data.get("sound_id", 0)): - sound = self._get_sound(sound_id) - if sound is None: - sound = PartialSoundboardSound(data, self, self.http) - raw = VoiceChannelEffectSendEvent(data, self, sound) - else: - raw = VoiceChannelEffectSendEvent(data, self, None) - - self.dispatch("voice_channel_effect_send", raw) - - def _get_sound(self, sound_id: int) -> SoundboardSound | None: - return self._sounds.get(sound_id) - - def _update_sound(self, sound: SoundboardSound) -> SoundboardSound | None: - before = self._sounds.get(sound.id) - self._sounds[sound.id] = sound - return before - - def parse_soundboard_sounds(self, data) -> None: - guild_id = int(data["guild_id"]) - for sound_data in data["soundboard_sounds"]: - self._add_sound(SoundboardSound(state=self, http=self.http, data=sound_data, guild_id=guild_id)) - - def parse_guild_soundboard_sounds_update(self, data): - before_sounds = [] - after_sounds = [] - for sound_data in data["soundboard_sounds"]: - after = SoundboardSound(state=self, http=self.http, data=sound_data) - if before := self._update_sound(after): - before_sounds.append(before) - after_sounds.append(after) - if len(before_sounds) == len(after_sounds): - self.dispatch("soundboard_sounds_update", before_sounds, after_sounds) - self.dispatch("raw_soundboard_sounds_update", after_sounds) - - def parse_guild_soundboard_sound_update(self, data): - after = SoundboardSound(state=self, http=self.http, data=data) - if before := self._update_sound(after): - self.dispatch("soundboard_sound_update", before, after) - self.dispatch("raw_soundboard_sound_update", after) - - def parse_guild_soundboard_sound_create(self, data): - sound = SoundboardSound(state=self, http=self.http, data=data) - self._add_sound(sound) - self.dispatch("soundboard_sound_create", sound) - - def parse_guild_soundboard_sound_delete(self, data): - sound_id = int(data["sound_id"]) - sound = self._get_sound(sound_id) - if sound is not None: - self._remove_sound(sound) - self.dispatch("soundboard_sound_delete", sound) - self.dispatch("raw_soundboard_sound_delete", RawSoundboardSoundDeleteEvent(data)) - - async def _add_default_sounds(self) -> None: - default_sounds = await self.http.get_default_sounds() - for default_sound in default_sounds: - sound = SoundboardSound(state=self, http=self.http, data=default_sound) - self._add_sound(sound) - - def _add_sound(self, sound: SoundboardSound) -> None: - self._sounds[sound.id] = sound - - def _remove_sound(self, sound: SoundboardSound) -> None: - self._sounds.pop(sound.id, None) - - @property - def sounds(self) -> list[SoundboardSound]: - return list(self._sounds.values()) - - -class AutoShardedConnectionState(ConnectionState): - def __init__(self, *args: Any, **kwargs: Any) -> None: - super().__init__(*args, **kwargs) - self.shard_ids: list[int] | range = [] - self.shards_launched: asyncio.Event = asyncio.Event() - - def _update_message_references(self) -> None: - # self._messages won't be None when this is called - for msg in self._messages: # type: ignore - if not msg.guild: - continue - - new_guild = self._get_guild(msg.guild.id) - if new_guild is not None and new_guild is not msg.guild: - channel_id = msg.channel.id - channel = new_guild._resolve_channel(channel_id) or Object(id=channel_id) - # channel will either be a TextChannel, Thread or Object - msg._rebind_cached_references(new_guild, channel) # type: ignore - - async def chunker( - self, - guild_id: int, - query: str = "", - limit: int = 0, - presences: bool = False, - *, - shard_id: int | None = None, - nonce: str | None = None, - ) -> None: - ws = self._get_websocket(guild_id, shard_id=shard_id) - await ws.request_chunks(guild_id, query=query, limit=limit, presences=presences, nonce=nonce) - - async def _delay_ready(self) -> None: - await self.shards_launched.wait() - processed = [] - max_concurrency = len(self.shard_ids) * 2 - current_bucket = [] - while True: - # this snippet of code is basically waiting N seconds - # until the last GUILD_CREATE was sent - try: - guild = await asyncio.wait_for(self._ready_state.get(), timeout=self.guild_ready_timeout) - except asyncio.TimeoutError: - break - else: - if self._guild_needs_chunking(guild): - _log.debug( - ("Guild ID %d requires chunking, will be done in the background."), - guild.id, - ) - if len(current_bucket) >= max_concurrency: - try: - await sane_wait_for(current_bucket, timeout=max_concurrency * 70.0) - except asyncio.TimeoutError: - fmt = "Shard ID %s failed to wait for chunks from a sub-bucket with length %d" - _log.warning(fmt, guild.shard_id, len(current_bucket)) - finally: - current_bucket = [] - - # Chunk the guild in the background while we wait for GUILD_CREATE streaming - future = asyncio.ensure_future(self.chunk_guild(guild)) - current_bucket.append(future) - else: - future = self.loop.create_future() - future.set_result([]) - - processed.append((guild, future)) - - guilds = sorted(processed, key=lambda g: g[0].shard_id) - for shard_id, info in itertools.groupby(guilds, key=lambda g: g[0].shard_id): - children, futures = zip(*info, strict=False) - # 110 reqs/minute w/ 1 req/guild plus some buffer - timeout = 61 * (len(children) / 110) - try: - await sane_wait_for(futures, timeout=timeout) - except asyncio.TimeoutError: - _log.warning( - ("Shard ID %s failed to wait for chunks (timeout=%.2f) for %d guilds"), - shard_id, - timeout, - len(guilds), - ) - for guild in children: - if guild.unavailable is False: - self.dispatch("guild_available", guild) - else: - self.dispatch("guild_join", guild) - - self.dispatch("shard_ready", shard_id) - - if self.cache_app_emojis and self.application_id: - data = await self.http.get_all_application_emojis(self.application_id) - for e in data.get("items", []): - self.maybe_store_app_emoji(self.application_id, e) - - # remove the state - try: - del self._ready_state - except AttributeError: - pass # already been deleted somehow - - # clear the current task - self._ready_task = None - - # dispatch the event - self.call_handlers("ready") - self.dispatch("ready") - - def parse_ready(self, data) -> None: - if not hasattr(self, "_ready_state"): - self._ready_state = asyncio.Queue() - - self.user = user = ClientUser(state=self, data=data["user"]) - # self._users is a list of Users, we're setting a ClientUser - self._users[user.id] = user # type: ignore - - if self.application_id is None: - try: - application = data["application"] - except KeyError: - pass - else: - self.application_id = get_as_snowflake(application, "id") - self.application_flags = ApplicationFlags._from_value(application["flags"]) - - for guild_data in data["guilds"]: - self._add_guild_from_data(guild_data) - - if self._messages: - self._update_message_references() - - self.dispatch("connect") - self.dispatch("shard_connect", data["__shard_id__"]) - - if self._ready_task is None: - self._ready_task = asyncio.create_task(self._delay_ready()) - - def parse_resumed(self, data) -> None: - self.dispatch("resumed") - self.dispatch("shard_resumed", data["__shard_id__"]) diff --git a/discord/sticker.py b/discord/sticker.py index 6fb3e5ba38..a73b19bd0a 100644 --- a/discord/sticker.py +++ b/discord/sticker.py @@ -46,8 +46,8 @@ if TYPE_CHECKING: import datetime + from .app.state import ConnectionState from .guild import Guild - from .state import ConnectionState from .types.sticker import EditGuildSticker from .types.sticker import GuildSticker as GuildStickerPayload from .types.sticker import ListPremiumStickerPacks as ListPremiumStickerPacksPayload @@ -417,7 +417,7 @@ class GuildSticker(Sticker): The name of a unicode emoji that represents this sticker. """ - __slots__ = ("available", "guild_id", "user", "emoji", "type", "_cs_guild") + __slots__ = ("available", "guild_id", "user", "emoji", "type") def _from_data(self, data: GuildStickerPayload) -> None: super()._from_data(data) @@ -431,14 +431,13 @@ def _from_data(self, data: GuildStickerPayload) -> None: def __repr__(self) -> str: return f"" - @cached_slot_property("_cs_guild") - def guild(self) -> Guild | None: + async def get_guild(self) -> Guild | None: """The guild that this sticker is from. Could be ``None`` if the bot is not in the guild. .. versionadded:: 2.0 """ - return self._state._get_guild(self.guild_id) + return await self._state._get_guild(self.guild_id) async def edit( self, diff --git a/discord/team.py b/discord/team.py index ee3a14408b..e2e4436367 100644 --- a/discord/team.py +++ b/discord/team.py @@ -34,7 +34,7 @@ from .utils.private import get_as_snowflake if TYPE_CHECKING: - from .state import ConnectionState + from .app.state import ConnectionState from .types.team import Team as TeamPayload from .types.team import TeamMember as TeamMemberPayload diff --git a/discord/template.py b/discord/template.py index e5336fd5ed..91efe14966 100644 --- a/discord/template.py +++ b/discord/template.py @@ -36,7 +36,7 @@ if TYPE_CHECKING: import datetime - from .state import ConnectionState + from .app.state import ConnectionState from .types.template import Template as TemplatePayload from .user import User @@ -78,8 +78,8 @@ def _get_voice_client(self, id): def _get_message(self, id): return None - def _get_guild(self, id): - return self.__state._get_guild(id) + async def _get_guild(self, id): + return await self.__state._get_guild(id) async def query_members(self, **kwargs: Any): return [] @@ -131,11 +131,11 @@ class Template: "_state", ) - def __init__(self, *, state: ConnectionState, data: TemplatePayload) -> None: + @classmethod + async def from_data(cls, state: ConnectionState, data: TemplatePayload) -> None: + self = cls() self._state = state - self._store(data) - def _store(self, data: TemplatePayload) -> None: self.code: str = data["code"] self.uses: int = data["usage_count"] self.name: str = data["name"] @@ -147,7 +147,7 @@ def _store(self, data: TemplatePayload) -> None: self.updated_at: datetime.datetime | None = parse_time(data.get("updated_at")) guild_id = int(data["source_guild_id"]) - guild: Guild | None = self._state._get_guild(guild_id) + guild: Guild | None = await self._state._get_guild(guild_id) self.source_guild: Guild if guild is None: @@ -155,7 +155,7 @@ def _store(self, data: TemplatePayload) -> None: source_serialised["id"] = guild_id state = _PartialTemplateState(state=self._state) # Guild expects a ConnectionState, we're passing a _PartialTemplateState - self.source_guild = Guild(data=source_serialised, state=state) # type: ignore + self.source_guild = await Guild._from_data(data=source_serialised, state=state) # type: ignore else: self.source_guild = guild @@ -199,7 +199,7 @@ async def create_guild(self, name: str, icon: Any = None) -> Guild: icon = bytes_to_base64_data(icon) data = await self._state.http.create_from_template(self.code, name, icon) - return Guild(data=data, state=self._state) + return await Guild._from_data(data=data, state=self._state) async def sync(self) -> Template: """|coro| @@ -230,7 +230,7 @@ async def sync(self) -> Template: """ data = await self._state.http.sync_template(self.source_guild.id, self.code) - return Template(state=self._state, data=data) + return await Template.from_data(state=self._state, data=data) async def edit( self, @@ -279,7 +279,7 @@ async def edit( payload["description"] = description data = await self._state.http.edit_template(self.source_guild.id, self.code, payload) - return Template(state=self._state, data=data) + return await Template.from_data(state=self._state, data=data) async def delete(self) -> None: """|coro| diff --git a/discord/threads.py b/discord/threads.py index 3a8e9e884b..1f2a7600a4 100644 --- a/discord/threads.py +++ b/discord/threads.py @@ -48,13 +48,13 @@ if TYPE_CHECKING: from .abc import Snowflake, SnowflakeTime + from .app.state import ConnectionState from .channel import CategoryChannel, ForumChannel, ForumTag, TextChannel from .guild import Guild from .member import Member from .message import Message, PartialMessage from .permissions import Permissions from .role import Role - from .state import ConnectionState from .types.snowflake import SnowflakeList from .types.threads import Thread as ThreadPayload from .types.threads import ThreadArchiveDuration, ThreadMetadata @@ -229,7 +229,7 @@ def _unroll_metadata(self, data: ThreadMetadata): self.invitable = data.get("invitable", True) self.created_at = parse_time(data.get("create_timestamp", None)) - def _update(self, data): + async def _update(self, data): try: self.name = data["name"] except KeyError: @@ -254,10 +254,9 @@ def parent(self) -> TextChannel | ForumChannel | None: """The parent channel this thread belongs to.""" return self.guild.get_channel(self.parent_id) # type: ignore - @property - def owner(self) -> Member | None: + async def get_owner(self) -> Member | None: """The member this thread belongs to.""" - return self.guild.get_member(self.owner_id) + return await self.guild.get_member(self.owner_id) @property def mention(self) -> str: @@ -294,8 +293,7 @@ def applied_tags(self) -> list[ForumTag]: return [tag for tag_id in self._applied_tags if (tag := self.parent.get_tag(tag_id)) is not None] return [] - @property - def last_message(self) -> Message | None: + async def get_last_message(self) -> Message | None: """Returns the last message from this thread in cache. The message might not be valid or point to an existing message. @@ -313,7 +311,7 @@ def last_message(self) -> Message | None: Optional[:class:`Message`] The last message in this channel or ``None`` if not found. """ - return self._state._get_message(self.last_message_id) if self.last_message_id else None + return await self._state._get_message(self.last_message_id) if self.last_message_id else None @property def category(self) -> CategoryChannel | None: @@ -355,8 +353,7 @@ def category_id(self) -> int | None: raise ClientException("Parent channel not found") return parent.category_id - @property - def starting_message(self) -> Message | None: + async def get_starting_message(self) -> Message | None: """Returns the message that started this thread. The message might not be valid or point to an existing message. @@ -369,7 +366,7 @@ def starting_message(self) -> Message | None: Optional[:class:`Message`] The message that started this thread or ``None`` if not found in the cache. """ - return self._state._get_message(self.id) + return await self._state._get_message(self.id) def is_pinned(self) -> bool: """Whether the thread is pinned to the top of its parent forum or media channel. diff --git a/discord/types/member.py b/discord/types/member.py index 618bb13efe..e2796dd88e 100644 --- a/discord/types/member.py +++ b/discord/types/member.py @@ -35,7 +35,7 @@ class Nickname(TypedDict): class PartialMember(TypedDict): roles: SnowflakeList - joined_at: str + joined_at: str | None deaf: bool mute: bool diff --git a/discord/ui/modal.py b/discord/ui/modal.py index f59d7bf962..86d5fd2800 100644 --- a/discord/ui/modal.py +++ b/discord/ui/modal.py @@ -10,17 +10,14 @@ from .input_text import InputText -__all__ = ( - "Modal", - "ModalStore", -) +__all__ = ("Modal",) if TYPE_CHECKING: from typing_extensions import Self + from ..app.state import ConnectionState from ..interactions import Interaction - from ..state import ConnectionState class Modal: @@ -78,16 +75,6 @@ def __repr__(self) -> str: attrs = " ".join(f"{key}={getattr(self, key)!r}" for key in self.__item_repr_attributes__) return f"<{self.__class__.__name__} {attrs}>" - def _start_listening_from_store(self, store: ModalStore) -> None: - self.__cancel_callback = partial(store.remove_modal) - if self.timeout: - loop = asyncio.get_running_loop() - if self.__timeout_task is not None: - self.__timeout_task.cancel() - - self.__timeout_expiry = time.monotonic() + self.timeout - self.__timeout_task = loop.create_task(self.__timeout_task_impl()) - async def __timeout_task_impl(self) -> None: while True: # Guard just in case someone changes the value of the timeout at runtime @@ -304,41 +291,3 @@ def remove_item(self, item: InputText) -> None: def clear(self) -> None: self.weights = [0, 0, 0, 0, 0] - - -class ModalStore: - def __init__(self, state: ConnectionState) -> None: - # (user_id, custom_id) : Modal - self._modals: dict[tuple[int, str], Modal] = {} - self._state: ConnectionState = state - - def add_modal(self, modal: Modal, user_id: int): - self._modals[(user_id, modal.custom_id)] = modal - modal._start_listening_from_store(self) - - def remove_modal(self, modal: Modal, user_id): - modal.stop() - self._modals.pop((user_id, modal.custom_id)) - - async def dispatch(self, user_id: int, custom_id: str, interaction: Interaction): - key = (user_id, custom_id) - value = self._modals.get(key) - if value is None: - return - interaction.modal = value - - try: - components = [ - component - for parent_component in interaction.data["components"] - for component in parent_component["components"] - ] - for component in components: - for child in value.children: - if child.custom_id == component["custom_id"]: # type: ignore - child.refresh_state(component) - break - await value.callback(interaction) - self.remove_modal(value, user_id) - except Exception as e: - return await value.on_error(e, interaction) diff --git a/discord/ui/select.py b/discord/ui/select.py index 43cabd249c..6ee54a0514 100644 --- a/discord/ui/select.py +++ b/discord/ui/select.py @@ -72,7 +72,7 @@ class Select(Item[V]): This is usually represented as a drop down menu. - In order to get the selected items that the user has chosen, use :attr:`Select.values`. + In order to get the selected items that the user has chosen, use :meth:`Select.get_values`. .. versionadded:: 2.0 @@ -332,8 +332,7 @@ def append_option(self, option: SelectOption) -> Self: self._underlying.options.append(option) return self - @property - def values( + async def get_values( self, ) -> list[str] | list[Member | User] | list[Role] | list[Member | User | Role] | list[GuildChannel | Thread]: """List[:class:`str`] | List[:class:`discord.Member` | :class:`discord.User`]] | List[:class:`discord.Role`]] | @@ -382,7 +381,7 @@ def values( member = dict(_member_data) member["user"] = _data _data = member - result = guild._get_and_update_member(_data, int(_id), cache_flag) + result = await guild._get_and_update_member(_data, int(_id), cache_flag) else: result = User(state=state, data=_data) resolved.append(result) @@ -463,7 +462,7 @@ def select( the :class:`discord.Interaction` you receive. In order to get the selected items that the user has chosen within the callback - use :attr:`Select.values`. + use :meth:`Select.get_values`. .. versionchanged:: 2.3 diff --git a/discord/ui/view.py b/discord/ui/view.py index 81b60d6568..374ef5bfa5 100644 --- a/discord/ui/view.py +++ b/discord/ui/view.py @@ -50,9 +50,9 @@ if TYPE_CHECKING: + from ..app.state import ConnectionState from ..interactions import Interaction, InteractionMessage from ..message import Message - from ..state import ConnectionState from ..types.components import Component as ComponentPayload V = TypeVar("V", bound="View", covariant=True) @@ -532,16 +532,6 @@ async def _scheduled_task(self, item: Item[V], interaction: Interaction): except Exception as e: return await self.on_error(e, item, interaction) - def _start_listening_from_store(self, store: ViewStore) -> None: - self.__cancel_callback = partial(store.remove_view) - if self.timeout: - loop = asyncio.get_running_loop() - if self.__timeout_task is not None: - self.__timeout_task.cancel() - - self.__timeout_expiry = time.monotonic() + self.timeout - self.__timeout_task = loop.create_task(self.__timeout_task_impl()) - def _dispatch_timeout(self): if self.__stopped.done(): return @@ -692,74 +682,3 @@ def message(self): @message.setter def message(self, value): self._message = value - - -class ViewStore: - def __init__(self, state: ConnectionState): - # (component_type, message_id, custom_id): (View, Item) - self._views: dict[tuple[int, int | None, str], tuple[View, Item[V]]] = {} - # message_id: View - self._synced_message_views: dict[int, View] = {} - self._state: ConnectionState = state - - @property - def persistent_views(self) -> Sequence[View]: - views = {view.id: view for (_, (view, _)) in self._views.items() if view.is_persistent()} - return list(views.values()) - - def __verify_integrity(self): - to_remove: list[tuple[int, int | None, str]] = [] - for k, (view, _) in self._views.items(): - if view.is_finished(): - to_remove.append(k) - - for k in to_remove: - del self._views[k] - - def add_view(self, view: View, message_id: int | None = None): - self.__verify_integrity() - - view._start_listening_from_store(self) - for item in view.walk_children(): - if item.is_storable(): - self._views[(item.type.value, message_id, item.custom_id)] = (view, item) # type: ignore - - if message_id is not None: - self._synced_message_views[message_id] = view - - def remove_view(self, view: View): - for item in view.walk_children(): - if item.is_storable(): - self._views.pop((item.type.value, item.custom_id), None) # type: ignore - - for key, value in self._synced_message_views.items(): - if value.id == view.id: - del self._synced_message_views[key] - break - - def dispatch(self, component_type: int, custom_id: str, interaction: Interaction): - self.__verify_integrity() - message_id: int | None = interaction.message and interaction.message.id - key = (component_type, message_id, custom_id) - # Fallback to None message_id searches in case a persistent view - # was added without an associated message_id - value = self._views.get(key) or self._views.get((component_type, None, custom_id)) - if value is None: - return - - view, item = value - interaction.view = view - item.refresh_state(interaction) - view._dispatch_item(item, interaction) - - def is_message_tracked(self, message_id: int): - return message_id in self._synced_message_views - - def remove_message_tracking(self, message_id: int) -> View | None: - return self._synced_message_views.pop(message_id, None) - - def update_from_message(self, message_id: int, components: list[ComponentPayload]): - # pre-req: is_message_tracked == true - view = self._synced_message_views[message_id] - components = [_component_factory(d, state=self._state) for d in components] - view.refresh(components) diff --git a/discord/user.py b/discord/user.py index 046c251295..e945154243 100644 --- a/discord/user.py +++ b/discord/user.py @@ -25,6 +25,7 @@ from __future__ import annotations +import asyncio from typing import TYPE_CHECKING, Any, TypeVar import discord.abc @@ -43,10 +44,10 @@ from datetime import datetime from .abc import Snowflake, SnowflakeTime + from .app.state import ConnectionState from .channel import DMChannel from .guild import Guild from .message import Message - from .state import ConnectionState from .types.channel import DMChannel as DMChannelPayload from .types.user import PartialUser as PartialUserPayload from .types.user import User as UserPayload @@ -131,7 +132,7 @@ def __eq__(self, other: Any) -> bool: def __hash__(self) -> int: return self.id >> 22 - def _update(self, data: UserPayload) -> None: + async def _update(self, data: UserPayload) -> None: self.name = data["username"] self.id = int(data["id"]) self.discriminator = data["discriminator"] @@ -423,7 +424,7 @@ def __repr__(self) -> str: f" bot={self.bot} verified={self.verified} mfa_enabled={self.mfa_enabled}>" ) - def _update(self, data: UserPayload) -> None: + async def _update(self, data: UserPayload) -> None: super()._update(data) # There's actually an Optional[str] phone field as well, but I won't use it self.verified = data.get("verified", False) @@ -566,7 +567,7 @@ def __repr__(self) -> str: def __del__(self) -> None: try: if self._stored: - self._state.deref_user(self.id) + asyncio.create_task(self._state.deref_user(self.id)) except Exception: pass @@ -580,17 +581,15 @@ async def _get_channel(self) -> DMChannel: ch = await self.create_dm() return ch - @property - def dm_channel(self) -> DMChannel | None: + async def get_dm_channel(self) -> DMChannel | None: """Returns the channel associated with this user if it exists. If this returns ``None``, you can create a DM channel by calling the :meth:`create_dm` coroutine function. """ - return self._state._get_private_channel_by_user(self.id) + return await self._state._get_private_channel_by_user(self.id) - @property - def mutual_guilds(self) -> list[Guild]: + async def get_mutual_guilds(self) -> list[Guild]: """The guilds that the user shares with the client. .. note:: @@ -599,7 +598,7 @@ def mutual_guilds(self) -> list[Guild]: .. versionadded:: 1.7 """ - return [guild for guild in self._state._guilds.values() if guild.get_member(self.id)] + return [guild for guild in await self._state.cache.get_all_guilds() if await guild.get_member(self.id)] async def create_dm(self) -> DMChannel: """|coro| @@ -620,7 +619,7 @@ async def create_dm(self) -> DMChannel: state = self._state data: DMChannelPayload = await state.http.start_private_message(self.id) - return state.add_dm_channel(data) + return await state.add_dm_channel(data) async def create_test_entitlement(self, sku: discord.abc.Snowflake) -> Entitlement: """|coro| diff --git a/discord/voice_client.py b/discord/voice_client.py index bc4e2196a3..e76cd4bd26 100644 --- a/discord/voice_client.py +++ b/discord/voice_client.py @@ -60,10 +60,10 @@ if TYPE_CHECKING: from . import abc + from .app.state import ConnectionState from .client import Client from .guild import Guild from .opus import Encoder - from .state import ConnectionState from .types.voice import GuildVoiceState as GuildVoiceStatePayload from .types.voice import SupportedModes from .types.voice import VoiceServerUpdate as VoiceServerUpdatePayload diff --git a/discord/webhook/async_.py b/discord/webhook/async_.py index a11ac45913..c5ad2d019c 100644 --- a/discord/webhook/async_.py +++ b/discord/webhook/async_.py @@ -70,6 +70,7 @@ import datetime from ..abc import Snowflake + from ..app.state import ConnectionState from ..channel import TextChannel from ..embeds import Embed from ..file import File @@ -77,7 +78,6 @@ from ..http import Response from ..mentions import AllowedMentions from ..poll import Poll - from ..state import ConnectionState from ..types.message import Message as MessagePayload from ..types.webhook import FollowerWebhook as FollowerWebhookPayload from ..types.webhook import Webhook as WebhookPayload @@ -825,9 +825,9 @@ def create_user(self, data): # state parameter is artificial return BaseUser(state=self, data=data) # type: ignore - def store_poll(self, poll: Poll, message_id: int): + async def store_poll(self, poll: Poll, message_id: int): if self._parent is not None: - return self._parent.store_poll(poll, message_id) + return await self._parent.store_poll(poll, message_id) # state parameter is artificial return None @@ -1028,7 +1028,7 @@ def __init__( self._state: ConnectionState | _WebhookState = state or _WebhookState(self, parent=state) self._update(data) - def _update(self, data: WebhookPayload | FollowerWebhookPayload): + async def _update(self, data: WebhookPayload | FollowerWebhookPayload): self.id = int(data["id"]) self.type = try_enum(WebhookType, int(data["type"])) self.channel_id = get_as_snowflake(data, "channel_id") @@ -1069,13 +1069,12 @@ def is_authenticated(self) -> bool: """ return self.auth_token is not None - @property - def guild(self) -> Guild | None: + async def get_guild(self) -> Guild | None: """The guild this webhook belongs to. If this is a partial webhook, then this will always return ``None``. """ - return self._state and self._state._get_guild(self.guild_id) + return self._state and await self._state._get_guild(self.guild_id) @property def channel(self) -> TextChannel | None: @@ -1824,12 +1823,11 @@ async def send( msg = self._create_message(data) if view is not MISSING and not view.is_finished(): - message_id = None if msg is None else msg.id view.message = None if msg is None else msg if msg: view.refresh(msg.components) if view.is_dispatchable(): - self._state.store_view(view, message_id) + await self._state.store_view(view) if delete_after is not None: @@ -1984,7 +1982,7 @@ async def edit_message( if isinstance(self._state, _WebhookState) and view and view.is_dispatchable(): raise InvalidArgument("Dispatchable Webhook views require an associated state with the webhook") - self._state.prevent_view_updates_for(message_id) + await self._state.prevent_view_updates_for(message_id) if self.type is not WebhookType.application: with_components = True @@ -2026,7 +2024,7 @@ async def edit_message( view.message = message view.refresh(message.components) if view.is_dispatchable(): - self._state.store_view(view, message_id) + await self._state.store_view(view) return message async def delete_message(self, message_id: int, *, thread_id: int | None = None) -> None: diff --git a/discord/welcome_screen.py b/discord/welcome_screen.py index 57286c1c70..a41cbbe0a5 100644 --- a/discord/welcome_screen.py +++ b/discord/welcome_screen.py @@ -128,7 +128,7 @@ def __init__(self, data: WelcomeScreenPayload, guild: Guild): def __repr__(self): return f" Invite: """ invite_id = resolve_invite(self._invite) data = await self._state.http.get_invite(invite_id, with_counts=with_counts) - return Invite.from_incomplete(state=self._state, data=data) + return await Invite.from_incomplete(state=self._state, data=data) diff --git a/docs/api/enums.rst b/docs/api/enums.rst index 7ceb0db38a..8b7b600d2d 100644 --- a/docs/api/enums.rst +++ b/docs/api/enums.rst @@ -821,7 +821,7 @@ of :class:`enum.Enum`. - Changing the guild moderation settings - Changing things related to the guild widget - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Guild`. Possible attributes for :class:`AuditLogDiff`: @@ -844,7 +844,7 @@ of :class:`enum.Enum`. A new channel was created. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID. A more filled out object in the :class:`Object` case can be found @@ -863,7 +863,7 @@ of :class:`enum.Enum`. - The channel name or topic was changed - The channel bitrate was changed - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID. A more filled out object in the :class:`Object` case can be found @@ -885,7 +885,7 @@ of :class:`enum.Enum`. A channel was deleted. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with an ID. A more filled out object can be found by using the @@ -901,7 +901,7 @@ of :class:`enum.Enum`. A channel permission overwrite was created. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID. When this is the action, the type of :attr:`~AuditLogEntry.extra` is @@ -923,7 +923,7 @@ of :class:`enum.Enum`. when the permission values change. See :attr:`overwrite_create` for more information on how the - :attr:`~AuditLogEntry.target` and :attr:`~AuditLogEntry.extra` fields + :func:`~AuditLogEntry.get_target` and :attr:`~AuditLogEntry.extra` fields are set. Possible attributes for :class:`AuditLogDiff`: @@ -938,7 +938,7 @@ of :class:`enum.Enum`. A channel permission overwrite was deleted. See :attr:`overwrite_create` for more information on how the - :attr:`~AuditLogEntry.target` and :attr:`~AuditLogEntry.extra` fields + :func:`~AuditLogEntry.get_target` and :attr:`~AuditLogEntry.extra` fields are set. Possible attributes for :class:`AuditLogDiff`: @@ -952,7 +952,7 @@ of :class:`enum.Enum`. A member was kicked. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got kicked. When this is the action, :attr:`~AuditLogEntry.changes` is empty. @@ -961,7 +961,7 @@ of :class:`enum.Enum`. A member prune was triggered. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is set to ``None``. When this is the action, the type of :attr:`~AuditLogEntry.extra` is @@ -976,7 +976,7 @@ of :class:`enum.Enum`. A member was banned. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got banned. When this is the action, :attr:`~AuditLogEntry.changes` is empty. @@ -985,7 +985,7 @@ of :class:`enum.Enum`. A member was unbanned. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got unbanned. When this is the action, :attr:`~AuditLogEntry.changes` is empty. @@ -997,7 +997,7 @@ of :class:`enum.Enum`. - A nickname was changed - They were server muted or deafened (or it was undone) - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got updated. Possible attributes for :class:`AuditLogDiff`: @@ -1011,7 +1011,7 @@ of :class:`enum.Enum`. A member's role has been updated. This triggers when a member either gains a role or loses a role. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got the role. Possible attributes for :class:`AuditLogDiff`: @@ -1047,7 +1047,7 @@ of :class:`enum.Enum`. A bot was added to the guild. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` which was added to the guild. .. versionadded:: 1.3 @@ -1056,7 +1056,7 @@ of :class:`enum.Enum`. A new role was created. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Role` or a :class:`Object` with the ID. Possible attributes for :class:`AuditLogDiff`: @@ -1076,7 +1076,7 @@ of :class:`enum.Enum`. - The colour has changed - Its hoist/mentionable state has changed - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Role` or a :class:`Object` with the ID. Possible attributes for :class:`AuditLogDiff`: @@ -1091,7 +1091,7 @@ of :class:`enum.Enum`. A role was deleted. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Role` or a :class:`Object` with the ID. Possible attributes for :class:`AuditLogDiff`: @@ -1106,7 +1106,7 @@ of :class:`enum.Enum`. An invite was created. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was created. Possible attributes for :class:`AuditLogDiff`: @@ -1123,14 +1123,14 @@ of :class:`enum.Enum`. An invite was updated. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was updated. .. attribute:: invite_delete An invite was deleted. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was deleted. Possible attributes for :class:`AuditLogDiff`: @@ -1147,7 +1147,7 @@ of :class:`enum.Enum`. A webhook was created. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the webhook ID. Possible attributes for :class:`AuditLogDiff`: @@ -1163,7 +1163,7 @@ of :class:`enum.Enum`. - The webhook name changed - The webhook channel changed - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the webhook ID. Possible attributes for :class:`AuditLogDiff`: @@ -1176,7 +1176,7 @@ of :class:`enum.Enum`. A webhook was deleted. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the webhook ID. Possible attributes for :class:`AuditLogDiff`: @@ -1189,7 +1189,7 @@ of :class:`enum.Enum`. An emoji was created. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID. Possible attributes for :class:`AuditLogDiff`: @@ -1200,7 +1200,7 @@ of :class:`enum.Enum`. An emoji was updated. This triggers when the name has changed. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID. Possible attributes for :class:`AuditLogDiff`: @@ -1211,7 +1211,7 @@ of :class:`enum.Enum`. An emoji was deleted. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the emoji ID. Possible attributes for :class:`AuditLogDiff`: @@ -1223,7 +1223,7 @@ of :class:`enum.Enum`. A message was deleted by a moderator. Note that this only triggers if the message was deleted by someone other than the author. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message deleted. When this is the action, the type of :attr:`~AuditLogEntry.extra` is @@ -1236,7 +1236,7 @@ of :class:`enum.Enum`. Messages were bulk deleted by a moderator. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged. When this is the action, the type of :attr:`~AuditLogEntry.extra` is @@ -1250,7 +1250,7 @@ of :class:`enum.Enum`. A message was pinned in a channel. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message pinned. When this is the action, the type of :attr:`~AuditLogEntry.extra` is @@ -1265,7 +1265,7 @@ of :class:`enum.Enum`. A message was unpinned in a channel. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message unpinned. When this is the action, the type of :attr:`~AuditLogEntry.extra` is @@ -1280,7 +1280,7 @@ of :class:`enum.Enum`. A guild integration was created. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was created. .. versionadded:: 1.3 @@ -1289,7 +1289,7 @@ of :class:`enum.Enum`. A guild integration was updated. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was updated. .. versionadded:: 1.3 @@ -1298,7 +1298,7 @@ of :class:`enum.Enum`. A guild integration was deleted. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was deleted. .. versionadded:: 1.3 @@ -1307,7 +1307,7 @@ of :class:`enum.Enum`. A stage instance was started. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created. @@ -1322,7 +1322,7 @@ of :class:`enum.Enum`. A stage instance was updated. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated. @@ -1343,7 +1343,7 @@ of :class:`enum.Enum`. A sticker was created. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated. @@ -1362,7 +1362,7 @@ of :class:`enum.Enum`. A sticker was updated. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated. @@ -1381,7 +1381,7 @@ of :class:`enum.Enum`. A sticker was deleted. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated. @@ -1400,7 +1400,7 @@ of :class:`enum.Enum`. A scheduled event was created. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted. @@ -1421,7 +1421,7 @@ of :class:`enum.Enum`. A scheduled event was updated. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted. @@ -1442,7 +1442,7 @@ of :class:`enum.Enum`. A scheduled event was deleted. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted. @@ -1463,7 +1463,7 @@ of :class:`enum.Enum`. A thread was created. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created. @@ -1481,7 +1481,7 @@ of :class:`enum.Enum`. A thread was updated. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated. @@ -1499,7 +1499,7 @@ of :class:`enum.Enum`. A thread was deleted. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted. @@ -1517,7 +1517,7 @@ of :class:`enum.Enum`. An application command's permissions were updated. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with the ID of the command that had it's permissions edited. @@ -1611,7 +1611,7 @@ of :class:`enum.Enum`. A voice channel status was updated. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated. @@ -1625,7 +1625,7 @@ of :class:`enum.Enum`. A voice channel status was deleted. - When this is the action, the type of :attr:`~AuditLogEntry.target` is + When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated. diff --git a/docs/api/events.rst b/docs/api/events.rst index 45d8c1e279..c948fe972b 100644 --- a/docs/api/events.rst +++ b/docs/api/events.rst @@ -328,7 +328,7 @@ Connection .. function:: on_ready() Called when the client is done preparing the data received from Discord. Usually after login is successful - and the :attr:`Client.guilds` and co. are filled up. + and the :func:`Client.get_guilds` and co. are filled up. .. warning:: @@ -434,7 +434,7 @@ Guilds - The client or the guild owner deleted the guild. In order for this event to be invoked then the :class:`Client` must have - been part of the guild to begin with. (i.e. it is part of :attr:`Client.guilds`) + been part of the guild to begin with. (i.e. it is part of :func:`Client.get_guilds`) This requires :attr:`Intents.guilds` to be enabled. @@ -512,7 +512,7 @@ Guilds on_guild_unavailable(guild) Called when a guild becomes available or unavailable. The guild must have - existed in the :attr:`Client.guilds` cache. + existed in the :func:`Client.get_guilds` cache. This requires :attr:`Intents.guilds` to be enabled. diff --git a/docs/build/locales/api/enums.pot b/docs/build/locales/api/enums.pot index 400416b350..6340980d34 100644 --- a/docs/build/locales/api/enums.pot +++ b/docs/build/locales/api/enums.pot @@ -1103,7 +1103,7 @@ msgstr "" #: ../../api/enums.rst:824 #: c890e719787243a5af28be7c6f82f77b -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Guild`." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Guild`." msgstr "" #: ../../api/enums.rst:827 @@ -1303,7 +1303,7 @@ msgstr "" #: ../../api/enums.rst:847 #: e00bbae1ecc54cd4aa7b2f97761a2857 -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." msgstr "" #: ../../api/enums.rst:850 @@ -1360,7 +1360,7 @@ msgstr "" #: ../../api/enums.rst:904 #: 8f81efbdafac4745899e4ad861717ecd #: 5257b72e408a46d4a7b06498d32f7209 -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." msgstr "" #: ../../api/enums.rst:869 @@ -1409,7 +1409,7 @@ msgstr "" #: ../../api/enums.rst:888 #: 5af5984da736481eae7b9ec37355167b -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with an ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with an ID." msgstr "" #: ../../api/enums.rst:891 @@ -1463,7 +1463,7 @@ msgstr "" #: ../../api/enums.rst:940 #: b74dea0f59eb486f98c229b259e001f9 #: 548a7a8ca0314acf9735eac331d866e9 -msgid "See :attr:`overwrite_create` for more information on how the :attr:`~AuditLogEntry.target` and :attr:`~AuditLogEntry.extra` fields are set." +msgid "See :attr:`overwrite_create` for more information on how the :func:`~AuditLogEntry.get_target` and :attr:`~AuditLogEntry.extra` fields are set." msgstr "" #: ../../api/enums.rst:938 @@ -1478,7 +1478,7 @@ msgstr "" #: ../../api/enums.rst:955 #: 9462b1de374b4d8696d91df0e11eaf2e -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got kicked." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got kicked." msgstr "" #: ../../api/enums.rst:958 @@ -1499,7 +1499,7 @@ msgstr "" #: ../../api/enums.rst:964 #: 4c83a0acb3cc4f5d9f86ee20117108e6 -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is set to ``None``." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is set to ``None``." msgstr "" #: ../../api/enums.rst:967 @@ -1532,7 +1532,7 @@ msgstr "" #: ../../api/enums.rst:979 #: 770451079d8d4b5f8e33b6c52da5f3ff -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got banned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got banned." msgstr "" #: ../../api/enums.rst:986 @@ -1542,7 +1542,7 @@ msgstr "" #: ../../api/enums.rst:988 #: 456609aa1df0460dbb3dcd6b5414aca8 -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got unbanned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got unbanned." msgstr "" #: ../../api/enums.rst:995 @@ -1562,7 +1562,7 @@ msgstr "" #: ../../api/enums.rst:1000 #: 3685711e4704496c8312ef6113636f20 -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got updated." msgstr "" #: ../../api/enums.rst:1005 @@ -1587,7 +1587,7 @@ msgstr "" #: ../../api/enums.rst:1014 #: a57b479bb72143a6b0e1fa6cff760c1a -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got the role." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got the role." msgstr "" #: ../../api/enums.rst:1019 @@ -1634,7 +1634,7 @@ msgstr "" #: ../../api/enums.rst:1050 #: aad1bbec2f2a487784929c43e432558a -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` which was added to the guild." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` which was added to the guild." msgstr "" #: ../../api/enums.rst:1057 @@ -1648,7 +1648,7 @@ msgstr "" #: 5547887ba3e64a6cadc87783c1bcecf7 #: 91ed6f1edab04e8aad95cd8d9aa069f7 #: f5e5f97f23e7451c8914aad7c3391dd4 -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Role` or a :class:`Object` with the ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Role` or a :class:`Object` with the ID." msgstr "" #: ../../api/enums.rst:1064 @@ -1724,7 +1724,7 @@ msgstr "" #: ../../api/enums.rst:1109 #: ce279e2749bb47529031e1755e0740c2 -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was created." msgstr "" #: ../../api/enums.rst:1114 @@ -1795,7 +1795,7 @@ msgstr "" #: ../../api/enums.rst:1126 #: c0adb6372c474dd9a6fa1b79ababb781 -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was updated." msgstr "" #: ../../api/enums.rst:1131 @@ -1805,7 +1805,7 @@ msgstr "" #: ../../api/enums.rst:1133 #: 951939c17ece4b73a544877c61858520 -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was deleted." msgstr "" #: ../../api/enums.rst:1148 @@ -1819,7 +1819,7 @@ msgstr "" #: 2fe79b01b896449f8a2711781524a8df #: ef972dbe7ec941a5907d624c86a390d6 #: 59d99fea521c4d5f9ce1c97173c5a522 -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the webhook ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the webhook ID." msgstr "" #: ../../api/enums.rst:1157 @@ -1863,7 +1863,7 @@ msgstr "" #: ../../api/enums.rst:1203 #: 41aeb9dc3c5840aeb56f92ec751f6cd0 #: df5de1fd8daa4ce2a481835fc9ae71f4 -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." msgstr "" #: ../../api/enums.rst:1201 @@ -1878,7 +1878,7 @@ msgstr "" #: ../../api/enums.rst:1214 #: 6c4676bf1a414f30a39f7196f7d82d10 -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the emoji ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the emoji ID." msgstr "" #: ../../api/enums.rst:1223 @@ -1888,7 +1888,7 @@ msgstr "" #: ../../api/enums.rst:1226 #: 8982961c175341f9a00e1d4196d2528a -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message deleted." msgstr "" #: ../../api/enums.rst:1232 @@ -1910,7 +1910,7 @@ msgstr "" #: ../../api/enums.rst:1239 #: b496e7abbf6641c6aa0ecb2f408fa88d -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." msgstr "" #: ../../api/enums.rst:1251 @@ -1920,7 +1920,7 @@ msgstr "" #: ../../api/enums.rst:1253 #: d1e5158c3f894e9098ce7240dda29673 -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message pinned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message pinned." msgstr "" #: ../../api/enums.rst:1259 @@ -1940,7 +1940,7 @@ msgstr "" #: ../../api/enums.rst:1268 #: 9133756a00814e1591bec12ddd56edb6 -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message unpinned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message unpinned." msgstr "" #: ../../api/enums.rst:1274 @@ -1960,7 +1960,7 @@ msgstr "" #: ../../api/enums.rst:1283 #: 28a61562db5c42e58719d9abdd270252 -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was created." msgstr "" #: ../../api/enums.rst:1290 @@ -1970,7 +1970,7 @@ msgstr "" #: ../../api/enums.rst:1292 #: cc4ffb3112c04683842b7de2775fb45d -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was updated." msgstr "" #: ../../api/enums.rst:1299 @@ -1980,7 +1980,7 @@ msgstr "" #: ../../api/enums.rst:1301 #: f5bd9a45dda249209e96a6ee8751ca52 -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was deleted." msgstr "" #: ../../api/enums.rst:1308 @@ -1990,7 +1990,7 @@ msgstr "" #: ../../api/enums.rst:1310 #: c2e9a68539184e2fa02ef00208b3a2aa -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." msgstr "" #: ../../api/enums.rst:1317 @@ -2013,7 +2013,7 @@ msgstr "" #: ../../api/enums.rst:1325 #: 5f94e6a27480458483dd65b0a69b1037 -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." msgstr "" #: ../../api/enums.rst:1338 @@ -2032,7 +2032,7 @@ msgstr "" #: a544a30d24fe44ce9cbd11c4d6bf9f7c #: 83e568d602594a06a3755e2645cea0e5 #: 3d62e77b4351433b96277edb798f3ce3 -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." msgstr "" #: ../../api/enums.rst:1353 @@ -2098,7 +2098,7 @@ msgstr "" #: af920a7bbbc94e369a1d93f7a1cc290a #: 5a0b011e635a4d84895b73b59e7641c9 #: 3a98586e07cd4bd4b61d000b98c58dec -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." msgstr "" #: ../../api/enums.rst:1413 @@ -2154,7 +2154,7 @@ msgstr "" #: ../../api/enums.rst:1466 #: afb06852a1554bf69f47285f8ffc16d4 -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." msgstr "" #: ../../api/enums.rst:1473 @@ -2200,7 +2200,7 @@ msgstr "" #: ../../api/enums.rst:1484 #: 43b8091416ca4f4987c31bc8136e00f5 -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." msgstr "" #: ../../api/enums.rst:1500 @@ -2210,7 +2210,7 @@ msgstr "" #: ../../api/enums.rst:1502 #: 438ec881b324479aad7b59bb720a7b9c -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." msgstr "" #: ../../api/enums.rst:1518 @@ -2220,7 +2220,7 @@ msgstr "" #: ../../api/enums.rst:1520 #: e7552f8804b04c728f78efa08726afe8 -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with the ID of the command that had it's permissions edited." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with the ID of the command that had it's permissions edited." msgstr "" #: ../../api/enums.rst:1526 @@ -2338,7 +2338,7 @@ msgstr "" #: ../../api/enums.rst:1628 #: d09aa244691540dbaeff35ae7f802cd6 #: 21d7aa25fa2449bdbc086189b5743a39 -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." msgstr "" #: ../../api/enums.rst:1620 diff --git a/docs/faq.rst b/docs/faq.rst index c1ba99f9ce..3f4e27aa23 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -201,7 +201,7 @@ to do anything special. You **cannot** send ``':thumbsup:'`` style shorthands. For custom emoji, you should pass an instance of :class:`GuildEmoji` or :class:`AppEmoji`. You can also pass a ``'<:name:id>'`` string, but if you can use said emoji, you should be able to use :meth:`Client.get_emoji` to get an emoji via ID or use :func:`utils.find`/ -:func:`utils.get` on :attr:`Client.emojis` or :attr:`Guild.emojis` collections. +:func:`utils.get` on :meth:`Client.get_emojis` or :attr:`Guild.emojis` collections. The name and ID of a custom emoji can be found with the client by prefixing ``:custom_emoji:`` with a backslash. For example, sending the message ``\:python3:`` with the client will result in ``<:python3:232720527448342530>``. @@ -285,7 +285,7 @@ specific models. Quick example: :: # find a guild by name - guild = discord.utils.find(lambda g: g.name == "My Server", client.guilds) + guild = discord.utils.find(lambda g: g.name == "My Server", await client.get_guilds()) # make sure to check if it's found if guild is not None: diff --git a/docs/locales/de/LC_MESSAGES/api/enums.po b/docs/locales/de/LC_MESSAGES/api/enums.po index bc214e5db0..cb033dc5c4 100644 --- a/docs/locales/de/LC_MESSAGES/api/enums.po +++ b/docs/locales/de/LC_MESSAGES/api/enums.po @@ -656,8 +656,8 @@ msgstr "Changing the guild moderation settings" msgid "Changing things related to the guild widget" msgstr "Changing things related to the guild widget" -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Guild`." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Guild`." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Guild`." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Guild`." msgid "Possible attributes for :class:`AuditLogDiff`:" msgstr "Possible attributes for :class:`AuditLogDiff`:" @@ -704,8 +704,8 @@ msgstr ":attr:`~AuditLogDiff.vanity_url_code`" msgid "A new channel was created." msgstr "A new channel was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." msgid "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after`." msgstr "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after`." @@ -725,8 +725,8 @@ msgstr "The channel name or topic was changed" msgid "The channel bitrate was changed" msgstr "The channel bitrate was changed" -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." msgid "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after` or :attr:`~AuditLogEntry.before`." msgstr "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after` or :attr:`~AuditLogEntry.before`." @@ -752,8 +752,8 @@ msgstr ":attr:`~AuditLogDiff.default_auto_archive_duration`" msgid "A channel was deleted." msgstr "A channel was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with an ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with an ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with an ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with an ID." msgid "A more filled out object can be found by using the :attr:`~AuditLogEntry.before` object." msgstr "A more filled out object can be found by using the :attr:`~AuditLogEntry.before` object." @@ -776,8 +776,8 @@ msgstr ":attr:`~AuditLogDiff.id`" msgid "A channel permission overwrite was changed, this is typically when the permission values change." msgstr "A channel permission overwrite was changed, this is typically when the permission values change." -msgid "See :attr:`overwrite_create` for more information on how the :attr:`~AuditLogEntry.target` and :attr:`~AuditLogEntry.extra` fields are set." -msgstr "See :attr:`overwrite_create` for more information on how the :attr:`~AuditLogEntry.target` and :attr:`~AuditLogEntry.extra` fields are set." +msgid "See :attr:`overwrite_create` for more information on how the :func:`~AuditLogEntry.get_target` and :attr:`~AuditLogEntry.extra` fields are set." +msgstr "See :attr:`overwrite_create` for more information on how the :func:`~AuditLogEntry.get_target` and :attr:`~AuditLogEntry.extra` fields are set." msgid "A channel permission overwrite was deleted." msgstr "A channel permission overwrite was deleted." @@ -785,8 +785,8 @@ msgstr "A channel permission overwrite was deleted." msgid "A member was kicked." msgstr "A member was kicked." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got kicked." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got kicked." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got kicked." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got kicked." msgid "When this is the action, :attr:`~AuditLogEntry.changes` is empty." msgstr "When this is the action, :attr:`~AuditLogEntry.changes` is empty." @@ -794,8 +794,8 @@ msgstr "When this is the action, :attr:`~AuditLogEntry.changes` is empty." msgid "A member prune was triggered." msgstr "A member prune was triggered." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is set to ``None``." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is set to ``None``." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is set to ``None``." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is set to ``None``." msgid "When this is the action, the type of :attr:`~AuditLogEntry.extra` is set to an unspecified proxy object with two attributes:" msgstr "When this is the action, the type of :attr:`~AuditLogEntry.extra` is set to an unspecified proxy object with two attributes:" @@ -809,14 +809,14 @@ msgstr "``members_removed``: An integer specifying how many members were removed msgid "A member was banned." msgstr "A member was banned." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got banned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got banned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got banned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got banned." msgid "A member was unbanned." msgstr "A member was unbanned." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got unbanned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got unbanned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got unbanned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got unbanned." msgid "A member has updated. This triggers in the following situations:" msgstr "A member has updated. This triggers in the following situations:" @@ -827,8 +827,8 @@ msgstr "A nickname was changed" msgid "They were server muted or deafened (or it was undone)" msgstr "They were server muted or deafened (or it was undone)" -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got updated." msgid ":attr:`~AuditLogDiff.nick`" msgstr ":attr:`~AuditLogDiff.nick`" @@ -842,8 +842,8 @@ msgstr ":attr:`~AuditLogDiff.deaf`" msgid "A member's role has been updated. This triggers when a member either gains a role or loses a role." msgstr "A member's role has been updated. This triggers when a member either gains a role or loses a role." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got the role." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got the role." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got the role." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got the role." msgid ":attr:`~AuditLogDiff.roles`" msgstr ":attr:`~AuditLogDiff.roles`" @@ -869,14 +869,14 @@ msgstr "``count``: An integer specifying how many members were disconnected." msgid "A bot was added to the guild." msgstr "A bot was added to the guild." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` which was added to the guild." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` which was added to the guild." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` which was added to the guild." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` which was added to the guild." msgid "A new role was created." msgstr "A new role was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Role` or a :class:`Object` with the ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Role` or a :class:`Object` with the ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Role` or a :class:`Object` with the ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Role` or a :class:`Object` with the ID." msgid ":attr:`~AuditLogDiff.colour`" msgstr ":attr:`~AuditLogDiff.colour`" @@ -911,8 +911,8 @@ msgstr "A role was deleted." msgid "An invite was created." msgstr "An invite was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was created." msgid ":attr:`~AuditLogDiff.max_age`" msgstr ":attr:`~AuditLogDiff.max_age`" @@ -938,20 +938,20 @@ msgstr ":attr:`~AuditLogDiff.max_uses`" msgid "An invite was updated." msgstr "An invite was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was updated." msgid "An invite was deleted." msgstr "An invite was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was deleted." msgid "A webhook was created." msgstr "A webhook was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the webhook ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the webhook ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the webhook ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the webhook ID." msgid ":attr:`~AuditLogDiff.type` (always set to ``1`` if so)" msgstr ":attr:`~AuditLogDiff.type` (always set to ``1`` if so)" @@ -974,8 +974,8 @@ msgstr "A webhook was deleted." msgid "An emoji was created." msgstr "An emoji was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." msgid "An emoji was updated. This triggers when the name has changed." msgstr "An emoji was updated. This triggers when the name has changed." @@ -983,14 +983,14 @@ msgstr "An emoji was updated. This triggers when the name has changed." msgid "An emoji was deleted." msgstr "An emoji was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the emoji ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the emoji ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the emoji ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the emoji ID." msgid "A message was deleted by a moderator. Note that this only triggers if the message was deleted by someone other than the author." msgstr "A message was deleted by a moderator. Note that this only triggers if the message was deleted by someone other than the author." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message deleted." msgid "``count``: An integer specifying how many messages were deleted." msgstr "``count``: An integer specifying how many messages were deleted." @@ -1001,14 +1001,14 @@ msgstr "``channel``: A :class:`TextChannel` or :class:`Object` with the channel msgid "Messages were bulk deleted by a moderator." msgstr "Messages were bulk deleted by a moderator." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." msgid "A message was pinned in a channel." msgstr "A message was pinned in a channel." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message pinned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message pinned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message pinned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message pinned." msgid "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was pinned." msgstr "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was pinned." @@ -1019,8 +1019,8 @@ msgstr "``message_id``: the ID of the message which was pinned." msgid "A message was unpinned in a channel." msgstr "A message was unpinned in a channel." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message unpinned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message unpinned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message unpinned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message unpinned." msgid "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was unpinned." msgstr "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was unpinned." @@ -1031,26 +1031,26 @@ msgstr "``message_id``: the ID of the message which was unpinned." msgid "A guild integration was created." msgstr "A guild integration was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was created." msgid "A guild integration was updated." msgstr "A guild integration was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was updated." msgid "A guild integration was deleted." msgstr "A guild integration was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was deleted." msgid "A stage instance was started." msgstr "A stage instance was started." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." msgid ":attr:`~AuditLogDiff.privacy_level`" msgstr ":attr:`~AuditLogDiff.privacy_level`" @@ -1058,8 +1058,8 @@ msgstr ":attr:`~AuditLogDiff.privacy_level`" msgid "A stage instance was updated." msgstr "A stage instance was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." msgid "A stage instance was ended." msgstr "A stage instance was ended." @@ -1067,8 +1067,8 @@ msgstr "A stage instance was ended." msgid "A sticker was created." msgstr "A sticker was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." msgid ":attr:`~AuditLogDiff.emoji`" msgstr ":attr:`~AuditLogDiff.emoji`" @@ -1091,8 +1091,8 @@ msgstr "A sticker was deleted." msgid "A scheduled event was created." msgstr "A scheduled event was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." msgid ":attr:`~discord.ScheduledEvent.location`" msgstr ":attr:`~discord.ScheduledEvent.location`" @@ -1115,8 +1115,8 @@ msgstr "A scheduled event was deleted." msgid "A thread was created." msgstr "A thread was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." msgid ":attr:`~AuditLogDiff.archived`" msgstr ":attr:`~AuditLogDiff.archived`" @@ -1133,20 +1133,20 @@ msgstr ":attr:`~AuditLogDiff.invitable`" msgid "A thread was updated." msgstr "A thread was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." msgid "A thread was deleted." msgstr "A thread was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." msgid "An application command's permissions were updated." msgstr "An application command's permissions were updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with the ID of the command that had it's permissions edited." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with the ID of the command that had it's permissions edited." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with the ID of the command that had it's permissions edited." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with the ID of the command that had it's permissions edited." msgid ":attr:`~AuditLogDiff.command_id`" msgstr ":attr:`~AuditLogDiff.command_id`" @@ -1199,8 +1199,8 @@ msgstr "The creator monetization terms were accepted." msgid "A voice channel status was updated." msgstr "A voice channel status was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." msgid ":attr:`~AuditLogDiff.status`" msgstr ":attr:`~AuditLogDiff.status`" diff --git a/docs/locales/en/LC_MESSAGES/api/enums.po b/docs/locales/en/LC_MESSAGES/api/enums.po index de7337e361..4660eda49f 100644 --- a/docs/locales/en/LC_MESSAGES/api/enums.po +++ b/docs/locales/en/LC_MESSAGES/api/enums.po @@ -960,7 +960,7 @@ msgstr "" #: ../../api/enums.rst:824 c890e719787243a5af28be7c6f82f77b msgid "" -"When this is the action, the type of :attr:`~AuditLogEntry.target` is the" +"When this is the action, the type of :func:`~AuditLogEntry.get_target` is the" " :class:`Guild`." msgstr "" @@ -1076,7 +1076,7 @@ msgstr "" #: ../../api/enums.rst:847 e00bbae1ecc54cd4aa7b2f97761a2857 msgid "" -"When this is the action, the type of :attr:`~AuditLogEntry.target` is " +"When this is the action, the type of :func:`~AuditLogEntry.get_target` is " "either a :class:`abc.GuildChannel` or :class:`Object` with an ID." msgstr "" @@ -1118,7 +1118,7 @@ msgstr "" #: ../../api/enums.rst:866 ../../api/enums.rst:904 #: 5257b72e408a46d4a7b06498d32f7209 8f81efbdafac4745899e4ad861717ecd msgid "" -"When this is the action, the type of :attr:`~AuditLogEntry.target` is the" +"When this is the action, the type of :func:`~AuditLogEntry.get_target` is the" " :class:`abc.GuildChannel` or :class:`Object` with an ID." msgstr "" @@ -1160,7 +1160,7 @@ msgstr "" #: ../../api/enums.rst:888 5af5984da736481eae7b9ec37355167b msgid "" -"When this is the action, the type of :attr:`~AuditLogEntry.target` is an " +"When this is the action, the type of :func:`~AuditLogEntry.get_target` is an " ":class:`Object` with an ID." msgstr "" @@ -1211,7 +1211,7 @@ msgstr "" #: 548a7a8ca0314acf9735eac331d866e9 b74dea0f59eb486f98c229b259e001f9 msgid "" "See :attr:`overwrite_create` for more information on how the " -":attr:`~AuditLogEntry.target` and :attr:`~AuditLogEntry.extra` fields are" +":func:`~AuditLogEntry.get_target` and :attr:`~AuditLogEntry.extra` fields are" " set." msgstr "" @@ -1225,7 +1225,7 @@ msgstr "" #: ../../api/enums.rst:955 9462b1de374b4d8696d91df0e11eaf2e msgid "" -"When this is the action, the type of :attr:`~AuditLogEntry.target` is the" +"When this is the action, the type of :func:`~AuditLogEntry.get_target` is the" " :class:`User` who got kicked." msgstr "" @@ -1242,7 +1242,7 @@ msgstr "" #: ../../api/enums.rst:964 4c83a0acb3cc4f5d9f86ee20117108e6 msgid "" -"When this is the action, the type of :attr:`~AuditLogEntry.target` is set" +"When this is the action, the type of :func:`~AuditLogEntry.get_target` is set" " to ``None``." msgstr "" @@ -1270,7 +1270,7 @@ msgstr "" #: ../../api/enums.rst:979 770451079d8d4b5f8e33b6c52da5f3ff msgid "" -"When this is the action, the type of :attr:`~AuditLogEntry.target` is the" +"When this is the action, the type of :func:`~AuditLogEntry.get_target` is the" " :class:`User` who got banned." msgstr "" @@ -1280,7 +1280,7 @@ msgstr "" #: ../../api/enums.rst:988 456609aa1df0460dbb3dcd6b5414aca8 msgid "" -"When this is the action, the type of :attr:`~AuditLogEntry.target` is the" +"When this is the action, the type of :func:`~AuditLogEntry.get_target` is the" " :class:`User` who got unbanned." msgstr "" @@ -1298,7 +1298,7 @@ msgstr "" #: ../../api/enums.rst:1000 3685711e4704496c8312ef6113636f20 msgid "" -"When this is the action, the type of :attr:`~AuditLogEntry.target` is the" +"When this is the action, the type of :func:`~AuditLogEntry.get_target` is the" " :class:`Member` or :class:`User` who got updated." msgstr "" @@ -1322,7 +1322,7 @@ msgstr "" #: ../../api/enums.rst:1014 a57b479bb72143a6b0e1fa6cff760c1a msgid "" -"When this is the action, the type of :attr:`~AuditLogEntry.target` is the" +"When this is the action, the type of :func:`~AuditLogEntry.get_target` is the" " :class:`Member` or :class:`User` who got the role." msgstr "" @@ -1369,7 +1369,7 @@ msgstr "" #: ../../api/enums.rst:1050 aad1bbec2f2a487784929c43e432558a msgid "" -"When this is the action, the type of :attr:`~AuditLogEntry.target` is the" +"When this is the action, the type of :func:`~AuditLogEntry.get_target` is the" " :class:`Member` or :class:`User` which was added to the guild." msgstr "" @@ -1381,7 +1381,7 @@ msgstr "" #: 5547887ba3e64a6cadc87783c1bcecf7 91ed6f1edab04e8aad95cd8d9aa069f7 #: f5e5f97f23e7451c8914aad7c3391dd4 msgid "" -"When this is the action, the type of :attr:`~AuditLogEntry.target` is the" +"When this is the action, the type of :func:`~AuditLogEntry.get_target` is the" " :class:`Role` or a :class:`Object` with the ID." msgstr "" @@ -1439,7 +1439,7 @@ msgstr "" #: ../../api/enums.rst:1109 ce279e2749bb47529031e1755e0740c2 msgid "" -"When this is the action, the type of :attr:`~AuditLogEntry.target` is the" +"When this is the action, the type of :func:`~AuditLogEntry.get_target` is the" " :class:`Invite` that was created." msgstr "" @@ -1489,7 +1489,7 @@ msgstr "" #: ../../api/enums.rst:1126 c0adb6372c474dd9a6fa1b79ababb781 msgid "" -"When this is the action, the type of :attr:`~AuditLogEntry.target` is the" +"When this is the action, the type of :func:`~AuditLogEntry.get_target` is the" " :class:`Invite` that was updated." msgstr "" @@ -1499,7 +1499,7 @@ msgstr "" #: ../../api/enums.rst:1133 951939c17ece4b73a544877c61858520 msgid "" -"When this is the action, the type of :attr:`~AuditLogEntry.target` is the" +"When this is the action, the type of :func:`~AuditLogEntry.get_target` is the" " :class:`Invite` that was deleted." msgstr "" @@ -1511,7 +1511,7 @@ msgstr "" #: 2fe79b01b896449f8a2711781524a8df 59d99fea521c4d5f9ce1c97173c5a522 #: ef972dbe7ec941a5907d624c86a390d6 msgid "" -"When this is the action, the type of :attr:`~AuditLogEntry.target` is the" +"When this is the action, the type of :func:`~AuditLogEntry.get_target` is the" " :class:`Object` with the webhook ID." msgstr "" @@ -1547,7 +1547,7 @@ msgstr "" #: ../../api/enums.rst:1192 ../../api/enums.rst:1203 #: 41aeb9dc3c5840aeb56f92ec751f6cd0 df5de1fd8daa4ce2a481835fc9ae71f4 msgid "" -"When this is the action, the type of :attr:`~AuditLogEntry.target` is the" +"When this is the action, the type of :func:`~AuditLogEntry.get_target` is the" " :class:`GuildEmoji` or :class:`Object` with the emoji ID." msgstr "" @@ -1561,7 +1561,7 @@ msgstr "" #: ../../api/enums.rst:1214 6c4676bf1a414f30a39f7196f7d82d10 msgid "" -"When this is the action, the type of :attr:`~AuditLogEntry.target` is the" +"When this is the action, the type of :func:`~AuditLogEntry.get_target` is the" " :class:`Object` with the emoji ID." msgstr "" @@ -1573,7 +1573,7 @@ msgstr "" #: ../../api/enums.rst:1226 8982961c175341f9a00e1d4196d2528a msgid "" -"When this is the action, the type of :attr:`~AuditLogEntry.target` is the" +"When this is the action, the type of :func:`~AuditLogEntry.get_target` is the" " :class:`Member` or :class:`User` who had their message deleted." msgstr "" @@ -1594,7 +1594,7 @@ msgstr "" #: ../../api/enums.rst:1239 b496e7abbf6641c6aa0ecb2f408fa88d msgid "" -"When this is the action, the type of :attr:`~AuditLogEntry.target` is the" +"When this is the action, the type of :func:`~AuditLogEntry.get_target` is the" " :class:`TextChannel` or :class:`Object` with the ID of the channel that " "was purged." msgstr "" @@ -1605,7 +1605,7 @@ msgstr "" #: ../../api/enums.rst:1253 d1e5158c3f894e9098ce7240dda29673 msgid "" -"When this is the action, the type of :attr:`~AuditLogEntry.target` is the" +"When this is the action, the type of :func:`~AuditLogEntry.get_target` is the" " :class:`Member` or :class:`User` who had their message pinned." msgstr "" @@ -1625,7 +1625,7 @@ msgstr "" #: ../../api/enums.rst:1268 9133756a00814e1591bec12ddd56edb6 msgid "" -"When this is the action, the type of :attr:`~AuditLogEntry.target` is the" +"When this is the action, the type of :func:`~AuditLogEntry.get_target` is the" " :class:`Member` or :class:`User` who had their message unpinned." msgstr "" @@ -1645,7 +1645,7 @@ msgstr "" #: ../../api/enums.rst:1283 28a61562db5c42e58719d9abdd270252 msgid "" -"When this is the action, the type of :attr:`~AuditLogEntry.target` is the" +"When this is the action, the type of :func:`~AuditLogEntry.get_target` is the" " :class:`Object` with the integration ID of the integration which was " "created." msgstr "" @@ -1656,7 +1656,7 @@ msgstr "" #: ../../api/enums.rst:1292 cc4ffb3112c04683842b7de2775fb45d msgid "" -"When this is the action, the type of :attr:`~AuditLogEntry.target` is the" +"When this is the action, the type of :func:`~AuditLogEntry.get_target` is the" " :class:`Object` with the integration ID of the integration which was " "updated." msgstr "" @@ -1667,7 +1667,7 @@ msgstr "" #: ../../api/enums.rst:1301 f5bd9a45dda249209e96a6ee8751ca52 msgid "" -"When this is the action, the type of :attr:`~AuditLogEntry.target` is the" +"When this is the action, the type of :func:`~AuditLogEntry.get_target` is the" " :class:`Object` with the integration ID of the integration which was " "deleted." msgstr "" @@ -1678,7 +1678,7 @@ msgstr "" #: ../../api/enums.rst:1310 c2e9a68539184e2fa02ef00208b3a2aa msgid "" -"When this is the action, the type of :attr:`~AuditLogEntry.target` is the" +"When this is the action, the type of :func:`~AuditLogEntry.get_target` is the" " :class:`StageInstance` or :class:`Object` with the ID of the stage " "instance which was created." msgstr "" @@ -1697,7 +1697,7 @@ msgstr "" #: ../../api/enums.rst:1325 5f94e6a27480458483dd65b0a69b1037 msgid "" -"When this is the action, the type of :attr:`~AuditLogEntry.target` is the" +"When this is the action, the type of :func:`~AuditLogEntry.get_target` is the" " :class:`StageInstance` or :class:`Object` with the ID of the stage " "instance which was updated." msgstr "" @@ -1714,7 +1714,7 @@ msgstr "" #: 3d62e77b4351433b96277edb798f3ce3 83e568d602594a06a3755e2645cea0e5 #: a544a30d24fe44ce9cbd11c4d6bf9f7c msgid "" -"When this is the action, the type of :attr:`~AuditLogEntry.target` is the" +"When this is the action, the type of :func:`~AuditLogEntry.get_target` is the" " :class:`GuildSticker` or :class:`Object` with the ID of the sticker " "which was updated." msgstr "" @@ -1761,7 +1761,7 @@ msgstr "" #: 3a98586e07cd4bd4b61d000b98c58dec 5a0b011e635a4d84895b73b59e7641c9 #: af920a7bbbc94e369a1d93f7a1cc290a msgid "" -"When this is the action, the type of :attr:`~AuditLogEntry.target` is the" +"When this is the action, the type of :func:`~AuditLogEntry.get_target` is the" " :class:`ScheduledEvent` or :class:`Object` with the ID of the thread " "which was deleted." msgstr "" @@ -1804,7 +1804,7 @@ msgstr "" #: ../../api/enums.rst:1466 afb06852a1554bf69f47285f8ffc16d4 msgid "" -"When this is the action, the type of :attr:`~AuditLogEntry.target` is the" +"When this is the action, the type of :func:`~AuditLogEntry.get_target` is the" " :class:`Thread` or :class:`Object` with the ID of the thread which was " "created." msgstr "" @@ -1839,7 +1839,7 @@ msgstr "" #: ../../api/enums.rst:1484 43b8091416ca4f4987c31bc8136e00f5 msgid "" -"When this is the action, the type of :attr:`~AuditLogEntry.target` is the" +"When this is the action, the type of :func:`~AuditLogEntry.get_target` is the" " :class:`Thread` or :class:`Object` with the ID of the thread which was " "updated." msgstr "" @@ -1850,7 +1850,7 @@ msgstr "" #: ../../api/enums.rst:1502 438ec881b324479aad7b59bb720a7b9c msgid "" -"When this is the action, the type of :attr:`~AuditLogEntry.target` is the" +"When this is the action, the type of :func:`~AuditLogEntry.get_target` is the" " :class:`Thread` or :class:`Object` with the ID of the thread which was " "deleted." msgstr "" @@ -1861,7 +1861,7 @@ msgstr "" #: ../../api/enums.rst:1520 e7552f8804b04c728f78efa08726afe8 msgid "" -"When this is the action, the type of :attr:`~AuditLogEntry.target` is an " +"When this is the action, the type of :func:`~AuditLogEntry.get_target` is an " ":class:`Object` with the ID of the command that had it's permissions " "edited." msgstr "" @@ -1950,7 +1950,7 @@ msgstr "" #: ../../api/enums.rst:1614 ../../api/enums.rst:1628 #: 21d7aa25fa2449bdbc086189b5743a39 d09aa244691540dbaeff35ae7f802cd6 msgid "" -"When this is the action, the type of :attr:`~AuditLogEntry.target` is the" +"When this is the action, the type of :func:`~AuditLogEntry.get_target` is the" " :class:`VoiceChannel` or :class:`Object` with the ID of the voice " "channel which was updated." msgstr "" @@ -2829,7 +2829,7 @@ msgstr "" #~ msgid "" #~ "When this is the action, the type" -#~ " of :attr:`~AuditLogEntry.target` is the " +#~ " of :func:`~AuditLogEntry.get_target` is the " #~ ":class:`Emoji` or :class:`Object` with the " #~ "emoji ID." #~ msgstr "" diff --git a/docs/locales/es/LC_MESSAGES/api/enums.po b/docs/locales/es/LC_MESSAGES/api/enums.po index bc214e5db0..cb033dc5c4 100644 --- a/docs/locales/es/LC_MESSAGES/api/enums.po +++ b/docs/locales/es/LC_MESSAGES/api/enums.po @@ -656,8 +656,8 @@ msgstr "Changing the guild moderation settings" msgid "Changing things related to the guild widget" msgstr "Changing things related to the guild widget" -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Guild`." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Guild`." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Guild`." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Guild`." msgid "Possible attributes for :class:`AuditLogDiff`:" msgstr "Possible attributes for :class:`AuditLogDiff`:" @@ -704,8 +704,8 @@ msgstr ":attr:`~AuditLogDiff.vanity_url_code`" msgid "A new channel was created." msgstr "A new channel was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." msgid "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after`." msgstr "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after`." @@ -725,8 +725,8 @@ msgstr "The channel name or topic was changed" msgid "The channel bitrate was changed" msgstr "The channel bitrate was changed" -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." msgid "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after` or :attr:`~AuditLogEntry.before`." msgstr "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after` or :attr:`~AuditLogEntry.before`." @@ -752,8 +752,8 @@ msgstr ":attr:`~AuditLogDiff.default_auto_archive_duration`" msgid "A channel was deleted." msgstr "A channel was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with an ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with an ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with an ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with an ID." msgid "A more filled out object can be found by using the :attr:`~AuditLogEntry.before` object." msgstr "A more filled out object can be found by using the :attr:`~AuditLogEntry.before` object." @@ -776,8 +776,8 @@ msgstr ":attr:`~AuditLogDiff.id`" msgid "A channel permission overwrite was changed, this is typically when the permission values change." msgstr "A channel permission overwrite was changed, this is typically when the permission values change." -msgid "See :attr:`overwrite_create` for more information on how the :attr:`~AuditLogEntry.target` and :attr:`~AuditLogEntry.extra` fields are set." -msgstr "See :attr:`overwrite_create` for more information on how the :attr:`~AuditLogEntry.target` and :attr:`~AuditLogEntry.extra` fields are set." +msgid "See :attr:`overwrite_create` for more information on how the :func:`~AuditLogEntry.get_target` and :attr:`~AuditLogEntry.extra` fields are set." +msgstr "See :attr:`overwrite_create` for more information on how the :func:`~AuditLogEntry.get_target` and :attr:`~AuditLogEntry.extra` fields are set." msgid "A channel permission overwrite was deleted." msgstr "A channel permission overwrite was deleted." @@ -785,8 +785,8 @@ msgstr "A channel permission overwrite was deleted." msgid "A member was kicked." msgstr "A member was kicked." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got kicked." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got kicked." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got kicked." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got kicked." msgid "When this is the action, :attr:`~AuditLogEntry.changes` is empty." msgstr "When this is the action, :attr:`~AuditLogEntry.changes` is empty." @@ -794,8 +794,8 @@ msgstr "When this is the action, :attr:`~AuditLogEntry.changes` is empty." msgid "A member prune was triggered." msgstr "A member prune was triggered." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is set to ``None``." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is set to ``None``." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is set to ``None``." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is set to ``None``." msgid "When this is the action, the type of :attr:`~AuditLogEntry.extra` is set to an unspecified proxy object with two attributes:" msgstr "When this is the action, the type of :attr:`~AuditLogEntry.extra` is set to an unspecified proxy object with two attributes:" @@ -809,14 +809,14 @@ msgstr "``members_removed``: An integer specifying how many members were removed msgid "A member was banned." msgstr "A member was banned." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got banned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got banned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got banned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got banned." msgid "A member was unbanned." msgstr "A member was unbanned." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got unbanned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got unbanned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got unbanned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got unbanned." msgid "A member has updated. This triggers in the following situations:" msgstr "A member has updated. This triggers in the following situations:" @@ -827,8 +827,8 @@ msgstr "A nickname was changed" msgid "They were server muted or deafened (or it was undone)" msgstr "They were server muted or deafened (or it was undone)" -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got updated." msgid ":attr:`~AuditLogDiff.nick`" msgstr ":attr:`~AuditLogDiff.nick`" @@ -842,8 +842,8 @@ msgstr ":attr:`~AuditLogDiff.deaf`" msgid "A member's role has been updated. This triggers when a member either gains a role or loses a role." msgstr "A member's role has been updated. This triggers when a member either gains a role or loses a role." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got the role." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got the role." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got the role." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got the role." msgid ":attr:`~AuditLogDiff.roles`" msgstr ":attr:`~AuditLogDiff.roles`" @@ -869,14 +869,14 @@ msgstr "``count``: An integer specifying how many members were disconnected." msgid "A bot was added to the guild." msgstr "A bot was added to the guild." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` which was added to the guild." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` which was added to the guild." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` which was added to the guild." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` which was added to the guild." msgid "A new role was created." msgstr "A new role was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Role` or a :class:`Object` with the ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Role` or a :class:`Object` with the ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Role` or a :class:`Object` with the ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Role` or a :class:`Object` with the ID." msgid ":attr:`~AuditLogDiff.colour`" msgstr ":attr:`~AuditLogDiff.colour`" @@ -911,8 +911,8 @@ msgstr "A role was deleted." msgid "An invite was created." msgstr "An invite was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was created." msgid ":attr:`~AuditLogDiff.max_age`" msgstr ":attr:`~AuditLogDiff.max_age`" @@ -938,20 +938,20 @@ msgstr ":attr:`~AuditLogDiff.max_uses`" msgid "An invite was updated." msgstr "An invite was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was updated." msgid "An invite was deleted." msgstr "An invite was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was deleted." msgid "A webhook was created." msgstr "A webhook was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the webhook ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the webhook ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the webhook ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the webhook ID." msgid ":attr:`~AuditLogDiff.type` (always set to ``1`` if so)" msgstr ":attr:`~AuditLogDiff.type` (always set to ``1`` if so)" @@ -974,8 +974,8 @@ msgstr "A webhook was deleted." msgid "An emoji was created." msgstr "An emoji was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." msgid "An emoji was updated. This triggers when the name has changed." msgstr "An emoji was updated. This triggers when the name has changed." @@ -983,14 +983,14 @@ msgstr "An emoji was updated. This triggers when the name has changed." msgid "An emoji was deleted." msgstr "An emoji was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the emoji ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the emoji ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the emoji ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the emoji ID." msgid "A message was deleted by a moderator. Note that this only triggers if the message was deleted by someone other than the author." msgstr "A message was deleted by a moderator. Note that this only triggers if the message was deleted by someone other than the author." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message deleted." msgid "``count``: An integer specifying how many messages were deleted." msgstr "``count``: An integer specifying how many messages were deleted." @@ -1001,14 +1001,14 @@ msgstr "``channel``: A :class:`TextChannel` or :class:`Object` with the channel msgid "Messages were bulk deleted by a moderator." msgstr "Messages were bulk deleted by a moderator." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." msgid "A message was pinned in a channel." msgstr "A message was pinned in a channel." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message pinned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message pinned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message pinned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message pinned." msgid "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was pinned." msgstr "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was pinned." @@ -1019,8 +1019,8 @@ msgstr "``message_id``: the ID of the message which was pinned." msgid "A message was unpinned in a channel." msgstr "A message was unpinned in a channel." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message unpinned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message unpinned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message unpinned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message unpinned." msgid "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was unpinned." msgstr "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was unpinned." @@ -1031,26 +1031,26 @@ msgstr "``message_id``: the ID of the message which was unpinned." msgid "A guild integration was created." msgstr "A guild integration was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was created." msgid "A guild integration was updated." msgstr "A guild integration was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was updated." msgid "A guild integration was deleted." msgstr "A guild integration was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was deleted." msgid "A stage instance was started." msgstr "A stage instance was started." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." msgid ":attr:`~AuditLogDiff.privacy_level`" msgstr ":attr:`~AuditLogDiff.privacy_level`" @@ -1058,8 +1058,8 @@ msgstr ":attr:`~AuditLogDiff.privacy_level`" msgid "A stage instance was updated." msgstr "A stage instance was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." msgid "A stage instance was ended." msgstr "A stage instance was ended." @@ -1067,8 +1067,8 @@ msgstr "A stage instance was ended." msgid "A sticker was created." msgstr "A sticker was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." msgid ":attr:`~AuditLogDiff.emoji`" msgstr ":attr:`~AuditLogDiff.emoji`" @@ -1091,8 +1091,8 @@ msgstr "A sticker was deleted." msgid "A scheduled event was created." msgstr "A scheduled event was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." msgid ":attr:`~discord.ScheduledEvent.location`" msgstr ":attr:`~discord.ScheduledEvent.location`" @@ -1115,8 +1115,8 @@ msgstr "A scheduled event was deleted." msgid "A thread was created." msgstr "A thread was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." msgid ":attr:`~AuditLogDiff.archived`" msgstr ":attr:`~AuditLogDiff.archived`" @@ -1133,20 +1133,20 @@ msgstr ":attr:`~AuditLogDiff.invitable`" msgid "A thread was updated." msgstr "A thread was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." msgid "A thread was deleted." msgstr "A thread was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." msgid "An application command's permissions were updated." msgstr "An application command's permissions were updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with the ID of the command that had it's permissions edited." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with the ID of the command that had it's permissions edited." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with the ID of the command that had it's permissions edited." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with the ID of the command that had it's permissions edited." msgid ":attr:`~AuditLogDiff.command_id`" msgstr ":attr:`~AuditLogDiff.command_id`" @@ -1199,8 +1199,8 @@ msgstr "The creator monetization terms were accepted." msgid "A voice channel status was updated." msgstr "A voice channel status was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." msgid ":attr:`~AuditLogDiff.status`" msgstr ":attr:`~AuditLogDiff.status`" diff --git a/docs/locales/fr/LC_MESSAGES/api/enums.po b/docs/locales/fr/LC_MESSAGES/api/enums.po index b1c7ba835e..651c5d9304 100644 --- a/docs/locales/fr/LC_MESSAGES/api/enums.po +++ b/docs/locales/fr/LC_MESSAGES/api/enums.po @@ -656,8 +656,8 @@ msgstr "Changing the guild moderation settings" msgid "Changing things related to the guild widget" msgstr "Changing things related to the guild widget" -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Guild`." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Guild`." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Guild`." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Guild`." msgid "Possible attributes for :class:`AuditLogDiff`:" msgstr "Possible attributes for :class:`AuditLogDiff`:" @@ -704,8 +704,8 @@ msgstr ":attr:`~AuditLogDiff.vanity_url_code`" msgid "A new channel was created." msgstr "A new channel was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." msgid "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after`." msgstr "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after`." @@ -725,8 +725,8 @@ msgstr "The channel name or topic was changed" msgid "The channel bitrate was changed" msgstr "The channel bitrate was changed" -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." msgid "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after` or :attr:`~AuditLogEntry.before`." msgstr "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after` or :attr:`~AuditLogEntry.before`." @@ -752,8 +752,8 @@ msgstr ":attr:`~AuditLogDiff.default_auto_archive_duration`" msgid "A channel was deleted." msgstr "A channel was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with an ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with an ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with an ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with an ID." msgid "A more filled out object can be found by using the :attr:`~AuditLogEntry.before` object." msgstr "A more filled out object can be found by using the :attr:`~AuditLogEntry.before` object." @@ -776,8 +776,8 @@ msgstr ":attr:`~AuditLogDiff.id`" msgid "A channel permission overwrite was changed, this is typically when the permission values change." msgstr "A channel permission overwrite was changed, this is typically when the permission values change." -msgid "See :attr:`overwrite_create` for more information on how the :attr:`~AuditLogEntry.target` and :attr:`~AuditLogEntry.extra` fields are set." -msgstr "See :attr:`overwrite_create` for more information on how the :attr:`~AuditLogEntry.target` and :attr:`~AuditLogEntry.extra` fields are set." +msgid "See :attr:`overwrite_create` for more information on how the :func:`~AuditLogEntry.get_target` and :attr:`~AuditLogEntry.extra` fields are set." +msgstr "See :attr:`overwrite_create` for more information on how the :func:`~AuditLogEntry.get_target` and :attr:`~AuditLogEntry.extra` fields are set." msgid "A channel permission overwrite was deleted." msgstr "A channel permission overwrite was deleted." @@ -785,8 +785,8 @@ msgstr "A channel permission overwrite was deleted." msgid "A member was kicked." msgstr "A member was kicked." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got kicked." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got kicked." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got kicked." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got kicked." msgid "When this is the action, :attr:`~AuditLogEntry.changes` is empty." msgstr "When this is the action, :attr:`~AuditLogEntry.changes` is empty." @@ -794,8 +794,8 @@ msgstr "When this is the action, :attr:`~AuditLogEntry.changes` is empty." msgid "A member prune was triggered." msgstr "A member prune was triggered." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is set to ``None``." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is set to ``None``." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is set to ``None``." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is set to ``None``." msgid "When this is the action, the type of :attr:`~AuditLogEntry.extra` is set to an unspecified proxy object with two attributes:" msgstr "When this is the action, the type of :attr:`~AuditLogEntry.extra` is set to an unspecified proxy object with two attributes:" @@ -809,14 +809,14 @@ msgstr "``members_removed``: An integer specifying how many members were removed msgid "A member was banned." msgstr "A member was banned." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got banned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got banned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got banned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got banned." msgid "A member was unbanned." msgstr "A member was unbanned." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got unbanned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got unbanned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got unbanned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got unbanned." msgid "A member has updated. This triggers in the following situations:" msgstr "A member has updated. This triggers in the following situations:" @@ -827,8 +827,8 @@ msgstr "A nickname was changed" msgid "They were server muted or deafened (or it was undone)" msgstr "They were server muted or deafened (or it was undone)" -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got updated." msgid ":attr:`~AuditLogDiff.nick`" msgstr ":attr:`~AuditLogDiff.nick`" @@ -842,8 +842,8 @@ msgstr ":attr:`~AuditLogDiff.deaf`" msgid "A member's role has been updated. This triggers when a member either gains a role or loses a role." msgstr "A member's role has been updated. This triggers when a member either gains a role or loses a role." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got the role." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got the role." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got the role." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got the role." msgid ":attr:`~AuditLogDiff.roles`" msgstr ":attr:`~AuditLogDiff.roles`" @@ -869,14 +869,14 @@ msgstr "``count``: An integer specifying how many members were disconnected." msgid "A bot was added to the guild." msgstr "A bot was added to the guild." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` which was added to the guild." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` which was added to the guild." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` which was added to the guild." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` which was added to the guild." msgid "A new role was created." msgstr "A new role was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Role` or a :class:`Object` with the ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Role` or a :class:`Object` with the ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Role` or a :class:`Object` with the ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Role` or a :class:`Object` with the ID." msgid ":attr:`~AuditLogDiff.colour`" msgstr ":attr:`~AuditLogDiff.colour`" @@ -911,8 +911,8 @@ msgstr "A role was deleted." msgid "An invite was created." msgstr "An invite was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was created." msgid ":attr:`~AuditLogDiff.max_age`" msgstr ":attr:`~AuditLogDiff.max_age`" @@ -938,20 +938,20 @@ msgstr ":attr:`~AuditLogDiff.max_uses`" msgid "An invite was updated." msgstr "An invite was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was updated." msgid "An invite was deleted." msgstr "An invite was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was deleted." msgid "A webhook was created." msgstr "A webhook was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the webhook ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the webhook ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the webhook ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the webhook ID." msgid ":attr:`~AuditLogDiff.type` (always set to ``1`` if so)" msgstr ":attr:`~AuditLogDiff.type` (always set to ``1`` if so)" @@ -974,8 +974,8 @@ msgstr "A webhook was deleted." msgid "An emoji was created." msgstr "An emoji was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." msgid "An emoji was updated. This triggers when the name has changed." msgstr "An emoji was updated. This triggers when the name has changed." @@ -983,14 +983,14 @@ msgstr "An emoji was updated. This triggers when the name has changed." msgid "An emoji was deleted." msgstr "An emoji was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the emoji ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the emoji ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the emoji ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the emoji ID." msgid "A message was deleted by a moderator. Note that this only triggers if the message was deleted by someone other than the author." msgstr "A message was deleted by a moderator. Note that this only triggers if the message was deleted by someone other than the author." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message deleted." msgid "``count``: An integer specifying how many messages were deleted." msgstr "``count``: An integer specifying how many messages were deleted." @@ -1001,14 +1001,14 @@ msgstr "``channel``: A :class:`TextChannel` or :class:`Object` with the channel msgid "Messages were bulk deleted by a moderator." msgstr "Messages were bulk deleted by a moderator." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." msgid "A message was pinned in a channel." msgstr "A message was pinned in a channel." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message pinned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message pinned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message pinned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message pinned." msgid "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was pinned." msgstr "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was pinned." @@ -1019,8 +1019,8 @@ msgstr "``message_id``: the ID of the message which was pinned." msgid "A message was unpinned in a channel." msgstr "A message was unpinned in a channel." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message unpinned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message unpinned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message unpinned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message unpinned." msgid "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was unpinned." msgstr "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was unpinned." @@ -1031,26 +1031,26 @@ msgstr "``message_id``: the ID of the message which was unpinned." msgid "A guild integration was created." msgstr "A guild integration was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was created." msgid "A guild integration was updated." msgstr "A guild integration was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was updated." msgid "A guild integration was deleted." msgstr "A guild integration was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was deleted." msgid "A stage instance was started." msgstr "A stage instance was started." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." msgid ":attr:`~AuditLogDiff.privacy_level`" msgstr ":attr:`~AuditLogDiff.privacy_level`" @@ -1058,8 +1058,8 @@ msgstr ":attr:`~AuditLogDiff.privacy_level`" msgid "A stage instance was updated." msgstr "A stage instance was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." msgid "A stage instance was ended." msgstr "A stage instance was ended." @@ -1067,8 +1067,8 @@ msgstr "A stage instance was ended." msgid "A sticker was created." msgstr "A sticker was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." msgid ":attr:`~AuditLogDiff.emoji`" msgstr ":attr:`~AuditLogDiff.emoji`" @@ -1091,8 +1091,8 @@ msgstr "A sticker was deleted." msgid "A scheduled event was created." msgstr "A scheduled event was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." msgid ":attr:`~discord.ScheduledEvent.location`" msgstr ":attr:`~discord.ScheduledEvent.location`" @@ -1115,8 +1115,8 @@ msgstr "A scheduled event was deleted." msgid "A thread was created." msgstr "A thread was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." msgid ":attr:`~AuditLogDiff.archived`" msgstr ":attr:`~AuditLogDiff.archived`" @@ -1133,20 +1133,20 @@ msgstr ":attr:`~AuditLogDiff.invitable`" msgid "A thread was updated." msgstr "A thread was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." msgid "A thread was deleted." msgstr "A thread was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." msgid "An application command's permissions were updated." msgstr "An application command's permissions were updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with the ID of the command that had it's permissions edited." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with the ID of the command that had it's permissions edited." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with the ID of the command that had it's permissions edited." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with the ID of the command that had it's permissions edited." msgid ":attr:`~AuditLogDiff.command_id`" msgstr ":attr:`~AuditLogDiff.command_id`" @@ -1199,8 +1199,8 @@ msgstr "The creator monetization terms were accepted." msgid "A voice channel status was updated." msgstr "A voice channel status was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." msgid ":attr:`~AuditLogDiff.status`" msgstr ":attr:`~AuditLogDiff.status`" diff --git a/docs/locales/hi/LC_MESSAGES/api/enums.po b/docs/locales/hi/LC_MESSAGES/api/enums.po index bc214e5db0..cb033dc5c4 100644 --- a/docs/locales/hi/LC_MESSAGES/api/enums.po +++ b/docs/locales/hi/LC_MESSAGES/api/enums.po @@ -656,8 +656,8 @@ msgstr "Changing the guild moderation settings" msgid "Changing things related to the guild widget" msgstr "Changing things related to the guild widget" -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Guild`." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Guild`." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Guild`." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Guild`." msgid "Possible attributes for :class:`AuditLogDiff`:" msgstr "Possible attributes for :class:`AuditLogDiff`:" @@ -704,8 +704,8 @@ msgstr ":attr:`~AuditLogDiff.vanity_url_code`" msgid "A new channel was created." msgstr "A new channel was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." msgid "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after`." msgstr "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after`." @@ -725,8 +725,8 @@ msgstr "The channel name or topic was changed" msgid "The channel bitrate was changed" msgstr "The channel bitrate was changed" -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." msgid "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after` or :attr:`~AuditLogEntry.before`." msgstr "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after` or :attr:`~AuditLogEntry.before`." @@ -752,8 +752,8 @@ msgstr ":attr:`~AuditLogDiff.default_auto_archive_duration`" msgid "A channel was deleted." msgstr "A channel was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with an ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with an ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with an ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with an ID." msgid "A more filled out object can be found by using the :attr:`~AuditLogEntry.before` object." msgstr "A more filled out object can be found by using the :attr:`~AuditLogEntry.before` object." @@ -776,8 +776,8 @@ msgstr ":attr:`~AuditLogDiff.id`" msgid "A channel permission overwrite was changed, this is typically when the permission values change." msgstr "A channel permission overwrite was changed, this is typically when the permission values change." -msgid "See :attr:`overwrite_create` for more information on how the :attr:`~AuditLogEntry.target` and :attr:`~AuditLogEntry.extra` fields are set." -msgstr "See :attr:`overwrite_create` for more information on how the :attr:`~AuditLogEntry.target` and :attr:`~AuditLogEntry.extra` fields are set." +msgid "See :attr:`overwrite_create` for more information on how the :func:`~AuditLogEntry.get_target` and :attr:`~AuditLogEntry.extra` fields are set." +msgstr "See :attr:`overwrite_create` for more information on how the :func:`~AuditLogEntry.get_target` and :attr:`~AuditLogEntry.extra` fields are set." msgid "A channel permission overwrite was deleted." msgstr "A channel permission overwrite was deleted." @@ -785,8 +785,8 @@ msgstr "A channel permission overwrite was deleted." msgid "A member was kicked." msgstr "A member was kicked." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got kicked." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got kicked." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got kicked." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got kicked." msgid "When this is the action, :attr:`~AuditLogEntry.changes` is empty." msgstr "When this is the action, :attr:`~AuditLogEntry.changes` is empty." @@ -794,8 +794,8 @@ msgstr "When this is the action, :attr:`~AuditLogEntry.changes` is empty." msgid "A member prune was triggered." msgstr "A member prune was triggered." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is set to ``None``." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is set to ``None``." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is set to ``None``." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is set to ``None``." msgid "When this is the action, the type of :attr:`~AuditLogEntry.extra` is set to an unspecified proxy object with two attributes:" msgstr "When this is the action, the type of :attr:`~AuditLogEntry.extra` is set to an unspecified proxy object with two attributes:" @@ -809,14 +809,14 @@ msgstr "``members_removed``: An integer specifying how many members were removed msgid "A member was banned." msgstr "A member was banned." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got banned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got banned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got banned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got banned." msgid "A member was unbanned." msgstr "A member was unbanned." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got unbanned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got unbanned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got unbanned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got unbanned." msgid "A member has updated. This triggers in the following situations:" msgstr "A member has updated. This triggers in the following situations:" @@ -827,8 +827,8 @@ msgstr "A nickname was changed" msgid "They were server muted or deafened (or it was undone)" msgstr "They were server muted or deafened (or it was undone)" -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got updated." msgid ":attr:`~AuditLogDiff.nick`" msgstr ":attr:`~AuditLogDiff.nick`" @@ -842,8 +842,8 @@ msgstr ":attr:`~AuditLogDiff.deaf`" msgid "A member's role has been updated. This triggers when a member either gains a role or loses a role." msgstr "A member's role has been updated. This triggers when a member either gains a role or loses a role." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got the role." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got the role." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got the role." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got the role." msgid ":attr:`~AuditLogDiff.roles`" msgstr ":attr:`~AuditLogDiff.roles`" @@ -869,14 +869,14 @@ msgstr "``count``: An integer specifying how many members were disconnected." msgid "A bot was added to the guild." msgstr "A bot was added to the guild." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` which was added to the guild." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` which was added to the guild." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` which was added to the guild." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` which was added to the guild." msgid "A new role was created." msgstr "A new role was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Role` or a :class:`Object` with the ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Role` or a :class:`Object` with the ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Role` or a :class:`Object` with the ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Role` or a :class:`Object` with the ID." msgid ":attr:`~AuditLogDiff.colour`" msgstr ":attr:`~AuditLogDiff.colour`" @@ -911,8 +911,8 @@ msgstr "A role was deleted." msgid "An invite was created." msgstr "An invite was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was created." msgid ":attr:`~AuditLogDiff.max_age`" msgstr ":attr:`~AuditLogDiff.max_age`" @@ -938,20 +938,20 @@ msgstr ":attr:`~AuditLogDiff.max_uses`" msgid "An invite was updated." msgstr "An invite was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was updated." msgid "An invite was deleted." msgstr "An invite was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was deleted." msgid "A webhook was created." msgstr "A webhook was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the webhook ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the webhook ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the webhook ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the webhook ID." msgid ":attr:`~AuditLogDiff.type` (always set to ``1`` if so)" msgstr ":attr:`~AuditLogDiff.type` (always set to ``1`` if so)" @@ -974,8 +974,8 @@ msgstr "A webhook was deleted." msgid "An emoji was created." msgstr "An emoji was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." msgid "An emoji was updated. This triggers when the name has changed." msgstr "An emoji was updated. This triggers when the name has changed." @@ -983,14 +983,14 @@ msgstr "An emoji was updated. This triggers when the name has changed." msgid "An emoji was deleted." msgstr "An emoji was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the emoji ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the emoji ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the emoji ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the emoji ID." msgid "A message was deleted by a moderator. Note that this only triggers if the message was deleted by someone other than the author." msgstr "A message was deleted by a moderator. Note that this only triggers if the message was deleted by someone other than the author." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message deleted." msgid "``count``: An integer specifying how many messages were deleted." msgstr "``count``: An integer specifying how many messages were deleted." @@ -1001,14 +1001,14 @@ msgstr "``channel``: A :class:`TextChannel` or :class:`Object` with the channel msgid "Messages were bulk deleted by a moderator." msgstr "Messages were bulk deleted by a moderator." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." msgid "A message was pinned in a channel." msgstr "A message was pinned in a channel." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message pinned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message pinned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message pinned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message pinned." msgid "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was pinned." msgstr "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was pinned." @@ -1019,8 +1019,8 @@ msgstr "``message_id``: the ID of the message which was pinned." msgid "A message was unpinned in a channel." msgstr "A message was unpinned in a channel." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message unpinned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message unpinned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message unpinned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message unpinned." msgid "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was unpinned." msgstr "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was unpinned." @@ -1031,26 +1031,26 @@ msgstr "``message_id``: the ID of the message which was unpinned." msgid "A guild integration was created." msgstr "A guild integration was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was created." msgid "A guild integration was updated." msgstr "A guild integration was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was updated." msgid "A guild integration was deleted." msgstr "A guild integration was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was deleted." msgid "A stage instance was started." msgstr "A stage instance was started." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." msgid ":attr:`~AuditLogDiff.privacy_level`" msgstr ":attr:`~AuditLogDiff.privacy_level`" @@ -1058,8 +1058,8 @@ msgstr ":attr:`~AuditLogDiff.privacy_level`" msgid "A stage instance was updated." msgstr "A stage instance was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." msgid "A stage instance was ended." msgstr "A stage instance was ended." @@ -1067,8 +1067,8 @@ msgstr "A stage instance was ended." msgid "A sticker was created." msgstr "A sticker was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." msgid ":attr:`~AuditLogDiff.emoji`" msgstr ":attr:`~AuditLogDiff.emoji`" @@ -1091,8 +1091,8 @@ msgstr "A sticker was deleted." msgid "A scheduled event was created." msgstr "A scheduled event was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." msgid ":attr:`~discord.ScheduledEvent.location`" msgstr ":attr:`~discord.ScheduledEvent.location`" @@ -1115,8 +1115,8 @@ msgstr "A scheduled event was deleted." msgid "A thread was created." msgstr "A thread was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." msgid ":attr:`~AuditLogDiff.archived`" msgstr ":attr:`~AuditLogDiff.archived`" @@ -1133,20 +1133,20 @@ msgstr ":attr:`~AuditLogDiff.invitable`" msgid "A thread was updated." msgstr "A thread was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." msgid "A thread was deleted." msgstr "A thread was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." msgid "An application command's permissions were updated." msgstr "An application command's permissions were updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with the ID of the command that had it's permissions edited." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with the ID of the command that had it's permissions edited." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with the ID of the command that had it's permissions edited." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with the ID of the command that had it's permissions edited." msgid ":attr:`~AuditLogDiff.command_id`" msgstr ":attr:`~AuditLogDiff.command_id`" @@ -1199,8 +1199,8 @@ msgstr "The creator monetization terms were accepted." msgid "A voice channel status was updated." msgstr "A voice channel status was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." msgid ":attr:`~AuditLogDiff.status`" msgstr ":attr:`~AuditLogDiff.status`" diff --git a/docs/locales/it/LC_MESSAGES/api/enums.po b/docs/locales/it/LC_MESSAGES/api/enums.po index bc214e5db0..cb033dc5c4 100644 --- a/docs/locales/it/LC_MESSAGES/api/enums.po +++ b/docs/locales/it/LC_MESSAGES/api/enums.po @@ -656,8 +656,8 @@ msgstr "Changing the guild moderation settings" msgid "Changing things related to the guild widget" msgstr "Changing things related to the guild widget" -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Guild`." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Guild`." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Guild`." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Guild`." msgid "Possible attributes for :class:`AuditLogDiff`:" msgstr "Possible attributes for :class:`AuditLogDiff`:" @@ -704,8 +704,8 @@ msgstr ":attr:`~AuditLogDiff.vanity_url_code`" msgid "A new channel was created." msgstr "A new channel was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." msgid "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after`." msgstr "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after`." @@ -725,8 +725,8 @@ msgstr "The channel name or topic was changed" msgid "The channel bitrate was changed" msgstr "The channel bitrate was changed" -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." msgid "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after` or :attr:`~AuditLogEntry.before`." msgstr "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after` or :attr:`~AuditLogEntry.before`." @@ -752,8 +752,8 @@ msgstr ":attr:`~AuditLogDiff.default_auto_archive_duration`" msgid "A channel was deleted." msgstr "A channel was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with an ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with an ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with an ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with an ID." msgid "A more filled out object can be found by using the :attr:`~AuditLogEntry.before` object." msgstr "A more filled out object can be found by using the :attr:`~AuditLogEntry.before` object." @@ -776,8 +776,8 @@ msgstr ":attr:`~AuditLogDiff.id`" msgid "A channel permission overwrite was changed, this is typically when the permission values change." msgstr "A channel permission overwrite was changed, this is typically when the permission values change." -msgid "See :attr:`overwrite_create` for more information on how the :attr:`~AuditLogEntry.target` and :attr:`~AuditLogEntry.extra` fields are set." -msgstr "See :attr:`overwrite_create` for more information on how the :attr:`~AuditLogEntry.target` and :attr:`~AuditLogEntry.extra` fields are set." +msgid "See :attr:`overwrite_create` for more information on how the :func:`~AuditLogEntry.get_target` and :attr:`~AuditLogEntry.extra` fields are set." +msgstr "See :attr:`overwrite_create` for more information on how the :func:`~AuditLogEntry.get_target` and :attr:`~AuditLogEntry.extra` fields are set." msgid "A channel permission overwrite was deleted." msgstr "A channel permission overwrite was deleted." @@ -785,8 +785,8 @@ msgstr "A channel permission overwrite was deleted." msgid "A member was kicked." msgstr "A member was kicked." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got kicked." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got kicked." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got kicked." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got kicked." msgid "When this is the action, :attr:`~AuditLogEntry.changes` is empty." msgstr "When this is the action, :attr:`~AuditLogEntry.changes` is empty." @@ -794,8 +794,8 @@ msgstr "When this is the action, :attr:`~AuditLogEntry.changes` is empty." msgid "A member prune was triggered." msgstr "A member prune was triggered." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is set to ``None``." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is set to ``None``." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is set to ``None``." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is set to ``None``." msgid "When this is the action, the type of :attr:`~AuditLogEntry.extra` is set to an unspecified proxy object with two attributes:" msgstr "When this is the action, the type of :attr:`~AuditLogEntry.extra` is set to an unspecified proxy object with two attributes:" @@ -809,14 +809,14 @@ msgstr "``members_removed``: An integer specifying how many members were removed msgid "A member was banned." msgstr "A member was banned." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got banned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got banned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got banned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got banned." msgid "A member was unbanned." msgstr "A member was unbanned." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got unbanned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got unbanned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got unbanned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got unbanned." msgid "A member has updated. This triggers in the following situations:" msgstr "A member has updated. This triggers in the following situations:" @@ -827,8 +827,8 @@ msgstr "A nickname was changed" msgid "They were server muted or deafened (or it was undone)" msgstr "They were server muted or deafened (or it was undone)" -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got updated." msgid ":attr:`~AuditLogDiff.nick`" msgstr ":attr:`~AuditLogDiff.nick`" @@ -842,8 +842,8 @@ msgstr ":attr:`~AuditLogDiff.deaf`" msgid "A member's role has been updated. This triggers when a member either gains a role or loses a role." msgstr "A member's role has been updated. This triggers when a member either gains a role or loses a role." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got the role." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got the role." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got the role." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got the role." msgid ":attr:`~AuditLogDiff.roles`" msgstr ":attr:`~AuditLogDiff.roles`" @@ -869,14 +869,14 @@ msgstr "``count``: An integer specifying how many members were disconnected." msgid "A bot was added to the guild." msgstr "A bot was added to the guild." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` which was added to the guild." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` which was added to the guild." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` which was added to the guild." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` which was added to the guild." msgid "A new role was created." msgstr "A new role was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Role` or a :class:`Object` with the ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Role` or a :class:`Object` with the ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Role` or a :class:`Object` with the ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Role` or a :class:`Object` with the ID." msgid ":attr:`~AuditLogDiff.colour`" msgstr ":attr:`~AuditLogDiff.colour`" @@ -911,8 +911,8 @@ msgstr "A role was deleted." msgid "An invite was created." msgstr "An invite was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was created." msgid ":attr:`~AuditLogDiff.max_age`" msgstr ":attr:`~AuditLogDiff.max_age`" @@ -938,20 +938,20 @@ msgstr ":attr:`~AuditLogDiff.max_uses`" msgid "An invite was updated." msgstr "An invite was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was updated." msgid "An invite was deleted." msgstr "An invite was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was deleted." msgid "A webhook was created." msgstr "A webhook was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the webhook ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the webhook ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the webhook ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the webhook ID." msgid ":attr:`~AuditLogDiff.type` (always set to ``1`` if so)" msgstr ":attr:`~AuditLogDiff.type` (always set to ``1`` if so)" @@ -974,8 +974,8 @@ msgstr "A webhook was deleted." msgid "An emoji was created." msgstr "An emoji was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." msgid "An emoji was updated. This triggers when the name has changed." msgstr "An emoji was updated. This triggers when the name has changed." @@ -983,14 +983,14 @@ msgstr "An emoji was updated. This triggers when the name has changed." msgid "An emoji was deleted." msgstr "An emoji was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the emoji ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the emoji ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the emoji ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the emoji ID." msgid "A message was deleted by a moderator. Note that this only triggers if the message was deleted by someone other than the author." msgstr "A message was deleted by a moderator. Note that this only triggers if the message was deleted by someone other than the author." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message deleted." msgid "``count``: An integer specifying how many messages were deleted." msgstr "``count``: An integer specifying how many messages were deleted." @@ -1001,14 +1001,14 @@ msgstr "``channel``: A :class:`TextChannel` or :class:`Object` with the channel msgid "Messages were bulk deleted by a moderator." msgstr "Messages were bulk deleted by a moderator." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." msgid "A message was pinned in a channel." msgstr "A message was pinned in a channel." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message pinned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message pinned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message pinned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message pinned." msgid "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was pinned." msgstr "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was pinned." @@ -1019,8 +1019,8 @@ msgstr "``message_id``: the ID of the message which was pinned." msgid "A message was unpinned in a channel." msgstr "A message was unpinned in a channel." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message unpinned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message unpinned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message unpinned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message unpinned." msgid "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was unpinned." msgstr "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was unpinned." @@ -1031,26 +1031,26 @@ msgstr "``message_id``: the ID of the message which was unpinned." msgid "A guild integration was created." msgstr "A guild integration was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was created." msgid "A guild integration was updated." msgstr "A guild integration was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was updated." msgid "A guild integration was deleted." msgstr "A guild integration was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was deleted." msgid "A stage instance was started." msgstr "A stage instance was started." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." msgid ":attr:`~AuditLogDiff.privacy_level`" msgstr ":attr:`~AuditLogDiff.privacy_level`" @@ -1058,8 +1058,8 @@ msgstr ":attr:`~AuditLogDiff.privacy_level`" msgid "A stage instance was updated." msgstr "A stage instance was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." msgid "A stage instance was ended." msgstr "A stage instance was ended." @@ -1067,8 +1067,8 @@ msgstr "A stage instance was ended." msgid "A sticker was created." msgstr "A sticker was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." msgid ":attr:`~AuditLogDiff.emoji`" msgstr ":attr:`~AuditLogDiff.emoji`" @@ -1091,8 +1091,8 @@ msgstr "A sticker was deleted." msgid "A scheduled event was created." msgstr "A scheduled event was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." msgid ":attr:`~discord.ScheduledEvent.location`" msgstr ":attr:`~discord.ScheduledEvent.location`" @@ -1115,8 +1115,8 @@ msgstr "A scheduled event was deleted." msgid "A thread was created." msgstr "A thread was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." msgid ":attr:`~AuditLogDiff.archived`" msgstr ":attr:`~AuditLogDiff.archived`" @@ -1133,20 +1133,20 @@ msgstr ":attr:`~AuditLogDiff.invitable`" msgid "A thread was updated." msgstr "A thread was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." msgid "A thread was deleted." msgstr "A thread was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." msgid "An application command's permissions were updated." msgstr "An application command's permissions were updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with the ID of the command that had it's permissions edited." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with the ID of the command that had it's permissions edited." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with the ID of the command that had it's permissions edited." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with the ID of the command that had it's permissions edited." msgid ":attr:`~AuditLogDiff.command_id`" msgstr ":attr:`~AuditLogDiff.command_id`" @@ -1199,8 +1199,8 @@ msgstr "The creator monetization terms were accepted." msgid "A voice channel status was updated." msgstr "A voice channel status was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." msgid ":attr:`~AuditLogDiff.status`" msgstr ":attr:`~AuditLogDiff.status`" diff --git a/docs/locales/ja/LC_MESSAGES/api/enums.po b/docs/locales/ja/LC_MESSAGES/api/enums.po index e4f5ebba42..792b61cbf2 100644 --- a/docs/locales/ja/LC_MESSAGES/api/enums.po +++ b/docs/locales/ja/LC_MESSAGES/api/enums.po @@ -656,8 +656,8 @@ msgstr "Changing the guild moderation settings" msgid "Changing things related to the guild widget" msgstr "Changing things related to the guild widget" -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Guild`." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Guild`." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Guild`." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Guild`." msgid "Possible attributes for :class:`AuditLogDiff`:" msgstr "Possible attributes for :class:`AuditLogDiff`:" @@ -704,8 +704,8 @@ msgstr ":attr:`~AuditLogDiff.vanity_url_code`" msgid "A new channel was created." msgstr "A new channel was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." msgid "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after`." msgstr "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after`." @@ -725,8 +725,8 @@ msgstr "The channel name or topic was changed" msgid "The channel bitrate was changed" msgstr "The channel bitrate was changed" -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." msgid "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after` or :attr:`~AuditLogEntry.before`." msgstr "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after` or :attr:`~AuditLogEntry.before`." @@ -752,8 +752,8 @@ msgstr ":attr:`~AuditLogDiff.default_auto_archive_duration`" msgid "A channel was deleted." msgstr "A channel was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with an ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with an ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with an ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with an ID." msgid "A more filled out object can be found by using the :attr:`~AuditLogEntry.before` object." msgstr "A more filled out object can be found by using the :attr:`~AuditLogEntry.before` object." @@ -776,8 +776,8 @@ msgstr ":attr:`~AuditLogDiff.id`" msgid "A channel permission overwrite was changed, this is typically when the permission values change." msgstr "A channel permission overwrite was changed, this is typically when the permission values change." -msgid "See :attr:`overwrite_create` for more information on how the :attr:`~AuditLogEntry.target` and :attr:`~AuditLogEntry.extra` fields are set." -msgstr "See :attr:`overwrite_create` for more information on how the :attr:`~AuditLogEntry.target` and :attr:`~AuditLogEntry.extra` fields are set." +msgid "See :attr:`overwrite_create` for more information on how the :func:`~AuditLogEntry.get_target` and :attr:`~AuditLogEntry.extra` fields are set." +msgstr "See :attr:`overwrite_create` for more information on how the :func:`~AuditLogEntry.get_target` and :attr:`~AuditLogEntry.extra` fields are set." msgid "A channel permission overwrite was deleted." msgstr "A channel permission overwrite was deleted." @@ -785,8 +785,8 @@ msgstr "A channel permission overwrite was deleted." msgid "A member was kicked." msgstr "A member was kicked." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got kicked." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got kicked." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got kicked." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got kicked." msgid "When this is the action, :attr:`~AuditLogEntry.changes` is empty." msgstr "When this is the action, :attr:`~AuditLogEntry.changes` is empty." @@ -794,8 +794,8 @@ msgstr "When this is the action, :attr:`~AuditLogEntry.changes` is empty." msgid "A member prune was triggered." msgstr "A member prune was triggered." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is set to ``None``." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is set to ``None``." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is set to ``None``." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is set to ``None``." msgid "When this is the action, the type of :attr:`~AuditLogEntry.extra` is set to an unspecified proxy object with two attributes:" msgstr "When this is the action, the type of :attr:`~AuditLogEntry.extra` is set to an unspecified proxy object with two attributes:" @@ -809,14 +809,14 @@ msgstr "``members_removed``: An integer specifying how many members were removed msgid "A member was banned." msgstr "A member was banned." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got banned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got banned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got banned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got banned." msgid "A member was unbanned." msgstr "A member was unbanned." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got unbanned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got unbanned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got unbanned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got unbanned." msgid "A member has updated. This triggers in the following situations:" msgstr "A member has updated. This triggers in the following situations:" @@ -827,8 +827,8 @@ msgstr "A nickname was changed" msgid "They were server muted or deafened (or it was undone)" msgstr "They were server muted or deafened (or it was undone)" -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got updated." msgid ":attr:`~AuditLogDiff.nick`" msgstr ":attr:`~AuditLogDiff.nick`" @@ -842,8 +842,8 @@ msgstr ":attr:`~AuditLogDiff.deaf`" msgid "A member's role has been updated. This triggers when a member either gains a role or loses a role." msgstr "A member's role has been updated. This triggers when a member either gains a role or loses a role." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got the role." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got the role." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got the role." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got the role." msgid ":attr:`~AuditLogDiff.roles`" msgstr ":attr:`~AuditLogDiff.roles`" @@ -869,14 +869,14 @@ msgstr "``count``: An integer specifying how many members were disconnected." msgid "A bot was added to the guild." msgstr "A bot was added to the guild." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` which was added to the guild." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` which was added to the guild." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` which was added to the guild." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` which was added to the guild." msgid "A new role was created." msgstr "A new role was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Role` or a :class:`Object` with the ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Role` or a :class:`Object` with the ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Role` or a :class:`Object` with the ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Role` or a :class:`Object` with the ID." msgid ":attr:`~AuditLogDiff.colour`" msgstr ":attr:`~AuditLogDiff.colour`" @@ -911,8 +911,8 @@ msgstr "A role was deleted." msgid "An invite was created." msgstr "An invite was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was created." msgid ":attr:`~AuditLogDiff.max_age`" msgstr ":attr:`~AuditLogDiff.max_age`" @@ -938,20 +938,20 @@ msgstr ":attr:`~AuditLogDiff.max_uses`" msgid "An invite was updated." msgstr "An invite was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was updated." msgid "An invite was deleted." msgstr "An invite was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was deleted." msgid "A webhook was created." msgstr "A webhook was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the webhook ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the webhook ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the webhook ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the webhook ID." msgid ":attr:`~AuditLogDiff.type` (always set to ``1`` if so)" msgstr ":attr:`~AuditLogDiff.type` (always set to ``1`` if so)" @@ -974,8 +974,8 @@ msgstr "A webhook was deleted." msgid "An emoji was created." msgstr "An emoji was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." msgid "An emoji was updated. This triggers when the name has changed." msgstr "An emoji was updated. This triggers when the name has changed." @@ -983,14 +983,14 @@ msgstr "An emoji was updated. This triggers when the name has changed." msgid "An emoji was deleted." msgstr "An emoji was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the emoji ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the emoji ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the emoji ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the emoji ID." msgid "A message was deleted by a moderator. Note that this only triggers if the message was deleted by someone other than the author." msgstr "A message was deleted by a moderator. Note that this only triggers if the message was deleted by someone other than the author." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message deleted." msgid "``count``: An integer specifying how many messages were deleted." msgstr "``count``: An integer specifying how many messages were deleted." @@ -1001,14 +1001,14 @@ msgstr "``channel``: A :class:`TextChannel` or :class:`Object` with the channel msgid "Messages were bulk deleted by a moderator." msgstr "Messages were bulk deleted by a moderator." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." msgid "A message was pinned in a channel." msgstr "A message was pinned in a channel." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message pinned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message pinned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message pinned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message pinned." msgid "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was pinned." msgstr "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was pinned." @@ -1019,8 +1019,8 @@ msgstr "``message_id``: the ID of the message which was pinned." msgid "A message was unpinned in a channel." msgstr "A message was unpinned in a channel." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message unpinned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message unpinned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message unpinned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message unpinned." msgid "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was unpinned." msgstr "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was unpinned." @@ -1031,26 +1031,26 @@ msgstr "``message_id``: the ID of the message which was unpinned." msgid "A guild integration was created." msgstr "A guild integration was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was created." msgid "A guild integration was updated." msgstr "A guild integration was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was updated." msgid "A guild integration was deleted." msgstr "A guild integration was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was deleted." msgid "A stage instance was started." msgstr "A stage instance was started." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." msgid ":attr:`~AuditLogDiff.privacy_level`" msgstr ":attr:`~AuditLogDiff.privacy_level`" @@ -1058,8 +1058,8 @@ msgstr ":attr:`~AuditLogDiff.privacy_level`" msgid "A stage instance was updated." msgstr "A stage instance was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." msgid "A stage instance was ended." msgstr "A stage instance was ended." @@ -1067,8 +1067,8 @@ msgstr "A stage instance was ended." msgid "A sticker was created." msgstr "A sticker was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." msgid ":attr:`~AuditLogDiff.emoji`" msgstr ":attr:`~AuditLogDiff.emoji`" @@ -1091,8 +1091,8 @@ msgstr "A sticker was deleted." msgid "A scheduled event was created." msgstr "A scheduled event was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." msgid ":attr:`~discord.ScheduledEvent.location`" msgstr ":attr:`~discord.ScheduledEvent.location`" @@ -1115,8 +1115,8 @@ msgstr "A scheduled event was deleted." msgid "A thread was created." msgstr "A thread was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." msgid ":attr:`~AuditLogDiff.archived`" msgstr ":attr:`~AuditLogDiff.archived`" @@ -1133,20 +1133,20 @@ msgstr ":attr:`~AuditLogDiff.invitable`" msgid "A thread was updated." msgstr "A thread was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." msgid "A thread was deleted." msgstr "A thread was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." msgid "An application command's permissions were updated." msgstr "An application command's permissions were updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with the ID of the command that had it's permissions edited." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with the ID of the command that had it's permissions edited." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with the ID of the command that had it's permissions edited." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with the ID of the command that had it's permissions edited." msgid ":attr:`~AuditLogDiff.command_id`" msgstr ":attr:`~AuditLogDiff.command_id`" @@ -1199,8 +1199,8 @@ msgstr "The creator monetization terms were accepted." msgid "A voice channel status was updated." msgstr "A voice channel status was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." msgid ":attr:`~AuditLogDiff.status`" msgstr ":attr:`~AuditLogDiff.status`" diff --git a/docs/locales/ja/LC_MESSAGES/build/locales/api/enums.po b/docs/locales/ja/LC_MESSAGES/build/locales/api/enums.po index f43361483c..f140fc4020 100644 --- a/docs/locales/ja/LC_MESSAGES/build/locales/api/enums.po +++ b/docs/locales/ja/LC_MESSAGES/build/locales/api/enums.po @@ -656,8 +656,8 @@ msgstr "Changing the guild moderation settings" msgid "Changing things related to the guild widget" msgstr "Changing things related to the guild widget" -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Guild`." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Guild`." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Guild`." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Guild`." msgid "Possible attributes for :class:`AuditLogDiff`:" msgstr "Possible attributes for :class:`AuditLogDiff`:" @@ -704,8 +704,8 @@ msgstr ":attr:`~AuditLogDiff.vanity_url_code`" msgid "A new channel was created." msgstr "A new channel was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." msgid "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after`." msgstr "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after`." @@ -725,8 +725,8 @@ msgstr "The channel name or topic was changed" msgid "The channel bitrate was changed" msgstr "The channel bitrate was changed" -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." msgid "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after` or :attr:`~AuditLogEntry.before`." msgstr "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after` or :attr:`~AuditLogEntry.before`." @@ -752,8 +752,8 @@ msgstr ":attr:`~AuditLogDiff.default_auto_archive_duration`" msgid "A channel was deleted." msgstr "A channel was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with an ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with an ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with an ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with an ID." msgid "A more filled out object can be found by using the :attr:`~AuditLogEntry.before` object." msgstr "A more filled out object can be found by using the :attr:`~AuditLogEntry.before` object." @@ -776,8 +776,8 @@ msgstr ":attr:`~AuditLogDiff.id`" msgid "A channel permission overwrite was changed, this is typically when the permission values change." msgstr "A channel permission overwrite was changed, this is typically when the permission values change." -msgid "See :attr:`overwrite_create` for more information on how the :attr:`~AuditLogEntry.target` and :attr:`~AuditLogEntry.extra` fields are set." -msgstr "See :attr:`overwrite_create` for more information on how the :attr:`~AuditLogEntry.target` and :attr:`~AuditLogEntry.extra` fields are set." +msgid "See :attr:`overwrite_create` for more information on how the :func:`~AuditLogEntry.get_target` and :attr:`~AuditLogEntry.extra` fields are set." +msgstr "See :attr:`overwrite_create` for more information on how the :func:`~AuditLogEntry.get_target` and :attr:`~AuditLogEntry.extra` fields are set." msgid "A channel permission overwrite was deleted." msgstr "A channel permission overwrite was deleted." @@ -785,8 +785,8 @@ msgstr "A channel permission overwrite was deleted." msgid "A member was kicked." msgstr "A member was kicked." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got kicked." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got kicked." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got kicked." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got kicked." msgid "When this is the action, :attr:`~AuditLogEntry.changes` is empty." msgstr "When this is the action, :attr:`~AuditLogEntry.changes` is empty." @@ -794,8 +794,8 @@ msgstr "When this is the action, :attr:`~AuditLogEntry.changes` is empty." msgid "A member prune was triggered." msgstr "A member prune was triggered." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is set to ``None``." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is set to ``None``." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is set to ``None``." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is set to ``None``." msgid "When this is the action, the type of :attr:`~AuditLogEntry.extra` is set to an unspecified proxy object with two attributes:" msgstr "When this is the action, the type of :attr:`~AuditLogEntry.extra` is set to an unspecified proxy object with two attributes:" @@ -809,14 +809,14 @@ msgstr "``members_removed``: An integer specifying how many members were removed msgid "A member was banned." msgstr "A member was banned." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got banned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got banned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got banned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got banned." msgid "A member was unbanned." msgstr "A member was unbanned." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got unbanned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got unbanned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got unbanned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got unbanned." msgid "A member has updated. This triggers in the following situations:" msgstr "A member has updated. This triggers in the following situations:" @@ -827,8 +827,8 @@ msgstr "A nickname was changed" msgid "They were server muted or deafened (or it was undone)" msgstr "They were server muted or deafened (or it was undone)" -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got updated." msgid ":attr:`~AuditLogDiff.nick`" msgstr ":attr:`~AuditLogDiff.nick`" @@ -842,8 +842,8 @@ msgstr ":attr:`~AuditLogDiff.deaf`" msgid "A member's role has been updated. This triggers when a member either gains a role or loses a role." msgstr "A member's role has been updated. This triggers when a member either gains a role or loses a role." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got the role." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got the role." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got the role." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got the role." msgid ":attr:`~AuditLogDiff.roles`" msgstr ":attr:`~AuditLogDiff.roles`" @@ -869,14 +869,14 @@ msgstr "``count``: An integer specifying how many members were disconnected." msgid "A bot was added to the guild." msgstr "A bot was added to the guild." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` which was added to the guild." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` which was added to the guild." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` which was added to the guild." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` which was added to the guild." msgid "A new role was created." msgstr "A new role was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Role` or a :class:`Object` with the ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Role` or a :class:`Object` with the ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Role` or a :class:`Object` with the ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Role` or a :class:`Object` with the ID." msgid ":attr:`~AuditLogDiff.colour`" msgstr ":attr:`~AuditLogDiff.colour`" @@ -911,8 +911,8 @@ msgstr "A role was deleted." msgid "An invite was created." msgstr "An invite was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was created." msgid ":attr:`~AuditLogDiff.max_age`" msgstr ":attr:`~AuditLogDiff.max_age`" @@ -938,20 +938,20 @@ msgstr ":attr:`~AuditLogDiff.max_uses`" msgid "An invite was updated." msgstr "An invite was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was updated." msgid "An invite was deleted." msgstr "An invite was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was deleted." msgid "A webhook was created." msgstr "A webhook was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the webhook ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the webhook ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the webhook ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the webhook ID." msgid ":attr:`~AuditLogDiff.type` (always set to ``1`` if so)" msgstr ":attr:`~AuditLogDiff.type` (always set to ``1`` if so)" @@ -974,8 +974,8 @@ msgstr "A webhook was deleted." msgid "An emoji was created." msgstr "An emoji was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Emoji` or :class:`Object` with the emoji ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Emoji` or :class:`Object` with the emoji ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Emoji` or :class:`Object` with the emoji ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Emoji` or :class:`Object` with the emoji ID." msgid "An emoji was updated. This triggers when the name has changed." msgstr "An emoji was updated. This triggers when the name has changed." @@ -983,14 +983,14 @@ msgstr "An emoji was updated. This triggers when the name has changed." msgid "An emoji was deleted." msgstr "An emoji was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the emoji ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the emoji ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the emoji ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the emoji ID." msgid "A message was deleted by a moderator. Note that this only triggers if the message was deleted by someone other than the author." msgstr "A message was deleted by a moderator. Note that this only triggers if the message was deleted by someone other than the author." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message deleted." msgid "``count``: An integer specifying how many messages were deleted." msgstr "``count``: An integer specifying how many messages were deleted." @@ -1001,14 +1001,14 @@ msgstr "``channel``: A :class:`TextChannel` or :class:`Object` with the channel msgid "Messages were bulk deleted by a moderator." msgstr "Messages were bulk deleted by a moderator." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." msgid "A message was pinned in a channel." msgstr "A message was pinned in a channel." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message pinned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message pinned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message pinned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message pinned." msgid "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was pinned." msgstr "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was pinned." @@ -1019,8 +1019,8 @@ msgstr "``message_id``: the ID of the message which was pinned." msgid "A message was unpinned in a channel." msgstr "A message was unpinned in a channel." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message unpinned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message unpinned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message unpinned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message unpinned." msgid "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was unpinned." msgstr "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was unpinned." @@ -1031,26 +1031,26 @@ msgstr "``message_id``: the ID of the message which was unpinned." msgid "A guild integration was created." msgstr "A guild integration was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was created." msgid "A guild integration was updated." msgstr "A guild integration was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was updated." msgid "A guild integration was deleted." msgstr "A guild integration was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was deleted." msgid "A stage instance was started." msgstr "A stage instance was started." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." msgid ":attr:`~AuditLogDiff.privacy_level`" msgstr ":attr:`~AuditLogDiff.privacy_level`" @@ -1058,8 +1058,8 @@ msgstr ":attr:`~AuditLogDiff.privacy_level`" msgid "A stage instance was updated." msgstr "A stage instance was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." msgid "A stage instance was ended." msgstr "A stage instance was ended." @@ -1067,8 +1067,8 @@ msgstr "A stage instance was ended." msgid "A sticker was created." msgstr "A sticker was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." msgid ":attr:`~AuditLogDiff.emoji`" msgstr ":attr:`~AuditLogDiff.emoji`" @@ -1091,8 +1091,8 @@ msgstr "A sticker was deleted." msgid "A scheduled event was created." msgstr "A scheduled event was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." msgid ":attr:`~discord.ScheduledEvent.location`" msgstr ":attr:`~discord.ScheduledEvent.location`" @@ -1115,8 +1115,8 @@ msgstr "A scheduled event was deleted." msgid "A thread was created." msgstr "A thread was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." msgid ":attr:`~AuditLogDiff.archived`" msgstr ":attr:`~AuditLogDiff.archived`" @@ -1133,20 +1133,20 @@ msgstr ":attr:`~AuditLogDiff.invitable`" msgid "A thread was updated." msgstr "A thread was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." msgid "A thread was deleted." msgstr "A thread was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." msgid "An application command's permissions were updated." msgstr "An application command's permissions were updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with the ID of the command that had it's permissions edited." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with the ID of the command that had it's permissions edited." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with the ID of the command that had it's permissions edited." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with the ID of the command that had it's permissions edited." msgid ":attr:`~AuditLogDiff.command_id`" msgstr ":attr:`~AuditLogDiff.command_id`" @@ -1199,8 +1199,8 @@ msgstr "The creator monetization terms were accepted." msgid "A voice channel status was updated." msgstr "A voice channel status was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." msgid ":attr:`~AuditLogDiff.status`" msgstr ":attr:`~AuditLogDiff.status`" diff --git a/docs/locales/ko/LC_MESSAGES/api/enums.po b/docs/locales/ko/LC_MESSAGES/api/enums.po index e4f5ebba42..792b61cbf2 100644 --- a/docs/locales/ko/LC_MESSAGES/api/enums.po +++ b/docs/locales/ko/LC_MESSAGES/api/enums.po @@ -656,8 +656,8 @@ msgstr "Changing the guild moderation settings" msgid "Changing things related to the guild widget" msgstr "Changing things related to the guild widget" -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Guild`." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Guild`." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Guild`." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Guild`." msgid "Possible attributes for :class:`AuditLogDiff`:" msgstr "Possible attributes for :class:`AuditLogDiff`:" @@ -704,8 +704,8 @@ msgstr ":attr:`~AuditLogDiff.vanity_url_code`" msgid "A new channel was created." msgstr "A new channel was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." msgid "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after`." msgstr "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after`." @@ -725,8 +725,8 @@ msgstr "The channel name or topic was changed" msgid "The channel bitrate was changed" msgstr "The channel bitrate was changed" -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." msgid "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after` or :attr:`~AuditLogEntry.before`." msgstr "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after` or :attr:`~AuditLogEntry.before`." @@ -752,8 +752,8 @@ msgstr ":attr:`~AuditLogDiff.default_auto_archive_duration`" msgid "A channel was deleted." msgstr "A channel was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with an ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with an ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with an ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with an ID." msgid "A more filled out object can be found by using the :attr:`~AuditLogEntry.before` object." msgstr "A more filled out object can be found by using the :attr:`~AuditLogEntry.before` object." @@ -776,8 +776,8 @@ msgstr ":attr:`~AuditLogDiff.id`" msgid "A channel permission overwrite was changed, this is typically when the permission values change." msgstr "A channel permission overwrite was changed, this is typically when the permission values change." -msgid "See :attr:`overwrite_create` for more information on how the :attr:`~AuditLogEntry.target` and :attr:`~AuditLogEntry.extra` fields are set." -msgstr "See :attr:`overwrite_create` for more information on how the :attr:`~AuditLogEntry.target` and :attr:`~AuditLogEntry.extra` fields are set." +msgid "See :attr:`overwrite_create` for more information on how the :func:`~AuditLogEntry.get_target` and :attr:`~AuditLogEntry.extra` fields are set." +msgstr "See :attr:`overwrite_create` for more information on how the :func:`~AuditLogEntry.get_target` and :attr:`~AuditLogEntry.extra` fields are set." msgid "A channel permission overwrite was deleted." msgstr "A channel permission overwrite was deleted." @@ -785,8 +785,8 @@ msgstr "A channel permission overwrite was deleted." msgid "A member was kicked." msgstr "A member was kicked." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got kicked." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got kicked." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got kicked." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got kicked." msgid "When this is the action, :attr:`~AuditLogEntry.changes` is empty." msgstr "When this is the action, :attr:`~AuditLogEntry.changes` is empty." @@ -794,8 +794,8 @@ msgstr "When this is the action, :attr:`~AuditLogEntry.changes` is empty." msgid "A member prune was triggered." msgstr "A member prune was triggered." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is set to ``None``." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is set to ``None``." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is set to ``None``." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is set to ``None``." msgid "When this is the action, the type of :attr:`~AuditLogEntry.extra` is set to an unspecified proxy object with two attributes:" msgstr "When this is the action, the type of :attr:`~AuditLogEntry.extra` is set to an unspecified proxy object with two attributes:" @@ -809,14 +809,14 @@ msgstr "``members_removed``: An integer specifying how many members were removed msgid "A member was banned." msgstr "A member was banned." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got banned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got banned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got banned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got banned." msgid "A member was unbanned." msgstr "A member was unbanned." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got unbanned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got unbanned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got unbanned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got unbanned." msgid "A member has updated. This triggers in the following situations:" msgstr "A member has updated. This triggers in the following situations:" @@ -827,8 +827,8 @@ msgstr "A nickname was changed" msgid "They were server muted or deafened (or it was undone)" msgstr "They were server muted or deafened (or it was undone)" -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got updated." msgid ":attr:`~AuditLogDiff.nick`" msgstr ":attr:`~AuditLogDiff.nick`" @@ -842,8 +842,8 @@ msgstr ":attr:`~AuditLogDiff.deaf`" msgid "A member's role has been updated. This triggers when a member either gains a role or loses a role." msgstr "A member's role has been updated. This triggers when a member either gains a role or loses a role." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got the role." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got the role." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got the role." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got the role." msgid ":attr:`~AuditLogDiff.roles`" msgstr ":attr:`~AuditLogDiff.roles`" @@ -869,14 +869,14 @@ msgstr "``count``: An integer specifying how many members were disconnected." msgid "A bot was added to the guild." msgstr "A bot was added to the guild." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` which was added to the guild." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` which was added to the guild." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` which was added to the guild." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` which was added to the guild." msgid "A new role was created." msgstr "A new role was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Role` or a :class:`Object` with the ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Role` or a :class:`Object` with the ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Role` or a :class:`Object` with the ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Role` or a :class:`Object` with the ID." msgid ":attr:`~AuditLogDiff.colour`" msgstr ":attr:`~AuditLogDiff.colour`" @@ -911,8 +911,8 @@ msgstr "A role was deleted." msgid "An invite was created." msgstr "An invite was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was created." msgid ":attr:`~AuditLogDiff.max_age`" msgstr ":attr:`~AuditLogDiff.max_age`" @@ -938,20 +938,20 @@ msgstr ":attr:`~AuditLogDiff.max_uses`" msgid "An invite was updated." msgstr "An invite was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was updated." msgid "An invite was deleted." msgstr "An invite was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was deleted." msgid "A webhook was created." msgstr "A webhook was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the webhook ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the webhook ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the webhook ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the webhook ID." msgid ":attr:`~AuditLogDiff.type` (always set to ``1`` if so)" msgstr ":attr:`~AuditLogDiff.type` (always set to ``1`` if so)" @@ -974,8 +974,8 @@ msgstr "A webhook was deleted." msgid "An emoji was created." msgstr "An emoji was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." msgid "An emoji was updated. This triggers when the name has changed." msgstr "An emoji was updated. This triggers when the name has changed." @@ -983,14 +983,14 @@ msgstr "An emoji was updated. This triggers when the name has changed." msgid "An emoji was deleted." msgstr "An emoji was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the emoji ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the emoji ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the emoji ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the emoji ID." msgid "A message was deleted by a moderator. Note that this only triggers if the message was deleted by someone other than the author." msgstr "A message was deleted by a moderator. Note that this only triggers if the message was deleted by someone other than the author." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message deleted." msgid "``count``: An integer specifying how many messages were deleted." msgstr "``count``: An integer specifying how many messages were deleted." @@ -1001,14 +1001,14 @@ msgstr "``channel``: A :class:`TextChannel` or :class:`Object` with the channel msgid "Messages were bulk deleted by a moderator." msgstr "Messages were bulk deleted by a moderator." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." msgid "A message was pinned in a channel." msgstr "A message was pinned in a channel." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message pinned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message pinned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message pinned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message pinned." msgid "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was pinned." msgstr "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was pinned." @@ -1019,8 +1019,8 @@ msgstr "``message_id``: the ID of the message which was pinned." msgid "A message was unpinned in a channel." msgstr "A message was unpinned in a channel." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message unpinned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message unpinned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message unpinned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message unpinned." msgid "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was unpinned." msgstr "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was unpinned." @@ -1031,26 +1031,26 @@ msgstr "``message_id``: the ID of the message which was unpinned." msgid "A guild integration was created." msgstr "A guild integration was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was created." msgid "A guild integration was updated." msgstr "A guild integration was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was updated." msgid "A guild integration was deleted." msgstr "A guild integration was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was deleted." msgid "A stage instance was started." msgstr "A stage instance was started." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." msgid ":attr:`~AuditLogDiff.privacy_level`" msgstr ":attr:`~AuditLogDiff.privacy_level`" @@ -1058,8 +1058,8 @@ msgstr ":attr:`~AuditLogDiff.privacy_level`" msgid "A stage instance was updated." msgstr "A stage instance was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." msgid "A stage instance was ended." msgstr "A stage instance was ended." @@ -1067,8 +1067,8 @@ msgstr "A stage instance was ended." msgid "A sticker was created." msgstr "A sticker was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." msgid ":attr:`~AuditLogDiff.emoji`" msgstr ":attr:`~AuditLogDiff.emoji`" @@ -1091,8 +1091,8 @@ msgstr "A sticker was deleted." msgid "A scheduled event was created." msgstr "A scheduled event was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." msgid ":attr:`~discord.ScheduledEvent.location`" msgstr ":attr:`~discord.ScheduledEvent.location`" @@ -1115,8 +1115,8 @@ msgstr "A scheduled event was deleted." msgid "A thread was created." msgstr "A thread was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." msgid ":attr:`~AuditLogDiff.archived`" msgstr ":attr:`~AuditLogDiff.archived`" @@ -1133,20 +1133,20 @@ msgstr ":attr:`~AuditLogDiff.invitable`" msgid "A thread was updated." msgstr "A thread was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." msgid "A thread was deleted." msgstr "A thread was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." msgid "An application command's permissions were updated." msgstr "An application command's permissions were updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with the ID of the command that had it's permissions edited." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with the ID of the command that had it's permissions edited." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with the ID of the command that had it's permissions edited." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with the ID of the command that had it's permissions edited." msgid ":attr:`~AuditLogDiff.command_id`" msgstr ":attr:`~AuditLogDiff.command_id`" @@ -1199,8 +1199,8 @@ msgstr "The creator monetization terms were accepted." msgid "A voice channel status was updated." msgstr "A voice channel status was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." msgid ":attr:`~AuditLogDiff.status`" msgstr ":attr:`~AuditLogDiff.status`" diff --git a/docs/locales/pt_BR/LC_MESSAGES/api/enums.po b/docs/locales/pt_BR/LC_MESSAGES/api/enums.po index bc214e5db0..cb033dc5c4 100644 --- a/docs/locales/pt_BR/LC_MESSAGES/api/enums.po +++ b/docs/locales/pt_BR/LC_MESSAGES/api/enums.po @@ -656,8 +656,8 @@ msgstr "Changing the guild moderation settings" msgid "Changing things related to the guild widget" msgstr "Changing things related to the guild widget" -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Guild`." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Guild`." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Guild`." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Guild`." msgid "Possible attributes for :class:`AuditLogDiff`:" msgstr "Possible attributes for :class:`AuditLogDiff`:" @@ -704,8 +704,8 @@ msgstr ":attr:`~AuditLogDiff.vanity_url_code`" msgid "A new channel was created." msgstr "A new channel was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." msgid "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after`." msgstr "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after`." @@ -725,8 +725,8 @@ msgstr "The channel name or topic was changed" msgid "The channel bitrate was changed" msgstr "The channel bitrate was changed" -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." msgid "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after` or :attr:`~AuditLogEntry.before`." msgstr "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after` or :attr:`~AuditLogEntry.before`." @@ -752,8 +752,8 @@ msgstr ":attr:`~AuditLogDiff.default_auto_archive_duration`" msgid "A channel was deleted." msgstr "A channel was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with an ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with an ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with an ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with an ID." msgid "A more filled out object can be found by using the :attr:`~AuditLogEntry.before` object." msgstr "A more filled out object can be found by using the :attr:`~AuditLogEntry.before` object." @@ -776,8 +776,8 @@ msgstr ":attr:`~AuditLogDiff.id`" msgid "A channel permission overwrite was changed, this is typically when the permission values change." msgstr "A channel permission overwrite was changed, this is typically when the permission values change." -msgid "See :attr:`overwrite_create` for more information on how the :attr:`~AuditLogEntry.target` and :attr:`~AuditLogEntry.extra` fields are set." -msgstr "See :attr:`overwrite_create` for more information on how the :attr:`~AuditLogEntry.target` and :attr:`~AuditLogEntry.extra` fields are set." +msgid "See :attr:`overwrite_create` for more information on how the :func:`~AuditLogEntry.get_target` and :attr:`~AuditLogEntry.extra` fields are set." +msgstr "See :attr:`overwrite_create` for more information on how the :func:`~AuditLogEntry.get_target` and :attr:`~AuditLogEntry.extra` fields are set." msgid "A channel permission overwrite was deleted." msgstr "A channel permission overwrite was deleted." @@ -785,8 +785,8 @@ msgstr "A channel permission overwrite was deleted." msgid "A member was kicked." msgstr "A member was kicked." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got kicked." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got kicked." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got kicked." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got kicked." msgid "When this is the action, :attr:`~AuditLogEntry.changes` is empty." msgstr "When this is the action, :attr:`~AuditLogEntry.changes` is empty." @@ -794,8 +794,8 @@ msgstr "When this is the action, :attr:`~AuditLogEntry.changes` is empty." msgid "A member prune was triggered." msgstr "A member prune was triggered." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is set to ``None``." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is set to ``None``." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is set to ``None``." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is set to ``None``." msgid "When this is the action, the type of :attr:`~AuditLogEntry.extra` is set to an unspecified proxy object with two attributes:" msgstr "When this is the action, the type of :attr:`~AuditLogEntry.extra` is set to an unspecified proxy object with two attributes:" @@ -809,14 +809,14 @@ msgstr "``members_removed``: An integer specifying how many members were removed msgid "A member was banned." msgstr "A member was banned." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got banned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got banned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got banned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got banned." msgid "A member was unbanned." msgstr "A member was unbanned." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got unbanned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got unbanned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got unbanned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got unbanned." msgid "A member has updated. This triggers in the following situations:" msgstr "A member has updated. This triggers in the following situations:" @@ -827,8 +827,8 @@ msgstr "A nickname was changed" msgid "They were server muted or deafened (or it was undone)" msgstr "They were server muted or deafened (or it was undone)" -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got updated." msgid ":attr:`~AuditLogDiff.nick`" msgstr ":attr:`~AuditLogDiff.nick`" @@ -842,8 +842,8 @@ msgstr ":attr:`~AuditLogDiff.deaf`" msgid "A member's role has been updated. This triggers when a member either gains a role or loses a role." msgstr "A member's role has been updated. This triggers when a member either gains a role or loses a role." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got the role." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got the role." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got the role." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got the role." msgid ":attr:`~AuditLogDiff.roles`" msgstr ":attr:`~AuditLogDiff.roles`" @@ -869,14 +869,14 @@ msgstr "``count``: An integer specifying how many members were disconnected." msgid "A bot was added to the guild." msgstr "A bot was added to the guild." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` which was added to the guild." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` which was added to the guild." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` which was added to the guild." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` which was added to the guild." msgid "A new role was created." msgstr "A new role was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Role` or a :class:`Object` with the ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Role` or a :class:`Object` with the ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Role` or a :class:`Object` with the ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Role` or a :class:`Object` with the ID." msgid ":attr:`~AuditLogDiff.colour`" msgstr ":attr:`~AuditLogDiff.colour`" @@ -911,8 +911,8 @@ msgstr "A role was deleted." msgid "An invite was created." msgstr "An invite was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was created." msgid ":attr:`~AuditLogDiff.max_age`" msgstr ":attr:`~AuditLogDiff.max_age`" @@ -938,20 +938,20 @@ msgstr ":attr:`~AuditLogDiff.max_uses`" msgid "An invite was updated." msgstr "An invite was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was updated." msgid "An invite was deleted." msgstr "An invite was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was deleted." msgid "A webhook was created." msgstr "A webhook was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the webhook ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the webhook ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the webhook ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the webhook ID." msgid ":attr:`~AuditLogDiff.type` (always set to ``1`` if so)" msgstr ":attr:`~AuditLogDiff.type` (always set to ``1`` if so)" @@ -974,8 +974,8 @@ msgstr "A webhook was deleted." msgid "An emoji was created." msgstr "An emoji was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." msgid "An emoji was updated. This triggers when the name has changed." msgstr "An emoji was updated. This triggers when the name has changed." @@ -983,14 +983,14 @@ msgstr "An emoji was updated. This triggers when the name has changed." msgid "An emoji was deleted." msgstr "An emoji was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the emoji ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the emoji ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the emoji ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the emoji ID." msgid "A message was deleted by a moderator. Note that this only triggers if the message was deleted by someone other than the author." msgstr "A message was deleted by a moderator. Note that this only triggers if the message was deleted by someone other than the author." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message deleted." msgid "``count``: An integer specifying how many messages were deleted." msgstr "``count``: An integer specifying how many messages were deleted." @@ -1001,14 +1001,14 @@ msgstr "``channel``: A :class:`TextChannel` or :class:`Object` with the channel msgid "Messages were bulk deleted by a moderator." msgstr "Messages were bulk deleted by a moderator." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." msgid "A message was pinned in a channel." msgstr "A message was pinned in a channel." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message pinned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message pinned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message pinned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message pinned." msgid "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was pinned." msgstr "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was pinned." @@ -1019,8 +1019,8 @@ msgstr "``message_id``: the ID of the message which was pinned." msgid "A message was unpinned in a channel." msgstr "A message was unpinned in a channel." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message unpinned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message unpinned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message unpinned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message unpinned." msgid "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was unpinned." msgstr "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was unpinned." @@ -1031,26 +1031,26 @@ msgstr "``message_id``: the ID of the message which was unpinned." msgid "A guild integration was created." msgstr "A guild integration was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was created." msgid "A guild integration was updated." msgstr "A guild integration was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was updated." msgid "A guild integration was deleted." msgstr "A guild integration was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was deleted." msgid "A stage instance was started." msgstr "A stage instance was started." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." msgid ":attr:`~AuditLogDiff.privacy_level`" msgstr ":attr:`~AuditLogDiff.privacy_level`" @@ -1058,8 +1058,8 @@ msgstr ":attr:`~AuditLogDiff.privacy_level`" msgid "A stage instance was updated." msgstr "A stage instance was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." msgid "A stage instance was ended." msgstr "A stage instance was ended." @@ -1067,8 +1067,8 @@ msgstr "A stage instance was ended." msgid "A sticker was created." msgstr "A sticker was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." msgid ":attr:`~AuditLogDiff.emoji`" msgstr ":attr:`~AuditLogDiff.emoji`" @@ -1091,8 +1091,8 @@ msgstr "A sticker was deleted." msgid "A scheduled event was created." msgstr "A scheduled event was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." msgid ":attr:`~discord.ScheduledEvent.location`" msgstr ":attr:`~discord.ScheduledEvent.location`" @@ -1115,8 +1115,8 @@ msgstr "A scheduled event was deleted." msgid "A thread was created." msgstr "A thread was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." msgid ":attr:`~AuditLogDiff.archived`" msgstr ":attr:`~AuditLogDiff.archived`" @@ -1133,20 +1133,20 @@ msgstr ":attr:`~AuditLogDiff.invitable`" msgid "A thread was updated." msgstr "A thread was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." msgid "A thread was deleted." msgstr "A thread was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." msgid "An application command's permissions were updated." msgstr "An application command's permissions were updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with the ID of the command that had it's permissions edited." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with the ID of the command that had it's permissions edited." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with the ID of the command that had it's permissions edited." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with the ID of the command that had it's permissions edited." msgid ":attr:`~AuditLogDiff.command_id`" msgstr ":attr:`~AuditLogDiff.command_id`" @@ -1199,8 +1199,8 @@ msgstr "The creator monetization terms were accepted." msgid "A voice channel status was updated." msgstr "A voice channel status was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." msgid ":attr:`~AuditLogDiff.status`" msgstr ":attr:`~AuditLogDiff.status`" diff --git a/docs/locales/ru/LC_MESSAGES/api/enums.po b/docs/locales/ru/LC_MESSAGES/api/enums.po index 715c0585fa..bb17b2b170 100644 --- a/docs/locales/ru/LC_MESSAGES/api/enums.po +++ b/docs/locales/ru/LC_MESSAGES/api/enums.po @@ -656,8 +656,8 @@ msgstr "Changing the guild moderation settings" msgid "Changing things related to the guild widget" msgstr "Changing things related to the guild widget" -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Guild`." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Guild`." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Guild`." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Guild`." msgid "Possible attributes for :class:`AuditLogDiff`:" msgstr "Possible attributes for :class:`AuditLogDiff`:" @@ -704,8 +704,8 @@ msgstr ":attr:`~AuditLogDiff.vanity_url_code`" msgid "A new channel was created." msgstr "A new channel was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." msgid "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after`." msgstr "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after`." @@ -725,8 +725,8 @@ msgstr "The channel name or topic was changed" msgid "The channel bitrate was changed" msgstr "The channel bitrate was changed" -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." msgid "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after` or :attr:`~AuditLogEntry.before`." msgstr "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after` or :attr:`~AuditLogEntry.before`." @@ -752,8 +752,8 @@ msgstr ":attr:`~AuditLogDiff.default_auto_archive_duration`" msgid "A channel was deleted." msgstr "A channel was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with an ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with an ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with an ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with an ID." msgid "A more filled out object can be found by using the :attr:`~AuditLogEntry.before` object." msgstr "A more filled out object can be found by using the :attr:`~AuditLogEntry.before` object." @@ -776,8 +776,8 @@ msgstr ":attr:`~AuditLogDiff.id`" msgid "A channel permission overwrite was changed, this is typically when the permission values change." msgstr "A channel permission overwrite was changed, this is typically when the permission values change." -msgid "See :attr:`overwrite_create` for more information on how the :attr:`~AuditLogEntry.target` and :attr:`~AuditLogEntry.extra` fields are set." -msgstr "See :attr:`overwrite_create` for more information on how the :attr:`~AuditLogEntry.target` and :attr:`~AuditLogEntry.extra` fields are set." +msgid "See :attr:`overwrite_create` for more information on how the :func:`~AuditLogEntry.get_target` and :attr:`~AuditLogEntry.extra` fields are set." +msgstr "See :attr:`overwrite_create` for more information on how the :func:`~AuditLogEntry.get_target` and :attr:`~AuditLogEntry.extra` fields are set." msgid "A channel permission overwrite was deleted." msgstr "A channel permission overwrite was deleted." @@ -785,8 +785,8 @@ msgstr "A channel permission overwrite was deleted." msgid "A member was kicked." msgstr "A member was kicked." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got kicked." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got kicked." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got kicked." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got kicked." msgid "When this is the action, :attr:`~AuditLogEntry.changes` is empty." msgstr "When this is the action, :attr:`~AuditLogEntry.changes` is empty." @@ -794,8 +794,8 @@ msgstr "When this is the action, :attr:`~AuditLogEntry.changes` is empty." msgid "A member prune was triggered." msgstr "A member prune was triggered." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is set to ``None``." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is set to ``None``." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is set to ``None``." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is set to ``None``." msgid "When this is the action, the type of :attr:`~AuditLogEntry.extra` is set to an unspecified proxy object with two attributes:" msgstr "When this is the action, the type of :attr:`~AuditLogEntry.extra` is set to an unspecified proxy object with two attributes:" @@ -809,14 +809,14 @@ msgstr "``members_removed``: An integer specifying how many members were removed msgid "A member was banned." msgstr "A member was banned." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got banned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got banned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got banned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got banned." msgid "A member was unbanned." msgstr "A member was unbanned." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got unbanned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got unbanned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got unbanned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got unbanned." msgid "A member has updated. This triggers in the following situations:" msgstr "A member has updated. This triggers in the following situations:" @@ -827,8 +827,8 @@ msgstr "A nickname was changed" msgid "They were server muted or deafened (or it was undone)" msgstr "They were server muted or deafened (or it was undone)" -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got updated." msgid ":attr:`~AuditLogDiff.nick`" msgstr ":attr:`~AuditLogDiff.nick`" @@ -842,8 +842,8 @@ msgstr ":attr:`~AuditLogDiff.deaf`" msgid "A member's role has been updated. This triggers when a member either gains a role or loses a role." msgstr "A member's role has been updated. This triggers when a member either gains a role or loses a role." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got the role." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got the role." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got the role." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got the role." msgid ":attr:`~AuditLogDiff.roles`" msgstr ":attr:`~AuditLogDiff.roles`" @@ -869,14 +869,14 @@ msgstr "``count``: An integer specifying how many members were disconnected." msgid "A bot was added to the guild." msgstr "A bot was added to the guild." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` which was added to the guild." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` which was added to the guild." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` which was added to the guild." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` which was added to the guild." msgid "A new role was created." msgstr "A new role was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Role` or a :class:`Object` with the ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Role` or a :class:`Object` with the ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Role` or a :class:`Object` with the ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Role` or a :class:`Object` with the ID." msgid ":attr:`~AuditLogDiff.colour`" msgstr ":attr:`~AuditLogDiff.colour`" @@ -911,8 +911,8 @@ msgstr "A role was deleted." msgid "An invite was created." msgstr "An invite was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was created." msgid ":attr:`~AuditLogDiff.max_age`" msgstr ":attr:`~AuditLogDiff.max_age`" @@ -938,20 +938,20 @@ msgstr ":attr:`~AuditLogDiff.max_uses`" msgid "An invite was updated." msgstr "An invite was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was updated." msgid "An invite was deleted." msgstr "An invite was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was deleted." msgid "A webhook was created." msgstr "A webhook was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the webhook ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the webhook ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the webhook ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the webhook ID." msgid ":attr:`~AuditLogDiff.type` (always set to ``1`` if so)" msgstr ":attr:`~AuditLogDiff.type` (always set to ``1`` if so)" @@ -974,8 +974,8 @@ msgstr "A webhook was deleted." msgid "An emoji was created." msgstr "An emoji was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." msgid "An emoji was updated. This triggers when the name has changed." msgstr "An emoji was updated. This triggers when the name has changed." @@ -983,14 +983,14 @@ msgstr "An emoji was updated. This triggers when the name has changed." msgid "An emoji was deleted." msgstr "An emoji was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the emoji ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the emoji ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the emoji ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the emoji ID." msgid "A message was deleted by a moderator. Note that this only triggers if the message was deleted by someone other than the author." msgstr "A message was deleted by a moderator. Note that this only triggers if the message was deleted by someone other than the author." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message deleted." msgid "``count``: An integer specifying how many messages were deleted." msgstr "``count``: An integer specifying how many messages were deleted." @@ -1001,14 +1001,14 @@ msgstr "``channel``: A :class:`TextChannel` or :class:`Object` with the channel msgid "Messages were bulk deleted by a moderator." msgstr "Messages were bulk deleted by a moderator." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." msgid "A message was pinned in a channel." msgstr "A message was pinned in a channel." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message pinned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message pinned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message pinned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message pinned." msgid "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was pinned." msgstr "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was pinned." @@ -1019,8 +1019,8 @@ msgstr "``message_id``: the ID of the message which was pinned." msgid "A message was unpinned in a channel." msgstr "A message was unpinned in a channel." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message unpinned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message unpinned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message unpinned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message unpinned." msgid "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was unpinned." msgstr "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was unpinned." @@ -1031,26 +1031,26 @@ msgstr "``message_id``: the ID of the message which was unpinned." msgid "A guild integration was created." msgstr "A guild integration was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was created." msgid "A guild integration was updated." msgstr "A guild integration was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was updated." msgid "A guild integration was deleted." msgstr "A guild integration was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was deleted." msgid "A stage instance was started." msgstr "A stage instance was started." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." msgid ":attr:`~AuditLogDiff.privacy_level`" msgstr ":attr:`~AuditLogDiff.privacy_level`" @@ -1058,8 +1058,8 @@ msgstr ":attr:`~AuditLogDiff.privacy_level`" msgid "A stage instance was updated." msgstr "A stage instance was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." msgid "A stage instance was ended." msgstr "A stage instance was ended." @@ -1067,8 +1067,8 @@ msgstr "A stage instance was ended." msgid "A sticker was created." msgstr "A sticker was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." msgid ":attr:`~AuditLogDiff.emoji`" msgstr ":attr:`~AuditLogDiff.emoji`" @@ -1091,8 +1091,8 @@ msgstr "A sticker was deleted." msgid "A scheduled event was created." msgstr "A scheduled event was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." msgid ":attr:`~discord.ScheduledEvent.location`" msgstr ":attr:`~discord.ScheduledEvent.location`" @@ -1115,8 +1115,8 @@ msgstr "A scheduled event was deleted." msgid "A thread was created." msgstr "A thread was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." msgid ":attr:`~AuditLogDiff.archived`" msgstr ":attr:`~AuditLogDiff.archived`" @@ -1133,20 +1133,20 @@ msgstr ":attr:`~AuditLogDiff.invitable`" msgid "A thread was updated." msgstr "A thread was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." msgid "A thread was deleted." msgstr "A thread was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." msgid "An application command's permissions were updated." msgstr "An application command's permissions were updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with the ID of the command that had it's permissions edited." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with the ID of the command that had it's permissions edited." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with the ID of the command that had it's permissions edited." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with the ID of the command that had it's permissions edited." msgid ":attr:`~AuditLogDiff.command_id`" msgstr ":attr:`~AuditLogDiff.command_id`" @@ -1199,8 +1199,8 @@ msgstr "The creator monetization terms were accepted." msgid "A voice channel status was updated." msgstr "A voice channel status was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." msgid ":attr:`~AuditLogDiff.status`" msgstr ":attr:`~AuditLogDiff.status`" diff --git a/docs/locales/zh_CN/LC_MESSAGES/api/enums.po b/docs/locales/zh_CN/LC_MESSAGES/api/enums.po index e4f5ebba42..792b61cbf2 100644 --- a/docs/locales/zh_CN/LC_MESSAGES/api/enums.po +++ b/docs/locales/zh_CN/LC_MESSAGES/api/enums.po @@ -656,8 +656,8 @@ msgstr "Changing the guild moderation settings" msgid "Changing things related to the guild widget" msgstr "Changing things related to the guild widget" -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Guild`." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Guild`." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Guild`." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Guild`." msgid "Possible attributes for :class:`AuditLogDiff`:" msgstr "Possible attributes for :class:`AuditLogDiff`:" @@ -704,8 +704,8 @@ msgstr ":attr:`~AuditLogDiff.vanity_url_code`" msgid "A new channel was created." msgstr "A new channel was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is either a :class:`abc.GuildChannel` or :class:`Object` with an ID." msgid "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after`." msgstr "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after`." @@ -725,8 +725,8 @@ msgstr "The channel name or topic was changed" msgid "The channel bitrate was changed" msgstr "The channel bitrate was changed" -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`abc.GuildChannel` or :class:`Object` with an ID." msgid "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after` or :attr:`~AuditLogEntry.before`." msgstr "A more filled out object in the :class:`Object` case can be found by using :attr:`~AuditLogEntry.after` or :attr:`~AuditLogEntry.before`." @@ -752,8 +752,8 @@ msgstr ":attr:`~AuditLogDiff.default_auto_archive_duration`" msgid "A channel was deleted." msgstr "A channel was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with an ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with an ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with an ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with an ID." msgid "A more filled out object can be found by using the :attr:`~AuditLogEntry.before` object." msgstr "A more filled out object can be found by using the :attr:`~AuditLogEntry.before` object." @@ -776,8 +776,8 @@ msgstr ":attr:`~AuditLogDiff.id`" msgid "A channel permission overwrite was changed, this is typically when the permission values change." msgstr "A channel permission overwrite was changed, this is typically when the permission values change." -msgid "See :attr:`overwrite_create` for more information on how the :attr:`~AuditLogEntry.target` and :attr:`~AuditLogEntry.extra` fields are set." -msgstr "See :attr:`overwrite_create` for more information on how the :attr:`~AuditLogEntry.target` and :attr:`~AuditLogEntry.extra` fields are set." +msgid "See :attr:`overwrite_create` for more information on how the :func:`~AuditLogEntry.get_target` and :attr:`~AuditLogEntry.extra` fields are set." +msgstr "See :attr:`overwrite_create` for more information on how the :func:`~AuditLogEntry.get_target` and :attr:`~AuditLogEntry.extra` fields are set." msgid "A channel permission overwrite was deleted." msgstr "A channel permission overwrite was deleted." @@ -785,8 +785,8 @@ msgstr "A channel permission overwrite was deleted." msgid "A member was kicked." msgstr "A member was kicked." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got kicked." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got kicked." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got kicked." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got kicked." msgid "When this is the action, :attr:`~AuditLogEntry.changes` is empty." msgstr "When this is the action, :attr:`~AuditLogEntry.changes` is empty." @@ -794,8 +794,8 @@ msgstr "When this is the action, :attr:`~AuditLogEntry.changes` is empty." msgid "A member prune was triggered." msgstr "A member prune was triggered." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is set to ``None``." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is set to ``None``." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is set to ``None``." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is set to ``None``." msgid "When this is the action, the type of :attr:`~AuditLogEntry.extra` is set to an unspecified proxy object with two attributes:" msgstr "When this is the action, the type of :attr:`~AuditLogEntry.extra` is set to an unspecified proxy object with two attributes:" @@ -809,14 +809,14 @@ msgstr "``members_removed``: An integer specifying how many members were removed msgid "A member was banned." msgstr "A member was banned." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got banned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got banned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got banned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got banned." msgid "A member was unbanned." msgstr "A member was unbanned." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got unbanned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`User` who got unbanned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got unbanned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`User` who got unbanned." msgid "A member has updated. This triggers in the following situations:" msgstr "A member has updated. This triggers in the following situations:" @@ -827,8 +827,8 @@ msgstr "A nickname was changed" msgid "They were server muted or deafened (or it was undone)" msgstr "They were server muted or deafened (or it was undone)" -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got updated." msgid ":attr:`~AuditLogDiff.nick`" msgstr ":attr:`~AuditLogDiff.nick`" @@ -842,8 +842,8 @@ msgstr ":attr:`~AuditLogDiff.deaf`" msgid "A member's role has been updated. This triggers when a member either gains a role or loses a role." msgstr "A member's role has been updated. This triggers when a member either gains a role or loses a role." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got the role." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who got the role." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got the role." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who got the role." msgid ":attr:`~AuditLogDiff.roles`" msgstr ":attr:`~AuditLogDiff.roles`" @@ -869,14 +869,14 @@ msgstr "``count``: An integer specifying how many members were disconnected." msgid "A bot was added to the guild." msgstr "A bot was added to the guild." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` which was added to the guild." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` which was added to the guild." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` which was added to the guild." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` which was added to the guild." msgid "A new role was created." msgstr "A new role was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Role` or a :class:`Object` with the ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Role` or a :class:`Object` with the ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Role` or a :class:`Object` with the ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Role` or a :class:`Object` with the ID." msgid ":attr:`~AuditLogDiff.colour`" msgstr ":attr:`~AuditLogDiff.colour`" @@ -911,8 +911,8 @@ msgstr "A role was deleted." msgid "An invite was created." msgstr "An invite was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was created." msgid ":attr:`~AuditLogDiff.max_age`" msgstr ":attr:`~AuditLogDiff.max_age`" @@ -938,20 +938,20 @@ msgstr ":attr:`~AuditLogDiff.max_uses`" msgid "An invite was updated." msgstr "An invite was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was updated." msgid "An invite was deleted." msgstr "An invite was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Invite` that was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Invite` that was deleted." msgid "A webhook was created." msgstr "A webhook was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the webhook ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the webhook ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the webhook ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the webhook ID." msgid ":attr:`~AuditLogDiff.type` (always set to ``1`` if so)" msgstr ":attr:`~AuditLogDiff.type` (always set to ``1`` if so)" @@ -974,8 +974,8 @@ msgstr "A webhook was deleted." msgid "An emoji was created." msgstr "An emoji was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildEmoji` or :class:`Object` with the emoji ID." msgid "An emoji was updated. This triggers when the name has changed." msgstr "An emoji was updated. This triggers when the name has changed." @@ -983,14 +983,14 @@ msgstr "An emoji was updated. This triggers when the name has changed." msgid "An emoji was deleted." msgstr "An emoji was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the emoji ID." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the emoji ID." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the emoji ID." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the emoji ID." msgid "A message was deleted by a moderator. Note that this only triggers if the message was deleted by someone other than the author." msgstr "A message was deleted by a moderator. Note that this only triggers if the message was deleted by someone other than the author." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message deleted." msgid "``count``: An integer specifying how many messages were deleted." msgstr "``count``: An integer specifying how many messages were deleted." @@ -1001,14 +1001,14 @@ msgstr "``channel``: A :class:`TextChannel` or :class:`Object` with the channel msgid "Messages were bulk deleted by a moderator." msgstr "Messages were bulk deleted by a moderator." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged." msgid "A message was pinned in a channel." msgstr "A message was pinned in a channel." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message pinned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message pinned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message pinned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message pinned." msgid "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was pinned." msgstr "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was pinned." @@ -1019,8 +1019,8 @@ msgstr "``message_id``: the ID of the message which was pinned." msgid "A message was unpinned in a channel." msgstr "A message was unpinned in a channel." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message unpinned." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Member` or :class:`User` who had their message unpinned." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message unpinned." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Member` or :class:`User` who had their message unpinned." msgid "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was unpinned." msgstr "``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was unpinned." @@ -1031,26 +1031,26 @@ msgstr "``message_id``: the ID of the message which was unpinned." msgid "A guild integration was created." msgstr "A guild integration was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was created." msgid "A guild integration was updated." msgstr "A guild integration was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was updated." msgid "A guild integration was deleted." msgstr "A guild integration was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Object` with the integration ID of the integration which was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Object` with the integration ID of the integration which was deleted." msgid "A stage instance was started." msgstr "A stage instance was started." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was created." msgid ":attr:`~AuditLogDiff.privacy_level`" msgstr ":attr:`~AuditLogDiff.privacy_level`" @@ -1058,8 +1058,8 @@ msgstr ":attr:`~AuditLogDiff.privacy_level`" msgid "A stage instance was updated." msgstr "A stage instance was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`StageInstance` or :class:`Object` with the ID of the stage instance which was updated." msgid "A stage instance was ended." msgstr "A stage instance was ended." @@ -1067,8 +1067,8 @@ msgstr "A stage instance was ended." msgid "A sticker was created." msgstr "A sticker was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`GuildSticker` or :class:`Object` with the ID of the sticker which was updated." msgid ":attr:`~AuditLogDiff.emoji`" msgstr ":attr:`~AuditLogDiff.emoji`" @@ -1091,8 +1091,8 @@ msgstr "A sticker was deleted." msgid "A scheduled event was created." msgstr "A scheduled event was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`ScheduledEvent` or :class:`Object` with the ID of the thread which was deleted." msgid ":attr:`~discord.ScheduledEvent.location`" msgstr ":attr:`~discord.ScheduledEvent.location`" @@ -1115,8 +1115,8 @@ msgstr "A scheduled event was deleted." msgid "A thread was created." msgstr "A thread was created." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was created." msgid ":attr:`~AuditLogDiff.archived`" msgstr ":attr:`~AuditLogDiff.archived`" @@ -1133,20 +1133,20 @@ msgstr ":attr:`~AuditLogDiff.invitable`" msgid "A thread was updated." msgstr "A thread was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was updated." msgid "A thread was deleted." msgstr "A thread was deleted." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`Thread` or :class:`Object` with the ID of the thread which was deleted." msgid "An application command's permissions were updated." msgstr "An application command's permissions were updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with the ID of the command that had it's permissions edited." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is an :class:`Object` with the ID of the command that had it's permissions edited." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with the ID of the command that had it's permissions edited." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is an :class:`Object` with the ID of the command that had it's permissions edited." msgid ":attr:`~AuditLogDiff.command_id`" msgstr ":attr:`~AuditLogDiff.command_id`" @@ -1199,8 +1199,8 @@ msgstr "The creator monetization terms were accepted." msgid "A voice channel status was updated." msgstr "A voice channel status was updated." -msgid "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." -msgstr "When this is the action, the type of :attr:`~AuditLogEntry.target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." +msgid "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." +msgstr "When this is the action, the type of :func:`~AuditLogEntry.get_target` is the :class:`VoiceChannel` or :class:`Object` with the ID of the voice channel which was updated." msgid ":attr:`~AuditLogDiff.status`" msgstr ":attr:`~AuditLogDiff.status`"