From 34a23ebc6abad1810cfaba66233b86b7fdd55631 Mon Sep 17 00:00:00 2001 From: Om <92863779+Om1609@users.noreply.github.com> Date: Sun, 26 Feb 2023 20:29:03 +0530 Subject: [PATCH 01/67] fix: UnboundLocalError (#1928) * fix UnboundLocalError Signed-off-by: Om <92863779+Om1609@users.noreply.github.com> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Check if command is bridge command every time Signed-off-by: Om <92863779+Om1609@users.noreply.github.com> --------- Signed-off-by: Om <92863779+Om1609@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: BobDotCom <71356958+BobDotCom@users.noreply.github.com> --- discord/ext/bridge/bot.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/discord/ext/bridge/bot.py b/discord/ext/bridge/bot.py index c9baecb034..1d9a36f37d 100644 --- a/discord/ext/bridge/bot.py +++ b/discord/ext/bridge/bot.py @@ -120,7 +120,7 @@ def decorator(func) -> BridgeCommandGroup: async def invoke(self, ctx: ExtContext | BridgeExtContext): if ctx.command is not None: self.dispatch("command", ctx) - if br_cmd := isinstance(ctx.command, BridgeExtCommand): + if isinstance(ctx.command, BridgeExtCommand): self.dispatch("bridge_command", ctx) try: if await self.can_run(ctx, call_once=True): @@ -131,12 +131,12 @@ async def invoke(self, ctx: ExtContext | BridgeExtContext): await ctx.command.dispatch_error(ctx, exc) else: self.dispatch("command_completion", ctx) - if br_cmd: + if isinstance(ctx.command, BridgeExtCommand): self.dispatch("bridge_command_completion", ctx) elif ctx.invoked_with: exc = errors.CommandNotFound(f'Command "{ctx.invoked_with}" is not found') self.dispatch("command_error", ctx, exc) - if br_cmd: + if isinstance(ctx.command, BridgeExtCommand): self.dispatch("bridge_command_error", ctx, exc) async def invoke_application_command( From 2e09718255c16e7226105e21c4660e69cfec5a7d Mon Sep 17 00:00:00 2001 From: UK <41271523+NeloBlivion@users.noreply.github.com> Date: Sun, 26 Feb 2023 15:16:59 +0000 Subject: [PATCH 02/67] fix: AttributeErrors from event handler move (#1946) Fix event issues from #1907 --- discord/cog.py | 2 +- discord/ext/commands/bot.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/discord/cog.py b/discord/cog.py index 9e3d8733a4..6f6a573869 100644 --- a/discord/cog.py +++ b/discord/cog.py @@ -735,7 +735,7 @@ def _remove_module_references(self, name: str) -> None: self.remove_application_command(cmd) # remove all the listeners from the module - for event_list in self.extra_events.copy().values(): + for event_list in self._event_handlers.copy().values(): remove = [ index for index, event in enumerate(event_list) diff --git a/discord/ext/commands/bot.py b/discord/ext/commands/bot.py index ae8a48c283..4f1753e49a 100644 --- a/discord/ext/commands/bot.py +++ b/discord/ext/commands/bot.py @@ -159,7 +159,7 @@ async def on_command_error( This only fires if you do not specify any listeners for command error. """ - if self.extra_events.get("on_command_error", None): + if self._event_handlers.get("on_command_error", None): return command = context.command From 13dbcddae889377e366af2e68569ec55b82bb5a8 Mon Sep 17 00:00:00 2001 From: Om <92863779+Om1609@users.noreply.github.com> Date: Sun, 26 Feb 2023 21:56:17 +0530 Subject: [PATCH 03/67] feat: add `once` decorator to `discord.Client` (#1940) Signed-off-by: Om <92863779+Om1609@users.noreply.github.com> Co-authored-by: BobDotCom <71356958+BobDotCom@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- CHANGELOG.md | 2 ++ discord/client.py | 58 +++++++++++++++++++++++++++++++++++++++ docs/api/clients.rst | 10 +++++-- docs/api/events.rst | 12 ++++++-- docs/ext/commands/api.rst | 5 +++- 5 files changed, 81 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97d1d56853..791df31a1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ These changes are available on the `master` branch, but have not yet been releas - Added new events `on_bridge_command`, `on_bridge_command_completion`, and `on_bridge_command_error`. ([#1916](https://github.com/Pycord-Development/pycord/pull/1916)) +- Added the `@client.once()` decorator, which serves as a one-time event listener. + ([#1940](https://github.com/Pycord-Development/pycord/pull/1940)) ### Fixed diff --git a/discord/client.py b/discord/client.py index b8b1057e67..07bba3bf41 100644 --- a/discord/client.py +++ b/discord/client.py @@ -1286,6 +1286,64 @@ async def on_ready(): _log.debug("%s has successfully been registered as an event", coro.__name__) return coro + def once( + self, name: str = MISSING, check: Callable[..., bool] | None = None + ) -> Coro: + """A decorator that registers an event to listen to only once. + + You can find more info about the events on the :ref:`documentation below `. + + The events must be a :ref:`coroutine `, if not, :exc:`TypeError` is raised. + + Parameters + ---------- + name: :class:`str` + The name of the event we want to listen to. This is passed to + :py:meth:`~discord.Client.wait_for`. Defaults to ``func.__name__``. + check: Optional[Callable[..., :class:`bool`]] + A predicate to check what to wait for. The arguments must meet the + parameters of the event being waited for. + + Raises + ------ + TypeError + The coroutine passed is not actually a coroutine. + + Example + ------- + + .. code-block:: python3 + + @client.once() + async def ready(): + print('Ready!') + """ + + def decorator(func: Coro) -> Coro: + if not asyncio.iscoroutinefunction(func): + raise TypeError("event registered must be a coroutine function") + + async def wrapped() -> None: + nonlocal name + nonlocal check + + name = func.__name__ if name is MISSING else name + + args = await self.wait_for(name, check=check) + + arg_len = func.__code__.co_argcount + if arg_len == 0 and args is None: + await func() + elif arg_len == 1: + await func(args) + else: + await func(*args) + + self.loop.create_task(wrapped()) + return func + + return decorator + async def change_presence( self, *, diff --git a/docs/api/clients.rst b/docs/api/clients.rst index 8bf10cff4f..aeae87cbcb 100644 --- a/docs/api/clients.rst +++ b/docs/api/clients.rst @@ -10,7 +10,7 @@ Bots .. autoclass:: Bot :members: :inherited-members: - :exclude-members: command, event, message_command, slash_command, user_command, listen + :exclude-members: command, event, message_command, slash_command, user_command, listen, once .. automethod:: Bot.command(**kwargs) :decorator: @@ -30,6 +30,9 @@ Bots .. automethod:: Bot.listen(name=None) :decorator: + .. automethod:: Bot.once(name=None, check=None) + :decorator: + .. attributetable:: AutoShardedBot .. autoclass:: AutoShardedBot :members: @@ -41,7 +44,7 @@ Clients .. attributetable:: Client .. autoclass:: Client :members: - :exclude-members: fetch_guilds, event + :exclude-members: fetch_guilds, event, once .. automethod:: Client.event() :decorator: @@ -49,6 +52,9 @@ Clients .. automethod:: Client.fetch_guilds :async-for: + .. automethod:: Client.once(name=None, check=None) + :decorator: + .. attributetable:: AutoShardedClient .. autoclass:: AutoShardedClient :members: diff --git a/docs/api/events.rst b/docs/api/events.rst index 10e2039c7d..4903ae8f92 100644 --- a/docs/api/events.rst +++ b/docs/api/events.rst @@ -7,10 +7,11 @@ Event Reference This section outlines the different types of events listened by :class:`Client`. -There are 3 ways to register an event, the first way is through the use of +There are 4 ways to register an event, the first way is through the use of :meth:`Client.event`. The second way is through subclassing :class:`Client` and -overriding the specific events. The third way is through the use of :meth:`Client.listen`, which can be used to assign multiple -event handlers instead of only one like in :meth:`Client.event`. For example: +overriding the specific events. The third way is through the use of :meth:`Client.listen`, +which can be used to assign multiple event handlers instead of only one like in :meth:`Client.event`. +The fourth way is through the use of :meth:`Client.once`, which serves as a one-time event listener. For example: .. code-block:: python :emphasize-lines: 17, 22 @@ -40,6 +41,11 @@ event handlers instead of only one like in :meth:`Client.event`. For example: async def on_message(message: discord.Message): print(f"Received {message.content}") + # Runs only for the 1st 'on_message' event. Can be useful for listening to 'on_ready' + @client.once() + async def message(message: discord.Message): + print(f"Received {message.content}") + If an event handler raises an exception, :func:`on_error` will be called to handle it, which defaults to print a traceback and ignoring the exception. diff --git a/docs/ext/commands/api.rst b/docs/ext/commands/api.rst index 355a8a1020..119a8de10c 100644 --- a/docs/ext/commands/api.rst +++ b/docs/ext/commands/api.rst @@ -23,7 +23,7 @@ Bot .. autoclass:: discord.ext.commands.Bot :members: :inherited-members: - :exclude-members: after_invoke, before_invoke, check, check_once, command, event, group, listen + :exclude-members: after_invoke, before_invoke, check, check_once, command, event, group, listen, once .. automethod:: Bot.after_invoke() :decorator: @@ -49,6 +49,9 @@ Bot .. automethod:: Bot.listen(name=None) :decorator: + .. automethod:: Bot.once(name=None, check=None) + :decorator: + AutoShardedBot ~~~~~~~~~~~~~~ From ba129e606bfe706866524743f27e2a8a0febd139 Mon Sep 17 00:00:00 2001 From: JustaSqu1d Date: Mon, 27 Feb 2023 19:16:10 -0800 Subject: [PATCH 04/67] chore(docs): add missing decorator in examples (#1950) --- docs/ext/commands/commands.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/ext/commands/commands.rst b/docs/ext/commands/commands.rst index 8465ee204e..793c3a64e4 100644 --- a/docs/ext/commands/commands.rst +++ b/docs/ext/commands/commands.rst @@ -899,6 +899,7 @@ If you want a more robust error system, you can derive from the exception and ra return True return commands.check(predicate) + @bot.command() @guild_only() async def test(ctx): await ctx.send('Hey this is not a DM! Nice.') From 88cc1878860f93a1b71397350c103fd4bf8f195e Mon Sep 17 00:00:00 2001 From: UK <41271523+NeloBlivion@users.noreply.github.com> Date: Tue, 28 Feb 2023 12:54:25 +0000 Subject: [PATCH 05/67] feat: Support for text in stage (#1936) --- CHANGELOG.md | 2 + discord/abc.py | 5 +- discord/channel.py | 275 +++++++++++++++++++++++++++++++++++++++++++-- discord/message.py | 7 +- discord/state.py | 9 +- 5 files changed, 285 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 791df31a1f..a1a4edb7d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ These changes are available on the `master` branch, but have not yet been releas ([#1916](https://github.com/Pycord-Development/pycord/pull/1916)) - Added the `@client.once()` decorator, which serves as a one-time event listener. ([#1940](https://github.com/Pycord-Development/pycord/pull/1940)) +- Added support for text-related features in `StageChannel` + ([#1936](https://github.com/Pycord-Development/pycord/pull/1936)) ### Fixed diff --git a/discord/abc.py b/discord/abc.py index 4ab10409c0..027ba96b18 100644 --- a/discord/abc.py +++ b/discord/abc.py @@ -77,6 +77,7 @@ DMChannel, GroupChannel, PartialMessageable, + StageChannel, TextChannel, VoiceChannel, ) @@ -97,7 +98,7 @@ from .user import ClientUser PartialMessageableChannel = Union[ - TextChannel, VoiceChannel, Thread, DMChannel, PartialMessageable + TextChannel, VoiceChannel, StageChannel, Thread, DMChannel, PartialMessageable ] MessageableChannel = Union[PartialMessageableChannel, GroupChannel] SnowflakeTime = Union["Snowflake", datetime] @@ -1292,6 +1293,8 @@ class Messageable: The following implement this ABC: - :class:`~discord.TextChannel` + - :class:`~discord.VoiceChannel` + - :class:`~discord.StageChannel` - :class:`~discord.DMChannel` - :class:`~discord.GroupChannel` - :class:`~discord.User` diff --git a/discord/channel.py b/discord/channel.py index 2efca7be02..88ba717db5 100644 --- a/discord/channel.py +++ b/discord/channel.py @@ -1358,6 +1358,7 @@ class VocalGuildChannel(discord.abc.Connectable, discord.abc.GuildChannel, Hasha "video_quality_mode", "last_message_id", "flags", + "nsfw", ) def __init__( @@ -1401,6 +1402,7 @@ def _update( self.bitrate: int = data.get("bitrate") self.user_limit: int = data.get("user_limit") self.flags: ChannelFlags = ChannelFlags._from_value(data.get("flags", 0)) + self.nsfw: bool = data.get("nsfw", False) self._fill_overwrites(data) @property @@ -1510,11 +1512,8 @@ class VoiceChannel(discord.abc.Messageable, VocalGuildChannel): .. versionadded:: 2.0 """ - __slots__ = "nsfw" - def _update(self, guild: Guild, data: VoiceChannelPayload): super()._update(guild, data) - self.nsfw: bool = data.get("nsfw", False) def __repr__(self) -> str: attrs = [ @@ -1944,7 +1943,7 @@ async def create_activity_invite( ) -class StageChannel(VocalGuildChannel): +class StageChannel(discord.abc.Messageable, VocalGuildChannel): """Represents a Discord guild stage channel. .. versionadded:: 1.7 @@ -1997,10 +1996,17 @@ class StageChannel(VocalGuildChannel): Extra features of the channel. .. versionadded:: 2.0 + last_message_id: Optional[:class:`int`] + The ID of the last message sent to this channel. It may not always point to an existing or valid message. + .. versionadded:: 2.5 """ __slots__ = ("topic",) + def _update(self, guild: Guild, data: StageChannelPayload) -> None: + super()._update(guild, data) + self.topic = data.get("topic") + def __repr__(self) -> str: attrs = [ ("id", self.id), @@ -2016,10 +2022,6 @@ 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: StageChannelPayload) -> None: - super()._update(guild, data) - self.topic = data.get("topic") - @property def requesting_to_speak(self) -> list[Member]: """A list of members who are requesting to speak in the stage channel.""" @@ -2053,6 +2055,263 @@ def listeners(self) -> list[Member]: member for member in self.members if member.voice and member.voice.suppress ] + async def _get_channel(self): + return self + + def is_nsfw(self) -> bool: + """Checks if the channel is NSFW.""" + return self.nsfw + + @property + def 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. + + .. admonition:: Reliable Fetching + :class: helpful + + For a slightly more reliable method of fetching the + last message, consider using either :meth:`history` + or :meth:`fetch_message` with the :attr:`last_message_id` + attribute. + + Returns + ------- + 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 + ) + + def get_partial_message(self, message_id: int, /) -> PartialMessage: + """Creates a :class:`PartialMessage` from the message ID. + + This is useful if you want to work with a message and only have its ID without + doing an unnecessary API call. + + .. versionadded:: 1.6 + + Parameters + ---------- + message_id: :class:`int` + The message ID to create a partial message for. + + Returns + ------- + :class:`PartialMessage` + The partial message. + """ + + from .message import PartialMessage + + return PartialMessage(channel=self, id=message_id) + + async def delete_messages( + self, messages: Iterable[Snowflake], *, reason: str | None = None + ) -> None: + """|coro| + + Deletes a list of messages. This is similar to :meth:`Message.delete` + except it bulk deletes multiple messages. + + As a special case, if the number of messages is 0, then nothing + is done. If the number of messages is 1 then single message + delete is done. If it's more than two, then bulk delete is used. + + You cannot bulk delete more than 100 messages or messages that + are older than 14 days old. + + You must have the :attr:`~Permissions.manage_messages` permission to + use this. + + Parameters + ---------- + messages: Iterable[:class:`abc.Snowflake`] + An iterable of messages denoting which ones to bulk delete. + reason: Optional[:class:`str`] + The reason for deleting the messages. Shows up on the audit log. + + Raises + ------ + ClientException + The number of messages to delete was more than 100. + Forbidden + You do not have proper permissions to delete the messages. + NotFound + If single delete, then the message was already deleted. + HTTPException + Deleting the messages failed. + """ + if not isinstance(messages, (list, tuple)): + messages = list(messages) + + if len(messages) == 0: + return # do nothing + + if len(messages) == 1: + message_id: int = messages[0].id + await self._state.http.delete_message(self.id, message_id, reason=reason) + return + + if len(messages) > 100: + raise ClientException("Can only bulk delete messages up to 100 messages") + + message_ids: SnowflakeList = [m.id for m in messages] + await self._state.http.delete_messages(self.id, message_ids, reason=reason) + + async def purge( + self, + *, + limit: int | None = 100, + check: Callable[[Message], bool] = MISSING, + before: SnowflakeTime | None = None, + after: SnowflakeTime | None = None, + around: SnowflakeTime | None = None, + oldest_first: bool | None = False, + bulk: bool = True, + reason: str | None = None, + ) -> list[Message]: + """|coro| + + Purges a list of messages that meet the criteria given by the predicate + ``check``. If a ``check`` is not provided then all messages are deleted + without discrimination. + + You must have the :attr:`~Permissions.manage_messages` permission to + delete messages even if they are your own. + The :attr:`~Permissions.read_message_history` permission is + also needed to retrieve message history. + + Parameters + ---------- + limit: Optional[:class:`int`] + The number of messages to search through. This is not the number + of messages that will be deleted, though it can be. + check: Callable[[:class:`Message`], :class:`bool`] + The function used to check if a message should be deleted. + It must take a :class:`Message` as its sole parameter. + before: Optional[Union[:class:`abc.Snowflake`, :class:`datetime.datetime`]] + Same as ``before`` in :meth:`history`. + after: Optional[Union[:class:`abc.Snowflake`, :class:`datetime.datetime`]] + Same as ``after`` in :meth:`history`. + around: Optional[Union[:class:`abc.Snowflake`, :class:`datetime.datetime`]] + Same as ``around`` in :meth:`history`. + oldest_first: Optional[:class:`bool`] + Same as ``oldest_first`` in :meth:`history`. + bulk: :class:`bool` + If ``True``, use bulk delete. Setting this to ``False`` is useful for mass-deleting + a bot's own messages without :attr:`Permissions.manage_messages`. When ``True``, will + fall back to single delete if messages are older than two weeks. + reason: Optional[:class:`str`] + The reason for deleting the messages. Shows up on the audit log. + + Returns + ------- + List[:class:`.Message`] + The list of messages that were deleted. + + Raises + ------ + Forbidden + You do not have proper permissions to do the actions required. + HTTPException + Purging the messages failed. + + Examples + -------- + + Deleting bot's messages :: + + def is_me(m): + return m.author == client.user + + deleted = await channel.purge(limit=100, check=is_me) + await channel.send(f'Deleted {len(deleted)} message(s)') + """ + return await discord.abc._purge_messages_helper( + self, + limit=limit, + check=check, + before=before, + after=after, + around=around, + oldest_first=oldest_first, + bulk=bulk, + reason=reason, + ) + + async def webhooks(self) -> list[Webhook]: + """|coro| + + Gets the list of webhooks from this channel. + + Requires :attr:`~.Permissions.manage_webhooks` permissions. + + Returns + ------- + List[:class:`Webhook`] + The webhooks for this channel. + + Raises + ------ + Forbidden + You don't have permissions to get the webhooks. + """ + + from .webhook import Webhook + + data = await self._state.http.channel_webhooks(self.id) + return [Webhook.from_state(d, state=self._state) for d in data] + + async def create_webhook( + self, *, name: str, avatar: bytes | None = None, reason: str | None = None + ) -> Webhook: + """|coro| + + Creates a webhook for this channel. + + Requires :attr:`~.Permissions.manage_webhooks` permissions. + + .. versionchanged:: 1.1 + Added the ``reason`` keyword-only parameter. + + Parameters + ---------- + name: :class:`str` + The webhook's name. + avatar: Optional[:class:`bytes`] + A :term:`py:bytes-like object` representing the webhook's default avatar. + This operates similarly to :meth:`~ClientUser.edit`. + reason: Optional[:class:`str`] + The reason for creating this webhook. Shows up in the audit logs. + + Returns + ------- + :class:`Webhook` + The created webhook. + + Raises + ------ + HTTPException + Creating the webhook failed. + Forbidden + You do not have permissions to create a webhook. + """ + + from .webhook import Webhook + + if avatar is not None: + avatar = utils._bytes_to_base64_data(avatar) # type: ignore + + data = await self._state.http.create_webhook( + self.id, name=str(name), avatar=avatar, reason=reason + ) + return Webhook.from_state(data, state=self._state) + @property def moderators(self) -> list[Member]: """A list of members who are moderating the stage channel. diff --git a/discord/message.py b/discord/message.py index e299113369..69c7a79753 100644 --- a/discord/message.py +++ b/discord/message.py @@ -1798,6 +1798,8 @@ class PartialMessage(Hashable): - :meth:`TextChannel.get_partial_message` - :meth:`Thread.get_partial_message` - :meth:`DMChannel.get_partial_message` + - :meth:`VoiceChannel.get_partial_message` + - :meth:`StageChannel.get_partial_message` Note that this class is trimmed down and has no rich attributes. @@ -1819,7 +1821,7 @@ class PartialMessage(Hashable): Attributes ---------- - channel: Union[:class:`TextChannel`, :class:`Thread`, :class:`DMChannel`] + channel: Union[:class:`TextChannel`, :class:`Thread`, :class:`DMChannel`, :class:`VoiceChannel`, :class:`StageChannel`] The channel associated with this partial message. id: :class:`int` The message ID. @@ -1844,6 +1846,7 @@ def __init__(self, *, channel: PartialMessageableChannel, id: int): if channel.type not in ( ChannelType.text, ChannelType.voice, + ChannelType.stage_voice, ChannelType.news, ChannelType.private, ChannelType.news_thread, @@ -1851,7 +1854,7 @@ def __init__(self, *, channel: PartialMessageableChannel, id: int): ChannelType.private_thread, ): raise TypeError( - "Expected TextChannel, VoiceChannel, DMChannel or Thread not" + "Expected TextChannel, VoiceChannel, StageChannel, DMChannel or Thread not" f" {type(channel)!r}" ) diff --git a/discord/state.py b/discord/state.py index 744f63cabf..90fd97ab53 100644 --- a/discord/state.py +++ b/discord/state.py @@ -672,8 +672,13 @@ def parse_message_create(self, data) -> None: self.dispatch("message", message) if self._messages is not None: self._messages.append(message) - # we ensure that the channel is either a TextChannel, VoiceChannel, or Thread - if channel and channel.__class__ in (TextChannel, VoiceChannel, Thread): + # 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: From 5d7a2b4a3c13d6cdeee94b3ec9eafddabccda800 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Mar 2023 21:21:13 -0600 Subject: [PATCH 06/67] chore(deps-dev): Bump pre-commit from 3.1.0 to 3.1.1 (#1952) Bumps [pre-commit](https://github.com/pre-commit/pre-commit) from 3.1.0 to 3.1.1. - [Release notes](https://github.com/pre-commit/pre-commit/releases) - [Changelog](https://github.com/pre-commit/pre-commit/blob/main/CHANGELOG.md) - [Commits](https://github.com/pre-commit/pre-commit/compare/v3.1.0...v3.1.1) --- updated-dependencies: - dependency-name: pre-commit dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/dev.txt b/requirements/dev.txt index 59140de190..c0893bf470 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -5,7 +5,7 @@ pytest-asyncio~=0.20.3 # pytest-order~=1.0.1 mypy~=1.0.1 coverage~=7.2 -pre-commit==3.1.0 +pre-commit==3.1.1 codespell==2.2.2 bandit==1.7.4 flake8==6.0.0 From eb903873f15d44f53de0831269cf0eebb60ec6f8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 Mar 2023 03:26:16 +0000 Subject: [PATCH 07/67] chore(deps): Bump myst-parser from 0.18.1 to 0.19.0 (#1953) Bumps [myst-parser](https://github.com/executablebooks/MyST-Parser) from 0.18.1 to 0.19.0. - [Release notes](https://github.com/executablebooks/MyST-Parser/releases) - [Changelog](https://github.com/executablebooks/MyST-Parser/blob/master/CHANGELOG.md) - [Commits](https://github.com/executablebooks/MyST-Parser/compare/v0.18.1...v0.19.0) --- updated-dependencies: - dependency-name: myst-parser dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/docs.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/docs.txt b/requirements/docs.txt index 221ba9f64a..90c64737d2 100644 --- a/requirements/docs.txt +++ b/requirements/docs.txt @@ -1,7 +1,7 @@ sphinx==5.3.0 sphinxcontrib_trio==1.1.2 sphinxcontrib-websupport==1.2.4 -myst-parser==0.18.1 +myst-parser==0.19.0 sphinxext-opengraph==0.8.1 sphinx-copybutton==0.5.1 furo@ git+https://github.com/pradyunsg/furo@193643f From cab0d71adf406422dc52f6c062350fb50af1f994 Mon Sep 17 00:00:00 2001 From: Lala Sabathil Date: Thu, 2 Mar 2023 04:41:37 +0100 Subject: [PATCH 08/67] fix: ip discovery changes (74 byte udp packets) (#1955) * fix: ip discovery changes (74 byte udp packets) * chore: Pr will be 1955 * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update CHANGELOG.md Signed-off-by: Lala Sabathil * Update CHANGELOG.md Co-authored-by: BobDotCom <71356958+BobDotCom@users.noreply.github.com> Signed-off-by: Lala Sabathil --------- Signed-off-by: Lala Sabathil Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: BobDotCom <71356958+BobDotCom@users.noreply.github.com> --- CHANGELOG.md | 3 +++ discord/gateway.py | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a1a4edb7d3..c717c55347 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,9 @@ These changes are available on the `master` branch, but have not yet been releas - Fixed the type-hinting of `SlashCommandGroup.walk_commands()` to reflect actual behavior. ([#1852](https://github.com/Pycord-Development/pycord/pull/1852)) +- Fixed the voice ip discovery due to the recent + [announced change](https://discord.com/channels/613425648685547541/697138785317814292/1080623873629884486). + ([#1955](https://github.com/Pycord-Development/pycord/pull/1955)) ## [2.4.0] - 2023-02-10 diff --git a/discord/gateway.py b/discord/gateway.py index d337dda69f..bd13f22e46 100644 --- a/discord/gateway.py +++ b/discord/gateway.py @@ -892,16 +892,16 @@ async def initial_connection(self, data): state.voice_port = data["port"] state.endpoint_ip = data["ip"] - packet = bytearray(70) + packet = bytearray(74) struct.pack_into(">H", packet, 0, 1) # 1 = Send struct.pack_into(">H", packet, 2, 70) # 70 = Length struct.pack_into(">I", packet, 4, state.ssrc) state.socket.sendto(packet, (state.endpoint_ip, state.voice_port)) - recv = await self.loop.sock_recv(state.socket, 70) + recv = await self.loop.sock_recv(state.socket, 74) _log.debug("received packet in initial_connection: %s", recv) - # the ip is ascii starting at the 4th byte and ending at the first null - ip_start = 4 + # the ip is ascii starting at the 8th byte and ending at the first null + ip_start = 8 ip_end = recv.index(0, ip_start) state.ip = recv[ip_start:ip_end].decode("ascii") From f5433762daa979b7e03fd03e293d2945f1efd736 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Mar 2023 10:34:35 -0600 Subject: [PATCH 09/67] chore(deps-dev): Update pylint requirement from ~=2.16.2 to ~=2.17.0 (#1968) Updates the requirements on [pylint](https://github.com/PyCQA/pylint) to permit the latest version. - [Release notes](https://github.com/PyCQA/pylint/releases) - [Commits](https://github.com/PyCQA/pylint/compare/v2.16.2...v2.17.0) --- updated-dependencies: - dependency-name: pylint dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/dev.txt b/requirements/dev.txt index c0893bf470..b5da277803 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -1,5 +1,5 @@ -r _.txt -pylint~=2.16.2 +pylint~=2.17.0 pytest~=7.2.1 pytest-asyncio~=0.20.3 # pytest-order~=1.0.1 From 67a891b73a8b02db9b3063b6e10c43c60bb3ce78 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Mar 2023 10:34:50 -0600 Subject: [PATCH 10/67] chore(deps-dev): Bump codespell from 2.2.2 to 2.2.4 (#1967) Bumps [codespell](https://github.com/codespell-project/codespell) from 2.2.2 to 2.2.4. - [Release notes](https://github.com/codespell-project/codespell/releases) - [Commits](https://github.com/codespell-project/codespell/compare/v2.2.2...v2.2.4) --- updated-dependencies: - dependency-name: codespell dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/dev.txt b/requirements/dev.txt index b5da277803..9611643e2b 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -6,6 +6,6 @@ pytest-asyncio~=0.20.3 mypy~=1.0.1 coverage~=7.2 pre-commit==3.1.1 -codespell==2.2.2 +codespell==2.2.4 bandit==1.7.4 flake8==6.0.0 From 838b97ca550deb1122617c05b93481b2d1bac1be Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Mar 2023 10:35:28 -0600 Subject: [PATCH 11/67] chore(deps-dev): Update mypy requirement from ~=1.0.1 to ~=1.1.1 (#1965) Updates the requirements on [mypy](https://github.com/python/mypy) to permit the latest version. - [Release notes](https://github.com/python/mypy/releases) - [Commits](https://github.com/python/mypy/compare/v1.0.1...v1.1.1) --- updated-dependencies: - dependency-name: mypy dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/dev.txt b/requirements/dev.txt index 9611643e2b..2020b50e67 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -3,7 +3,7 @@ pylint~=2.17.0 pytest~=7.2.1 pytest-asyncio~=0.20.3 # pytest-order~=1.0.1 -mypy~=1.0.1 +mypy~=1.1.1 coverage~=7.2 pre-commit==3.1.1 codespell==2.2.4 From 02f32517d718e1f634de7d4e5a3f11b311158fdb Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 9 Mar 2023 10:35:47 -0600 Subject: [PATCH 12/67] chore(pre-commit): pre-commit autoupdate (#1961) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-prettier: v3.0.0-alpha.4 → v3.0.0-alpha.6](https://github.com/pre-commit/mirrors-prettier/compare/v3.0.0-alpha.4...v3.0.0-alpha.6) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 50d52ea416..ba50fa3b6a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -76,7 +76,7 @@ repos: # - id: mypy - repo: https://github.com/pre-commit/mirrors-prettier - rev: v3.0.0-alpha.4 + rev: v3.0.0-alpha.6 hooks: - id: prettier args: [--prose-wrap=always, --print-width=88] From b92409bbc2f39999fb7382a8c9e54d06d5bc0ac0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Mar 2023 10:36:56 -0600 Subject: [PATCH 13/67] chore(deps): Bump myst-parser from 0.19.0 to 1.0.0 (#1966) Bumps [myst-parser](https://github.com/executablebooks/MyST-Parser) from 0.19.0 to 1.0.0. - [Release notes](https://github.com/executablebooks/MyST-Parser/releases) - [Changelog](https://github.com/executablebooks/MyST-Parser/blob/master/CHANGELOG.md) - [Commits](https://github.com/executablebooks/MyST-Parser/compare/v0.19.0...v1.0.0) --- updated-dependencies: - dependency-name: myst-parser dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/docs.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/docs.txt b/requirements/docs.txt index 90c64737d2..fdc9d77afa 100644 --- a/requirements/docs.txt +++ b/requirements/docs.txt @@ -1,7 +1,7 @@ sphinx==5.3.0 sphinxcontrib_trio==1.1.2 sphinxcontrib-websupport==1.2.4 -myst-parser==0.19.0 +myst-parser==1.0.0 sphinxext-opengraph==0.8.1 sphinx-copybutton==0.5.1 furo@ git+https://github.com/pradyunsg/furo@193643f From e78732682ef61f4bb8fdaca26b482bcfbed1aeda Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Mar 2023 10:50:26 -0600 Subject: [PATCH 14/67] chore(deps-dev): Update pytest requirement from ~=7.2.1 to ~=7.2.2 (#1959) Updates the requirements on [pytest](https://github.com/pytest-dev/pytest) to permit the latest version. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/7.2.1...7.2.2) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/dev.txt b/requirements/dev.txt index 2020b50e67..7ec7f443eb 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -1,6 +1,6 @@ -r _.txt pylint~=2.17.0 -pytest~=7.2.1 +pytest~=7.2.2 pytest-asyncio~=0.20.3 # pytest-order~=1.0.1 mypy~=1.1.1 From 010116d8bb5d294a75bf4442be1cef03057219fe Mon Sep 17 00:00:00 2001 From: Om <92863779+Om1609@users.noreply.github.com> Date: Fri, 10 Mar 2023 04:41:41 +0530 Subject: [PATCH 15/67] fix: pass `reason` to the correct method in AutoModRule (#1960) * Remove `reason` from being passed to AutoModRule Signed-off-by: Om <92863779+Om1609@users.noreply.github.com> * Update discord/guild.py Co-authored-by: plun1331 <49261529+plun1331@users.noreply.github.com> Signed-off-by: Om <92863779+Om1609@users.noreply.github.com> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update CHANGELOG.md Signed-off-by: Om <92863779+Om1609@users.noreply.github.com> * Update CHANGELOG.md Signed-off-by: BobDotCom <71356958+BobDotCom@users.noreply.github.com> --------- Signed-off-by: Om <92863779+Om1609@users.noreply.github.com> Signed-off-by: BobDotCom <71356958+BobDotCom@users.noreply.github.com> Co-authored-by: plun1331 <49261529+plun1331@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: BobDotCom <71356958+BobDotCom@users.noreply.github.com> --- CHANGELOG.md | 2 ++ discord/guild.py | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c717c55347..632d95bbcf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,8 @@ These changes are available on the `master` branch, but have not yet been releas - Fixed the voice ip discovery due to the recent [announced change](https://discord.com/channels/613425648685547541/697138785317814292/1080623873629884486). ([#1955](https://github.com/Pycord-Development/pycord/pull/1955)) +- Fixed `reason` being passed to wrong method in `guild.create_auto_moderation_rule`. + ([#1960](https://github.com/Pycord-Development/pycord/pull/1960)) ## [2.4.0] - 2023-02-10 diff --git a/discord/guild.py b/discord/guild.py index 465a6096dd..067f71ed39 100644 --- a/discord/guild.py +++ b/discord/guild.py @@ -3835,5 +3835,7 @@ async def create_auto_moderation_rule( if exempt_channels: payload["exempt_channels"] = [c.id for c in exempt_channels] - data = await self._state.http.create_auto_moderation_rule(self.id, payload) - return AutoModRule(state=self._state, data=data, reason=reason) + data = await self._state.http.create_auto_moderation_rule( + self.id, payload, reason=reason + ) + return AutoModRule(state=self._state, data=data) From 38c05cb45a1f4e7e49f922dd3340c31c62287611 Mon Sep 17 00:00:00 2001 From: JustaSqu1d Date: Tue, 14 Mar 2023 18:15:50 -0700 Subject: [PATCH 16/67] docs: fix message_content missing subject (#1975) --- discord/flags.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/discord/flags.py b/discord/flags.py index b0808026f7..c04020a28e 100644 --- a/discord/flags.py +++ b/discord/flags.py @@ -1077,7 +1077,7 @@ def message_content(self): .. note:: - As of September 2022 requires opting in explicitly via the Developer Portal to receive the actual content + As of September 2022 using this intent requires opting in explicitly via the Developer Portal to receive the actual content of the guild messages. This intent is privileged, meaning that bots in over 100 guilds that require this intent would need to request this intent on the Developer Portal. See https://support-dev.discord.com/hc/en-us/articles/4404772028055 for more information. From cedde9480900410a3aefd63f8103cf588aef8847 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Mar 2023 14:31:31 -0500 Subject: [PATCH 17/67] chore(deps-dev): Bump pre-commit from 3.1.1 to 3.2.0 (#1977) Bumps [pre-commit](https://github.com/pre-commit/pre-commit) from 3.1.1 to 3.2.0. - [Release notes](https://github.com/pre-commit/pre-commit/releases) - [Changelog](https://github.com/pre-commit/pre-commit/blob/main/CHANGELOG.md) - [Commits](https://github.com/pre-commit/pre-commit/compare/v3.1.1...v3.2.0) --- updated-dependencies: - dependency-name: pre-commit dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/dev.txt b/requirements/dev.txt index 7ec7f443eb..3e92c91462 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -5,7 +5,7 @@ pytest-asyncio~=0.20.3 # pytest-order~=1.0.1 mypy~=1.1.1 coverage~=7.2 -pre-commit==3.1.1 +pre-commit==3.2.0 codespell==2.2.4 bandit==1.7.4 flake8==6.0.0 From 2eacfc9413c438b5dd3c9384e090b5357275ca70 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 20 Mar 2023 15:17:48 -0500 Subject: [PATCH 18/67] chore(pre-commit): pre-commit autoupdate (#1974) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/PyCQA/autoflake: v2.0.1 → v2.0.2](https://github.com/PyCQA/autoflake/compare/v2.0.1...v2.0.2) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ba50fa3b6a..23eddd57ff 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -8,7 +8,7 @@ repos: - id: trailing-whitespace - id: end-of-file-fixer - repo: https://github.com/PyCQA/autoflake - rev: v2.0.1 + rev: v2.0.2 hooks: - id: autoflake # args: From 5e723c14449bd89f2347774023cd1840a5a316f0 Mon Sep 17 00:00:00 2001 From: BobDotCom <71356958+BobDotCom@users.noreply.github.com> Date: Mon, 20 Mar 2023 17:37:18 -0500 Subject: [PATCH 19/67] docs(changelog): update changelog for v2.4.1 --- CHANGELOG.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 632d95bbcf..ad17545335 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,9 +17,17 @@ These changes are available on the `master` branch, but have not yet been releas ([#1916](https://github.com/Pycord-Development/pycord/pull/1916)) - Added the `@client.once()` decorator, which serves as a one-time event listener. ([#1940](https://github.com/Pycord-Development/pycord/pull/1940)) -- Added support for text-related features in `StageChannel` +- Added support for text-related features in `StageChannel`. ([#1936](https://github.com/Pycord-Development/pycord/pull/1936)) +## [2.4.1] - 2023-03-20 + +### Changed + +- Updated the values of the `Color.embed_background()` classmethod to correspond with + new theme colors in the app. + ([#1931](https://github.com/Pycord-Development/pycord/pull/1931)) + ### Fixed - Fixed the type-hinting of `SlashCommandGroup.walk_commands()` to reflect actual @@ -539,7 +547,8 @@ These changes are available on the `master` branch, but have not yet been releas - Fix py3.10 UnionType checks issue. ([#1240](https://github.com/Pycord-Development/pycord/pull/1240)) -[unreleased]: https://github.com/Pycord-Development/pycord/compare/v2.4.0...HEAD +[unreleased]: https://github.com/Pycord-Development/pycord/compare/v2.4.1...HEAD +[2.4.1]: https://github.com/Pycord-Development/pycord/compare/v2.4.0...v2.4.1 [2.4.0]: https://github.com/Pycord-Development/pycord/compare/v2.3.3...v2.4.0 [2.3.3]: https://github.com/Pycord-Development/pycord/compare/v2.3.2...v2.3.3 [2.3.2]: https://github.com/Pycord-Development/pycord/compare/v2.3.1...v2.3.2 From f8b4294ff06e0f700bcfe8c0ec13d0ec0085c7dd Mon Sep 17 00:00:00 2001 From: BobDotCom <71356958+BobDotCom@users.noreply.github.com> Date: Mon, 20 Mar 2023 17:40:43 -0500 Subject: [PATCH 20/67] docs(changelog): fix pull request number in entry Signed-off-by: BobDotCom <71356958+BobDotCom@users.noreply.github.com> --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad17545335..674fee9e46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,7 +31,7 @@ These changes are available on the `master` branch, but have not yet been releas ### Fixed - Fixed the type-hinting of `SlashCommandGroup.walk_commands()` to reflect actual - behavior. ([#1852](https://github.com/Pycord-Development/pycord/pull/1852)) + behavior. ([#1838](https://github.com/Pycord-Development/pycord/pull/1838)) - Fixed the voice ip discovery due to the recent [announced change](https://discord.com/channels/613425648685547541/697138785317814292/1080623873629884486). ([#1955](https://github.com/Pycord-Development/pycord/pull/1955)) From 910c4000a48dd2b55706565d3931f9a41735fa67 Mon Sep 17 00:00:00 2001 From: DefiDebauchery <75273961+DefiDebauchery@users.noreply.github.com> Date: Fri, 24 Mar 2023 00:49:02 -0400 Subject: [PATCH 21/67] feat: add current_page parameter to paginator.update() (#1983) --- CHANGELOG.md | 2 ++ discord/ext/pages/pagination.py | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 674fee9e46..2de68efacd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,8 @@ These changes are available on the `master` branch, but have not yet been releas ([#1940](https://github.com/Pycord-Development/pycord/pull/1940)) - Added support for text-related features in `StageChannel`. ([#1936](https://github.com/Pycord-Development/pycord/pull/1936)) +- Added `current_page` argument to Paginator.update() + ([#1983](https://github.com/Pycord-Development/pycord/pull/1983)) ## [2.4.1] - 2023-03-20 diff --git a/discord/ext/pages/pagination.py b/discord/ext/pages/pagination.py index 463992988b..6228158c63 100644 --- a/discord/ext/pages/pagination.py +++ b/discord/ext/pages/pagination.py @@ -465,6 +465,7 @@ async def update( custom_buttons: list[PaginatorButton] | None = None, trigger_on_display: bool | None = None, interaction: discord.Interaction | None = None, + current_page: int = 0, ): """Updates the existing :class:`Paginator` instance with the provided options. @@ -505,6 +506,8 @@ async def update( interaction: Optional[:class:`discord.Interaction`] The interaction to use when updating the paginator. If not provided, the paginator will be updated by using its stored :attr:`message` attribute instead. + current_page: :class:`int` + The initial page number to display when updating the paginator. """ # Update pages and reset current_page to 0 (default) @@ -527,7 +530,7 @@ async def update( self.page_groups[self.default_page_group] ) self.page_count = max(len(self.pages) - 1, 0) - self.current_page = 0 + self.current_page = current_page if current_page <= self.page_count else 0 # Apply config changes, if specified self.show_disabled = ( show_disabled if show_disabled is not None else self.show_disabled From 97a60f1e009b96fabcea6e7c0beeed150b55ac19 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Mar 2023 11:43:22 -0500 Subject: [PATCH 22/67] chore(deps-dev): Update pylint requirement from ~=2.17.0 to ~=2.17.1 (#1982) Updates the requirements on [pylint](https://github.com/PyCQA/pylint) to permit the latest version. - [Release notes](https://github.com/PyCQA/pylint/releases) - [Commits](https://github.com/PyCQA/pylint/compare/v2.17.0...v2.17.1) --- updated-dependencies: - dependency-name: pylint dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/dev.txt b/requirements/dev.txt index 3e92c91462..9c898e8feb 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -1,5 +1,5 @@ -r _.txt -pylint~=2.17.0 +pylint~=2.17.1 pytest~=7.2.2 pytest-asyncio~=0.20.3 # pytest-order~=1.0.1 From ea847583d55ce953cc5116e5851b8220c0b921da Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Mar 2023 11:43:47 -0500 Subject: [PATCH 23/67] chore(deps-dev): Update pytest-asyncio requirement from ~=0.20.3 to ~=0.21.0 (#1978) chore(deps-dev): Update pytest-asyncio requirement Updates the requirements on [pytest-asyncio](https://github.com/pytest-dev/pytest-asyncio) to permit the latest version. - [Release notes](https://github.com/pytest-dev/pytest-asyncio/releases) - [Commits](https://github.com/pytest-dev/pytest-asyncio/compare/v0.20.3...v0.21.0) --- updated-dependencies: - dependency-name: pytest-asyncio dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/dev.txt b/requirements/dev.txt index 9c898e8feb..00ff7b8c74 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -1,7 +1,7 @@ -r _.txt pylint~=2.17.1 pytest~=7.2.2 -pytest-asyncio~=0.20.3 +pytest-asyncio~=0.21.0 # pytest-order~=1.0.1 mypy~=1.1.1 coverage~=7.2 From 2e9ab6177c5a464dedcd76cf6a17596607587e86 Mon Sep 17 00:00:00 2001 From: Om <92863779+Om1609@users.noreply.github.com> Date: Sat, 25 Mar 2023 17:15:25 +0530 Subject: [PATCH 24/67] feat!: one time event listeners (#1957) Signed-off-by: Om <92863779+Om1609@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: VincentRPS Co-authored-by: Lulalaby --- CHANGELOG.md | 9 ++++- discord/client.py | 76 +++++++++------------------------------ docs/api/clients.rst | 11 +++--- docs/ext/commands/api.rst | 7 ++-- 4 files changed, 31 insertions(+), 72 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2de68efacd..b763c9c413 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,8 +19,15 @@ These changes are available on the `master` branch, but have not yet been releas ([#1940](https://github.com/Pycord-Development/pycord/pull/1940)) - Added support for text-related features in `StageChannel`. ([#1936](https://github.com/Pycord-Development/pycord/pull/1936)) +- Added support for one-time event listeners in `@client.listen()`. + ([#1957](https://github.com/Pycord-Development/pycord/pull/1957)) - Added `current_page` argument to Paginator.update() - ([#1983](https://github.com/Pycord-Development/pycord/pull/1983)) + ([#1983](https://github.com/Pycord-Development/pycord/pull/1983) + +### Removed + +- Removed `@client.once()` in favour of `@client.listen(once=True)` + ([#1957](https://github.com/Pycord-Development/pycord/pull/1957)) ## [2.4.1] - 2023-03-20 diff --git a/discord/client.py b/discord/client.py index 07bba3bf41..a6849a205b 100644 --- a/discord/client.py +++ b/discord/client.py @@ -435,9 +435,19 @@ def dispatch(self, event: str, *args: Any, **kwargs: Any) -> None: else: self._schedule_event(coro, method, *args, **kwargs) + # collect the once listeners as removing them from the list + # while iterating over it causes issues + once_listeners = [] + # Schedule additional handlers registered with @listen for coro in self._event_handlers.get(method, []): self._schedule_event(coro, method, *args, **kwargs) + if coro._once: + once_listeners.append(coro) + + # remove the once listeners + for coro in once_listeners: + self._event_handlers[method].remove(coro) async def on_error(self, event_method: str, *args: Any, **kwargs: Any) -> None: """|coro| @@ -1204,7 +1214,7 @@ def remove_listener(self, func: Coro, name: str = MISSING) -> None: except ValueError: pass - def listen(self, name: str = MISSING) -> Callable[[Coro], Coro]: + def listen(self, name: str = MISSING, once: bool = False) -> Callable[[Coro], Coro]: """A decorator that registers another function as an external event listener. Basically this allows you to listen to multiple events from different places e.g. such as :func:`.on_ready` @@ -1233,6 +1243,11 @@ async def on_message(message): async def my_message(message): print('two') + # listen to the first event only + @client.listen('on_ready', once=True) + async def on_ready(): + print('ready!') + Would print one and two in an unspecified order. """ @@ -1241,6 +1256,7 @@ def decorator(func: Coro) -> Coro: if name == "on_application_command_error": return self.event(func) + func._once = once self.add_listener(func, name) return func @@ -1286,64 +1302,6 @@ async def on_ready(): _log.debug("%s has successfully been registered as an event", coro.__name__) return coro - def once( - self, name: str = MISSING, check: Callable[..., bool] | None = None - ) -> Coro: - """A decorator that registers an event to listen to only once. - - You can find more info about the events on the :ref:`documentation below `. - - The events must be a :ref:`coroutine `, if not, :exc:`TypeError` is raised. - - Parameters - ---------- - name: :class:`str` - The name of the event we want to listen to. This is passed to - :py:meth:`~discord.Client.wait_for`. Defaults to ``func.__name__``. - check: Optional[Callable[..., :class:`bool`]] - A predicate to check what to wait for. The arguments must meet the - parameters of the event being waited for. - - Raises - ------ - TypeError - The coroutine passed is not actually a coroutine. - - Example - ------- - - .. code-block:: python3 - - @client.once() - async def ready(): - print('Ready!') - """ - - def decorator(func: Coro) -> Coro: - if not asyncio.iscoroutinefunction(func): - raise TypeError("event registered must be a coroutine function") - - async def wrapped() -> None: - nonlocal name - nonlocal check - - name = func.__name__ if name is MISSING else name - - args = await self.wait_for(name, check=check) - - arg_len = func.__code__.co_argcount - if arg_len == 0 and args is None: - await func() - elif arg_len == 1: - await func(args) - else: - await func(*args) - - self.loop.create_task(wrapped()) - return func - - return decorator - async def change_presence( self, *, diff --git a/docs/api/clients.rst b/docs/api/clients.rst index aeae87cbcb..f5b03d8e6c 100644 --- a/docs/api/clients.rst +++ b/docs/api/clients.rst @@ -10,7 +10,7 @@ Bots .. autoclass:: Bot :members: :inherited-members: - :exclude-members: command, event, message_command, slash_command, user_command, listen, once + :exclude-members: command, event, message_command, slash_command, user_command, listen .. automethod:: Bot.command(**kwargs) :decorator: @@ -27,10 +27,7 @@ Bots .. automethod:: Bot.user_command(**kwargs) :decorator: - .. automethod:: Bot.listen(name=None) - :decorator: - - .. automethod:: Bot.once(name=None, check=None) + .. automethod:: Bot.listen(name=None, once=False) :decorator: .. attributetable:: AutoShardedBot @@ -44,7 +41,7 @@ Clients .. attributetable:: Client .. autoclass:: Client :members: - :exclude-members: fetch_guilds, event, once + :exclude-members: fetch_guilds, event, listen .. automethod:: Client.event() :decorator: @@ -52,7 +49,7 @@ Clients .. automethod:: Client.fetch_guilds :async-for: - .. automethod:: Client.once(name=None, check=None) + .. automethod:: Client.listen(name=None, once=False) :decorator: .. attributetable:: AutoShardedClient diff --git a/docs/ext/commands/api.rst b/docs/ext/commands/api.rst index 119a8de10c..2d9af7f378 100644 --- a/docs/ext/commands/api.rst +++ b/docs/ext/commands/api.rst @@ -23,7 +23,7 @@ Bot .. autoclass:: discord.ext.commands.Bot :members: :inherited-members: - :exclude-members: after_invoke, before_invoke, check, check_once, command, event, group, listen, once + :exclude-members: after_invoke, before_invoke, check, check_once, command, event, group, listen .. automethod:: Bot.after_invoke() :decorator: @@ -46,10 +46,7 @@ Bot .. automethod:: Bot.group(*args, **kwargs) :decorator: - .. automethod:: Bot.listen(name=None) - :decorator: - - .. automethod:: Bot.once(name=None, check=None) + .. automethod:: Bot.listen(name=None, once=False) :decorator: AutoShardedBot From 93c28aa7dfc587f5634c6c67d30ffee9e626dc1d Mon Sep 17 00:00:00 2001 From: JustaSqu1d Date: Tue, 28 Mar 2023 22:02:06 -0700 Subject: [PATCH 25/67] feat(ApplicationFlags): add application_auto_moderation_rule_create_badge (#1992) Signed-off-by: JustaSqu1d Signed-off-by: plun1331 <49261529+plun1331@users.noreply.github.com> Co-authored-by: plun1331 <49261529+plun1331@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- CHANGELOG.md | 6 ++++-- discord/flags.py | 8 ++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b763c9c413..cb78469987 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,12 +21,14 @@ These changes are available on the `master` branch, but have not yet been releas ([#1936](https://github.com/Pycord-Development/pycord/pull/1936)) - Added support for one-time event listeners in `@client.listen()`. ([#1957](https://github.com/Pycord-Development/pycord/pull/1957)) -- Added `current_page` argument to Paginator.update() +- Added `current_page` argument to Paginator.update(). ([#1983](https://github.com/Pycord-Development/pycord/pull/1983) +- Added new `application_auto_moderation_rule_create_badge` to `ApplicationFlags`. + ([#1992](https://github.com/Pycord-Development/pycord/pull/1992)) ### Removed -- Removed `@client.once()` in favour of `@client.listen(once=True)` +- Removed `@client.once()` in favour of `@client.listen(once=True)`. ([#1957](https://github.com/Pycord-Development/pycord/pull/1957)) ## [2.4.1] - 2023-03-20 diff --git a/discord/flags.py b/discord/flags.py index c04020a28e..ae5d74da82 100644 --- a/discord/flags.py +++ b/discord/flags.py @@ -1338,6 +1338,14 @@ def group_dm_create(self): """:class:`bool`: Returns ``True`` if the application can create group DMs.""" return 1 << 5 + @flag_value + def application_auto_moderation_rule_create_badge(self): + """:class:`bool`: Returns ``True`` if the application uses the Auto Moderation API. + + .. versionadded:: 2.5 + """ + return 1 << 6 + @flag_value def rpc_has_connected(self): """:class:`bool`: Returns ``True`` if the application has connected to RPC.""" From 614f79409ca3fb1e335e4ed8f900f2dbbe8b3b2c Mon Sep 17 00:00:00 2001 From: Om <92863779+Om1609@users.noreply.github.com> Date: Fri, 31 Mar 2023 20:05:21 +0530 Subject: [PATCH 26/67] fix: attribute error with listeners in cogs (#1989) * fix attribute error Signed-off-by: Om <92863779+Om1609@users.noreply.github.com> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Revert "[pre-commit.ci] auto fixes from pre-commit.com hooks" This reverts commit 3375d386bc662d9ddca6c60ecf620dbc00c0a3b3. * Revert "fix attribute error" This reverts commit b8733f2a549c51551a556ccd16f7af75573bc936. * fix using EAPF * Changelog and comments * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update CHANGELOG.md Signed-off-by: Om <92863779+Om1609@users.noreply.github.com> * Update CHANGELOG.md Co-authored-by: BobDotCom <71356958+BobDotCom@users.noreply.github.com> Signed-off-by: Om <92863779+Om1609@users.noreply.github.com> --------- Signed-off-by: Om <92863779+Om1609@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: BobDotCom <71356958+BobDotCom@users.noreply.github.com> --- CHANGELOG.md | 6 ++++++ discord/client.py | 14 ++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cb78469987..dd044d7072 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,12 @@ These changes are available on the `master` branch, but have not yet been releas - Removed `@client.once()` in favour of `@client.listen(once=True)`. ([#1957](https://github.com/Pycord-Development/pycord/pull/1957)) +### Fixed + +- Fixed `AttributeError` caused by + [#1957](https://github.com/Pycord-Development/pycord/pull/1957) when using listeners + in cogs. ([#1989](https://github.com/Pycord-Development/pycord/pull/1989)) + ## [2.4.1] - 2023-03-20 ### Changed diff --git a/discord/client.py b/discord/client.py index a6849a205b..654219a0bd 100644 --- a/discord/client.py +++ b/discord/client.py @@ -442,8 +442,18 @@ def dispatch(self, event: str, *args: Any, **kwargs: Any) -> None: # Schedule additional handlers registered with @listen for coro in self._event_handlers.get(method, []): self._schedule_event(coro, method, *args, **kwargs) - if coro._once: - once_listeners.append(coro) + + try: + if coro._once: # added using @listen() + once_listeners.append(coro) + + except AttributeError: # added using @Cog.add_listener() + # https://github.com/Pycord-Development/pycord/pull/1989 + # Although methods are similar to functions, attributes can't be added to them. + # This means that we can't add the `_once` attribute in the `add_listener` method + # and can only be added using the `@listen` decorator. + + continue # remove the once listeners for coro in once_listeners: From 4a5099a59ce561d4eca5c889662b24a4e887fe08 Mon Sep 17 00:00:00 2001 From: Middledot <78228142+Middledot@users.noreply.github.com> Date: Mon, 3 Apr 2023 02:01:57 -0400 Subject: [PATCH 27/67] fix(scheduled_events): location editing breaking (#1998) * fix(scheduled_events): location breaking * chore(changelog): changelog --- CHANGELOG.md | 2 ++ discord/scheduled_events.py | 2 ++ 2 files changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dd044d7072..57d0af8f6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,8 @@ These changes are available on the `master` branch, but have not yet been releas - Fixed `AttributeError` caused by [#1957](https://github.com/Pycord-Development/pycord/pull/1957) when using listeners in cogs. ([#1989](https://github.com/Pycord-Development/pycord/pull/1989)) +- Fixed scheduled events breaking when changing the location from external to a channel. + ([#1998](https://github.com/Pycord-Development/pycord/pull/1998)) ## [2.4.1] - 2023-03-20 diff --git a/discord/scheduled_events.py b/discord/scheduled_events.py index 8fefdc2c24..6f70ff88c6 100644 --- a/discord/scheduled_events.py +++ b/discord/scheduled_events.py @@ -359,6 +359,8 @@ async def edit( payload["channel_id"] = location.value.id payload["entity_metadata"] = None + payload["entity_type"] = location.type.value + location = location if location is not MISSING else self.location if end_time is MISSING and location.type is ScheduledEventLocationType.external: end_time = self.end_time From 279f616b392c78d3b2cdecf50830a5dd06e92b0d Mon Sep 17 00:00:00 2001 From: Om <92863779+Om1609@users.noreply.github.com> Date: Mon, 3 Apr 2023 21:52:13 +0530 Subject: [PATCH 28/67] fix: bridge command group name (#2000) * fix double name parameter * Update CHANGELOG.md Signed-off-by: Om <92863779+Om1609@users.noreply.github.com> --------- Signed-off-by: Om <92863779+Om1609@users.noreply.github.com> --- CHANGELOG.md | 2 ++ discord/ext/bridge/core.py | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 57d0af8f6d..951baa9f2e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,8 @@ These changes are available on the `master` branch, but have not yet been releas in cogs. ([#1989](https://github.com/Pycord-Development/pycord/pull/1989)) - Fixed scheduled events breaking when changing the location from external to a channel. ([#1998](https://github.com/Pycord-Development/pycord/pull/1998)) +- Fixed `TypeError` being raised when passing `name` argument to bridge groups. + ([#2000](https://github.com/Pycord-Development/pycord/pull/2000)) ## [2.4.1] - 2023-03-20 diff --git a/discord/ext/bridge/core.py b/discord/ext/bridge/core.py index 0985526ab0..8c9a69d265 100644 --- a/discord/ext/bridge/core.py +++ b/discord/ext/bridge/core.py @@ -325,10 +325,12 @@ class BridgeCommandGroup(BridgeCommand): slash_variant: BridgeSlashGroup def __init__(self, callback, *args, **kwargs): + ext_var = BridgeExtGroup(callback, *args, **kwargs) + kwargs.update({"name": ext_var.name}) super().__init__( callback, - ext_variant=(ext_var := BridgeExtGroup(callback, *args, **kwargs)), - slash_variant=BridgeSlashGroup(callback, ext_var.name, *args, **kwargs), + ext_variant=ext_var, + slash_variant=BridgeSlashGroup(callback, *args, **kwargs), parent=kwargs.pop("parent", None), ) From 982c5d8c5230e3f9f68a614600834b7306172159 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Apr 2023 23:11:40 +0200 Subject: [PATCH 29/67] chore(deps-dev): Update pylint requirement from ~=2.17.1 to ~=2.17.2 (#2002) Updates the requirements on [pylint](https://github.com/PyCQA/pylint) to permit the latest version. - [Release notes](https://github.com/PyCQA/pylint/releases) - [Commits](https://github.com/PyCQA/pylint/compare/v2.17.1...v2.17.2) --- updated-dependencies: - dependency-name: pylint dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/dev.txt b/requirements/dev.txt index 00ff7b8c74..3bef44d1b0 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -1,5 +1,5 @@ -r _.txt -pylint~=2.17.1 +pylint~=2.17.2 pytest~=7.2.2 pytest-asyncio~=0.21.0 # pytest-order~=1.0.1 From e10e8807ba61a89bec285dc169541e8d74c4fb50 Mon Sep 17 00:00:00 2001 From: ItsRqtl Date: Tue, 4 Apr 2023 21:04:26 -0700 Subject: [PATCH 30/67] fix: add None support for ClientUser edit (#1994) --- CHANGELOG.md | 2 ++ discord/user.py | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 951baa9f2e..246eb82abe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,8 @@ These changes are available on the `master` branch, but have not yet been releas - Fixed `AttributeError` caused by [#1957](https://github.com/Pycord-Development/pycord/pull/1957) when using listeners in cogs. ([#1989](https://github.com/Pycord-Development/pycord/pull/1989)) +- Fixed `None` being handled incorrectly for avatar in `ClientUser.edit`. + ([#1994](https://github.com/Pycord-Development/pycord/pull/1994)) - Fixed scheduled events breaking when changing the location from external to a channel. ([#1998](https://github.com/Pycord-Development/pycord/pull/1998)) - Fixed `TypeError` being raised when passing `name` argument to bridge groups. diff --git a/discord/user.py b/discord/user.py index 6a322f9800..540032f0b9 100644 --- a/discord/user.py +++ b/discord/user.py @@ -404,7 +404,9 @@ async def edit( if username is not MISSING: payload["username"] = username - if avatar is not MISSING: + if avatar is None: + payload["avatar"] = None + elif avatar is not MISSING: payload["avatar"] = _bytes_to_base64_data(avatar) data: UserPayload = await self._state.http.edit_profile(payload) From 6824de659cb4b5200a9e63b2d2975d781caf6c42 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Apr 2023 03:57:21 +0200 Subject: [PATCH 31/67] chore(deps-dev): Update mypy requirement from ~=1.1.1 to ~=1.2.0 (#2005) Updates the requirements on [mypy](https://github.com/python/mypy) to permit the latest version. - [Release notes](https://github.com/python/mypy/releases) - [Commits](https://github.com/python/mypy/compare/v1.1.1...v1.2.0) --- updated-dependencies: - dependency-name: mypy dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/dev.txt b/requirements/dev.txt index 3bef44d1b0..4514c2945b 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -3,7 +3,7 @@ pylint~=2.17.2 pytest~=7.2.2 pytest-asyncio~=0.21.0 # pytest-order~=1.0.1 -mypy~=1.1.1 +mypy~=1.2.0 coverage~=7.2 pre-commit==3.2.0 codespell==2.2.4 From 5b1c15c615e84f6cebf3622948a8384ffd974daf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Apr 2023 01:32:14 -0400 Subject: [PATCH 32/67] chore(deps-dev): Bump pre-commit from 3.2.0 to 3.2.2 (#2003) Bumps [pre-commit](https://github.com/pre-commit/pre-commit) from 3.2.0 to 3.2.2. - [Release notes](https://github.com/pre-commit/pre-commit/releases) - [Changelog](https://github.com/pre-commit/pre-commit/blob/main/CHANGELOG.md) - [Commits](https://github.com/pre-commit/pre-commit/compare/v3.2.0...v3.2.2) --- updated-dependencies: - dependency-name: pre-commit dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/dev.txt b/requirements/dev.txt index 4514c2945b..ebdac009a5 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -5,7 +5,7 @@ pytest-asyncio~=0.21.0 # pytest-order~=1.0.1 mypy~=1.2.0 coverage~=7.2 -pre-commit==3.2.0 +pre-commit==3.2.2 codespell==2.2.4 bandit==1.7.4 flake8==6.0.0 From fa0f16030eba9c2b708419a89d57f1d33882659c Mon Sep 17 00:00:00 2001 From: Lacosst0 <68904262+Lacosst0@users.noreply.github.com> Date: Sun, 9 Apr 2023 00:44:31 +0400 Subject: [PATCH 33/67] docs: fix typo in .send docstring (#2007) Fix Typo slient -> silent Signed-off-by: Lacosst0 <68904262+Lacosst0@users.noreply.github.com> --- discord/abc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/discord/abc.py b/discord/abc.py index 027ba96b18..5aa94840eb 100644 --- a/discord/abc.py +++ b/discord/abc.py @@ -1481,7 +1481,7 @@ async def send( .. versionadded:: 2.0 suppress: :class:`bool` Whether to suppress embeds for the message. - slient: :class:`bool` + silent: :class:`bool` Whether to suppress push and desktop notifications for the message. .. versionadded:: 2.4 From e66dd97a08a5f3f2f810506376165010e5284f3a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 14 Apr 2023 08:08:30 -0500 Subject: [PATCH 34/67] chore(deps): Bump sphinxext-opengraph from 0.8.1 to 0.8.2 (#2013) Bumps [sphinxext-opengraph](https://github.com/wpilibsuite/sphinxext-opengraph) from 0.8.1 to 0.8.2. - [Release notes](https://github.com/wpilibsuite/sphinxext-opengraph/releases) - [Commits](https://github.com/wpilibsuite/sphinxext-opengraph/compare/v0.8.1...v0.8.2) --- updated-dependencies: - dependency-name: sphinxext-opengraph dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/docs.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/docs.txt b/requirements/docs.txt index fdc9d77afa..6783abad85 100644 --- a/requirements/docs.txt +++ b/requirements/docs.txt @@ -2,7 +2,7 @@ sphinx==5.3.0 sphinxcontrib_trio==1.1.2 sphinxcontrib-websupport==1.2.4 myst-parser==1.0.0 -sphinxext-opengraph==0.8.1 +sphinxext-opengraph==0.8.2 sphinx-copybutton==0.5.1 furo@ git+https://github.com/pradyunsg/furo@193643f sphinx-autodoc-typehints==1.22 From 43b0e8657df8fa4a5dac73d2280821b64937133d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 14 Apr 2023 08:10:14 -0500 Subject: [PATCH 35/67] chore(pre-commit): pre-commit autoupdate (#2001) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/psf/black: 23.1.0 → 23.3.0](https://github.com/psf/black/compare/23.1.0...23.3.0) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 23eddd57ff..3005b95cbe 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,7 +27,7 @@ repos: hooks: - id: isort - repo: https://github.com/psf/black - rev: 23.1.0 + rev: 23.3.0 hooks: - id: black args: [--safe, --quiet] From 39b61c29dd85f38c113d802fc905323ffa229d56 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 14 Apr 2023 08:11:58 -0500 Subject: [PATCH 36/67] chore(deps): Bump sphinx-autodoc-typehints from 1.22 to 1.23.0 (#2012) Bumps [sphinx-autodoc-typehints](https://github.com/tox-dev/sphinx-autodoc-typehints) from 1.22 to 1.23.0. - [Release notes](https://github.com/tox-dev/sphinx-autodoc-typehints/releases) - [Changelog](https://github.com/tox-dev/sphinx-autodoc-typehints/blob/main/CHANGELOG.md) - [Commits](https://github.com/tox-dev/sphinx-autodoc-typehints/compare/1.22...1.23.0) --- updated-dependencies: - dependency-name: sphinx-autodoc-typehints dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/docs.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/docs.txt b/requirements/docs.txt index 6783abad85..bed7e3a03c 100644 --- a/requirements/docs.txt +++ b/requirements/docs.txt @@ -5,4 +5,4 @@ myst-parser==1.0.0 sphinxext-opengraph==0.8.2 sphinx-copybutton==0.5.1 furo@ git+https://github.com/pradyunsg/furo@193643f -sphinx-autodoc-typehints==1.22 +sphinx-autodoc-typehints==1.23.0 From 77d77e64ee48e06399727d955b507b455d17906d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 14 Apr 2023 08:12:14 -0500 Subject: [PATCH 37/67] chore(deps-dev): Update pytest requirement from ~=7.2.2 to ~=7.3.0 (#2009) Updates the requirements on [pytest](https://github.com/pytest-dev/pytest) to permit the latest version. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/7.2.2...7.3.0) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/dev.txt b/requirements/dev.txt index ebdac009a5..f08aa1be5a 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -1,6 +1,6 @@ -r _.txt pylint~=2.17.2 -pytest~=7.2.2 +pytest~=7.3.0 pytest-asyncio~=0.21.0 # pytest-order~=1.0.1 mypy~=1.2.0 From 0e2277f6c78a861b326dbb2339251dbaa5a60118 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Apr 2023 08:10:55 -0500 Subject: [PATCH 38/67] chore(deps): Bump sphinx-copybutton from 0.5.1 to 0.5.2 (#2018) Bumps [sphinx-copybutton](https://github.com/executablebooks/sphinx-copybutton) from 0.5.1 to 0.5.2. - [Release notes](https://github.com/executablebooks/sphinx-copybutton/releases) - [Changelog](https://github.com/executablebooks/sphinx-copybutton/blob/master/CHANGELOG.md) - [Commits](https://github.com/executablebooks/sphinx-copybutton/compare/v0.5.1...v0.5.2) --- updated-dependencies: - dependency-name: sphinx-copybutton dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/docs.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/docs.txt b/requirements/docs.txt index bed7e3a03c..453c4fcf7b 100644 --- a/requirements/docs.txt +++ b/requirements/docs.txt @@ -3,6 +3,6 @@ sphinxcontrib_trio==1.1.2 sphinxcontrib-websupport==1.2.4 myst-parser==1.0.0 sphinxext-opengraph==0.8.2 -sphinx-copybutton==0.5.1 +sphinx-copybutton==0.5.2 furo@ git+https://github.com/pradyunsg/furo@193643f sphinx-autodoc-typehints==1.23.0 From 2ac951fa05fc973d581f27131b737f68823eee86 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Apr 2023 08:11:15 -0500 Subject: [PATCH 39/67] chore(deps-dev): Update pytest requirement from ~=7.3.0 to ~=7.3.1 (#2017) Updates the requirements on [pytest](https://github.com/pytest-dev/pytest) to permit the latest version. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/7.3.0...7.3.1) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/dev.txt b/requirements/dev.txt index f08aa1be5a..696ec91da3 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -1,6 +1,6 @@ -r _.txt pylint~=2.17.2 -pytest~=7.3.0 +pytest~=7.3.1 pytest-asyncio~=0.21.0 # pytest-order~=1.0.1 mypy~=1.2.0 From eb4fd12eda4f0236532e7b4e2ee71dc5a6bc65d0 Mon Sep 17 00:00:00 2001 From: JustaSqu1d Date: Mon, 17 Apr 2023 08:44:00 -0700 Subject: [PATCH 40/67] chore: update file upload size limit (#2014) * chore: update file upload size limit * docs: add changelog entry * docs: fix formatting in earlier changelog entry * docs: add pull request number --------- Co-authored-by: plun1331 <49261529+plun1331@users.noreply.github.com> --- CHANGELOG.md | 7 ++++++- discord/guild.py | 6 +++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 246eb82abe..ff67a173db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,10 +22,15 @@ These changes are available on the `master` branch, but have not yet been releas - Added support for one-time event listeners in `@client.listen()`. ([#1957](https://github.com/Pycord-Development/pycord/pull/1957)) - Added `current_page` argument to Paginator.update(). - ([#1983](https://github.com/Pycord-Development/pycord/pull/1983) + ([#1983](https://github.com/Pycord-Development/pycord/pull/1983)) - Added new `application_auto_moderation_rule_create_badge` to `ApplicationFlags`. ([#1992](https://github.com/Pycord-Development/pycord/pull/1992)) +### Changed + +- Changed file-upload size limit from 8 MB to 25 MB accordingly. + ([#2014](https://github.com/Pycord-Development/pycord/pull/2014)) + ### Removed - Removed `@client.once()` in favour of `@client.listen(once=True)`. diff --git a/discord/guild.py b/discord/guild.py index 067f71ed39..a84f0d2eba 100644 --- a/discord/guild.py +++ b/discord/guild.py @@ -324,9 +324,9 @@ class Guild(Hashable): ) _PREMIUM_GUILD_LIMITS: ClassVar[dict[int | None, _GuildLimit]] = { - None: _GuildLimit(emoji=50, stickers=5, bitrate=96e3, filesize=8388608), - 0: _GuildLimit(emoji=50, stickers=5, bitrate=96e3, filesize=8388608), - 1: _GuildLimit(emoji=100, stickers=15, bitrate=128e3, filesize=8388608), + None: _GuildLimit(emoji=50, stickers=5, bitrate=96e3, filesize=26214400), + 0: _GuildLimit(emoji=50, stickers=5, bitrate=96e3, filesize=26214400), + 1: _GuildLimit(emoji=100, stickers=15, bitrate=128e3, filesize=26214400), 2: _GuildLimit(emoji=150, stickers=30, bitrate=256e3, filesize=52428800), 3: _GuildLimit(emoji=250, stickers=60, bitrate=384e3, filesize=104857600), } From f5e780a028068dd11df1d2f85178c1845d495407 Mon Sep 17 00:00:00 2001 From: BobDotCom <71356958+BobDotCom@users.noreply.github.com> Date: Mon, 17 Apr 2023 10:54:49 -0500 Subject: [PATCH 41/67] chore(docs): revert removal of custom search scoring (#2019) Signed-off-by: Lala Sabathil Co-authored-by: Lala Sabathil Co-authored-by: plun1331 <49261529+plun1331@users.noreply.github.com> --- docs/_static/js/scorer.js | 82 +++++++++++++++++++++++++++++++++++++++ docs/conf.py | 2 +- 2 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 docs/_static/js/scorer.js diff --git a/docs/_static/js/scorer.js b/docs/_static/js/scorer.js new file mode 100644 index 0000000000..a0f50cb083 --- /dev/null +++ b/docs/_static/js/scorer.js @@ -0,0 +1,82 @@ +"use-strict"; + +let queryBeingDone = null; +let pattern = null; + +const escapedRegex = /[-\/\\^$*+?.()|[\]{}]/g; +function escapeRegex(e) { + return e.replace(escapedRegex, "\\$&"); +} + +// for some reason Sphinx shows some entries twice +// if something has been scored already I'd rather sort it to the bottom +const beenScored = new Set(); + +function __score(haystack, regex) { + let match = regex.exec(haystack); + if (match == null) { + return Number.MAX_VALUE; + } + let subLength = match[0].length; + let start = match.index; + return (subLength * 1000 + start) / 1000.0; +} + +// unused for now +function __cleanNamespaces(query) { + return query.replace(/(discord\.(ext\.)?)?(.+)/, "$3"); +} + +Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [filename, title, anchor, descr, score] + // and returns the new score. + score: (result) => { + // only inflate the score of things that are actual API reference things + const [, title, , , score] = result; + + if (pattern !== null && title.startsWith("discord.")) { + let _score = __score(title, pattern); + if (_score === Number.MAX_VALUE) { + return score; + } + if (beenScored.has(title)) { + return 0; + } + beenScored.add(title); + let newScore = 100 + queryBeingDone.length - _score; + // console.log(`${title}: ${score} -> ${newScore} (${_score})`); + return newScore; + } + return score; + }, + + // query matches the full name of an object + objNameMatch: 15, + // or matches in the last dotted part of the object name + objPartialMatch: 11, + // Additive scores depending on the priority of the object + objPrio: { + 0: 15, // used to be importantResults + 1: 7, // used to be objectResults + 2: -5, // used to be unimportantResults + }, + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + partialTitle: 7, + // query found in terms + term: 5, + partialTerm: 2, +}; + +document.addEventListener("DOMContentLoaded", () => { + const params = new URLSearchParams(window.location.search); + queryBeingDone = params.get("q"); + if (queryBeingDone) { + let pattern = Array.from(queryBeingDone).map(escapeRegex).join(".*?"); + pattern = new RegExp(pattern, "i"); + } +}); diff --git a/docs/conf.py b/docs/conf.py index ab87ced36b..38958e6066 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -380,7 +380,7 @@ def write_new(): # The name of a javascript file (relative to the configuration directory) that # implements a search results scorer. If empty, the default will be used. -# html_search_scorer = "_static/scorer.js" +html_search_scorer = "_static/js/scorer.js" # html_js_files = ["custom.js", "settings.js", "copy.js", "sidebar.js"] From 4584bec9b143d4be7da715ba2696651be266c04c Mon Sep 17 00:00:00 2001 From: Middledot <78228142+Middledot@users.noreply.github.com> Date: Mon, 17 Apr 2023 12:07:08 -0400 Subject: [PATCH 42/67] fix(ext.bridge): Bridge options & bool converter breaking sometimes (#1999) * fix(ext.bridge): bool opt breaks sometimes * chore(changelog): changelog * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Signed-off-by: Middledot <78228142+Middledot@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: BobDotCom <71356958+BobDotCom@users.noreply.github.com> --- CHANGELOG.md | 2 ++ discord/ext/bridge/core.py | 8 +++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff67a173db..b7e6fc3126 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,6 +45,8 @@ These changes are available on the `master` branch, but have not yet been releas ([#1994](https://github.com/Pycord-Development/pycord/pull/1994)) - Fixed scheduled events breaking when changing the location from external to a channel. ([#1998](https://github.com/Pycord-Development/pycord/pull/1998)) +- Fixed boolean converter breaking for bridge commands. Fix bridge command Options not + working. ([#1999](https://github.com/Pycord-Development/pycord/pull/1999)) - Fixed `TypeError` being raised when passing `name` argument to bridge groups. ([#2000](https://github.com/Pycord-Development/pycord/pull/2000)) diff --git a/discord/ext/bridge/core.py b/discord/ext/bridge/core.py index 8c9a69d265..4f53389d05 100644 --- a/discord/ext/bridge/core.py +++ b/discord/ext/bridge/core.py @@ -532,10 +532,15 @@ async def convert(self, ctx: Context, arg: str): return attach +class BooleanConverter(Converter): + async def convert(self, ctx, arg: bool): + return _convert_to_bool(str(arg)) + + BRIDGE_CONVERTER_MAPPING = { SlashCommandOptionType.string: str, SlashCommandOptionType.integer: int, - SlashCommandOptionType.boolean: lambda val: _convert_to_bool(str(val)), + SlashCommandOptionType.boolean: BooleanConverter, SlashCommandOptionType.user: UserConverter, SlashCommandOptionType.channel: GuildChannelConverter, SlashCommandOptionType.role: RoleConverter, @@ -579,3 +584,4 @@ async def convert(self, ctx, argument: str) -> Any: discord.commands.options.Option = BridgeOption +discord.Option = BridgeOption From 8fb956c0d64ef47fda1a2f2c297c09b6967b0391 Mon Sep 17 00:00:00 2001 From: Om <92863779+Om1609@users.noreply.github.com> Date: Tue, 18 Apr 2023 07:10:57 +0530 Subject: [PATCH 43/67] feat: suppress FFMPEG output (#1993) * supress ffmpeg output * Update CHANGELOG.md * Update CHANGELOG.md Co-authored-by: plun1331 <49261529+plun1331@users.noreply.github.com> Signed-off-by: Om <92863779+Om1609@users.noreply.github.com> --------- Signed-off-by: Om <92863779+Om1609@users.noreply.github.com> Co-authored-by: plun1331 <49261529+plun1331@users.noreply.github.com> Co-authored-by: Lala Sabathil --- CHANGELOG.md | 5 +++++ discord/sinks/m4a.py | 2 ++ discord/sinks/mka.py | 2 ++ discord/sinks/mkv.py | 2 ++ discord/sinks/mp3.py | 2 ++ discord/sinks/mp4.py | 2 ++ discord/sinks/ogg.py | 2 ++ 7 files changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b7e6fc3126..c4434ec0d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,11 @@ These changes are available on the `master` branch, but have not yet been releas - Removed `@client.once()` in favour of `@client.listen(once=True)`. ([#1957](https://github.com/Pycord-Development/pycord/pull/1957)) +### Changed + +- Suppressed FFMPEG output when recording voice channels. + ([#1993](https://github.com/Pycord-Development/pycord/pull/1993)) + ### Fixed - Fixed `AttributeError` caused by diff --git a/discord/sinks/m4a.py b/discord/sinks/m4a.py index 497a22225f..6b65e3653c 100644 --- a/discord/sinks/m4a.py +++ b/discord/sinks/m4a.py @@ -67,6 +67,8 @@ def format_audio(self, audio): "s16le", "-ar", "48000", + "-loglevel", + "error", "-ac", "2", "-i", diff --git a/discord/sinks/mka.py b/discord/sinks/mka.py index 830954a9d3..819608d368 100644 --- a/discord/sinks/mka.py +++ b/discord/sinks/mka.py @@ -64,6 +64,8 @@ def format_audio(self, audio): "s16le", "-ar", "48000", + "-loglevel", + "error", "-ac", "2", "-i", diff --git a/discord/sinks/mkv.py b/discord/sinks/mkv.py index e1ed4ca78e..2071c1ae4f 100644 --- a/discord/sinks/mkv.py +++ b/discord/sinks/mkv.py @@ -64,6 +64,8 @@ def format_audio(self, audio): "s16le", "-ar", "48000", + "-loglevel", + "error", "-ac", "2", "-i", diff --git a/discord/sinks/mp3.py b/discord/sinks/mp3.py index 96fa8a562d..c4707eb5ed 100644 --- a/discord/sinks/mp3.py +++ b/discord/sinks/mp3.py @@ -64,6 +64,8 @@ def format_audio(self, audio): "s16le", "-ar", "48000", + "-loglevel", + "error", "-ac", "2", "-i", diff --git a/discord/sinks/mp4.py b/discord/sinks/mp4.py index 3168452e47..9f540c6c29 100644 --- a/discord/sinks/mp4.py +++ b/discord/sinks/mp4.py @@ -67,6 +67,8 @@ def format_audio(self, audio): "s16le", "-ar", "48000", + "-loglevel", + "error", "-ac", "2", "-i", diff --git a/discord/sinks/ogg.py b/discord/sinks/ogg.py index 759b97d53a..09abcfc402 100644 --- a/discord/sinks/ogg.py +++ b/discord/sinks/ogg.py @@ -64,6 +64,8 @@ def format_audio(self, audio): "s16le", "-ar", "48000", + "-loglevel", + "error", "-ac", "2", "-i", From f553fdebe7abefb8e4bbfa7000c5a3f9bd2b3969 Mon Sep 17 00:00:00 2001 From: David Hozic Date: Tue, 18 Apr 2023 03:54:31 +0200 Subject: [PATCH 44/67] feat: add new parameters to ``discord.Embed`` (#1996) * Embed - add parameters * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Changelog * Fixed spelling * spelling * 'The' * Resolve comments * EmbedAuthor, EmbedFooter as return types * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: plun1331 <49261529+plun1331@users.noreply.github.com> Co-authored-by: Lala Sabathil --- CHANGELOG.md | 2 + discord/embeds.py | 86 ++++++++++++++++++++++++++++++++++++--- docs/api/data_classes.rst | 12 ++++++ 3 files changed, 95 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4434ec0d0..e95d08c840 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ These changes are available on the `master` branch, but have not yet been releas ### Added +- Added new parameters (`author`, `footer`, `image`, `thumbnail`) to `discord.Embed`. + ([#1996](https://github.com/Pycord-Development/pycord/pull/1996)) - Added new events `on_bridge_command`, `on_bridge_command_completion`, and `on_bridge_command_error`. ([#1916](https://github.com/Pycord-Development/pycord/pull/1916)) diff --git a/discord/embeds.py b/discord/embeds.py index ca3a9c5e72..1d6a7d11f2 100644 --- a/discord/embeds.py +++ b/discord/embeds.py @@ -34,6 +34,8 @@ __all__ = ( "Embed", "EmbedField", + "EmbedAuthor", + "EmbedFooter", ) @@ -62,7 +64,7 @@ def __repr__(self) -> str: inner = ", ".join( (f"{k}={v!r}" for k, v in self.__dict__.items() if not k.startswith("_")) ) - return f"EmbedProxy({inner})" + return f"{type(self).__name__}({inner})" def __getattr__(self, attr: str) -> _EmptyEmbed: return EmptyEmbed @@ -103,6 +105,64 @@ class _EmbedAuthorProxy(Protocol): proxy_icon_url: MaybeEmpty[str] +class EmbedAuthor(EmbedProxy): + """Represents the author on the :class:`Embed` object. + + .. versionadded:: 2.5 + + Attributes + ---------- + name: :class:`str` + The name of the author. + url: :class:`str` + The URL of the hyperlink created in the author's name. + icon_url: :class:`str` + The URL of the author icon image. + """ + + def __init__( + self, + name: str, + url: MaybeEmpty[str] = EmptyEmbed, + icon_url: MaybeEmpty[str] = EmptyEmbed, + proxy_icon_url: MaybeEmpty[str] = EmptyEmbed, + ) -> None: + layer = { + k: v + for k, v in locals().items() + if k in {"name", "url", "icon_url", "proxy_icon_url"} + and v is not EmptyEmbed + } + super().__init__(layer) + + +class EmbedFooter(EmbedProxy): + """Represents the footer on the :class:`Embed` object. + + .. versionadded:: 2.5 + + Attributes + ---------- + text: :class:`str` + The text inside the footer. + icon_url: :class:`str` + The URL of the footer icon image. + """ + + def __init__( + self, + text: str, + icon_url: MaybeEmpty[str] = EmptyEmbed, + proxy_icon_url: MaybeEmpty[str] = EmptyEmbed, + ) -> None: + layer = { + k: v + for k, v in locals().items() + if k in {"text", "icon_url", "proxy_icon_url"} and v is not EmptyEmbed + } + super().__init__(layer) + + class EmbedField: """Represents a field on the :class:`Embed` object. @@ -246,6 +306,10 @@ def __init__( description: MaybeEmpty[Any] = EmptyEmbed, timestamp: datetime.datetime = None, fields: list[EmbedField] | None = None, + author: MaybeEmpty[EmbedAuthor] = EmptyEmbed, + footer: MaybeEmpty[EmbedFooter] = EmptyEmbed, + image: MaybeEmpty[str] = EmptyEmbed, + thumbnail: MaybeEmpty[str] = EmptyEmbed, ): self.colour = colour if colour is not EmptyEmbed else color self.title = title @@ -266,6 +330,18 @@ def __init__( self.timestamp = timestamp self._fields: list[EmbedField] = fields or [] + if author is not EmptyEmbed: + self.set_author(**author.__dict__) + + if footer is not EmptyEmbed: + self.set_footer(**footer.__dict__) + + if image is not EmptyEmbed: + self.set_image(url=image) + + if thumbnail is not EmptyEmbed: + self.set_thumbnail(url=thumbnail) + @classmethod def from_dict(cls: type[E], data: Mapping[str, Any]) -> E: """Converts a :class:`dict` to a :class:`Embed` provided it is in the @@ -426,14 +502,14 @@ def timestamp(self, value: MaybeEmpty[datetime.datetime]): ) @property - def footer(self) -> _EmbedFooterProxy: + def footer(self) -> EmbedFooter: """Returns an ``EmbedProxy`` denoting the footer contents. See :meth:`set_footer` for possible values you can access. If the attribute has no value then :attr:`Empty` is returned. """ - return EmbedProxy(getattr(self, "_footer", {})) # type: ignore + return EmbedFooter(**getattr(self, "_footer", {})) def set_footer( self: E, @@ -618,14 +694,14 @@ def provider(self) -> _EmbedProviderProxy: return EmbedProxy(getattr(self, "_provider", {})) # type: ignore @property - def author(self) -> _EmbedAuthorProxy: + def author(self) -> EmbedAuthor: """Returns an ``EmbedProxy`` denoting the author contents. See :meth:`set_author` for possible values you can access. If the attribute has no value then :attr:`Empty` is returned. """ - return EmbedProxy(getattr(self, "_author", {})) # type: ignore + return EmbedAuthor(**getattr(self, "_author", {})) # type: ignore def set_author( self: E, diff --git a/docs/api/data_classes.rst b/docs/api/data_classes.rst index 236aa64851..f05b38d646 100644 --- a/docs/api/data_classes.rst +++ b/docs/api/data_classes.rst @@ -72,6 +72,18 @@ Embed .. autoclass:: EmbedField :members: +.. attributetable:: EmbedAuthor + +.. autoclass:: EmbedAuthor + :members: + + +.. attributetable:: EmbedFooter + +.. autoclass:: EmbedFooter + :members: + + Flags ----- From 8a913c3b66254ce6201b35144aa3ba596fca5e8b Mon Sep 17 00:00:00 2001 From: Snawe Date: Tue, 18 Apr 2023 05:55:09 +0200 Subject: [PATCH 45/67] feat: Add possibility to start bot via async context manager (#1801) * feat: Add possibility to start bot via async context manager * fix: Add type hints to __aexit__ * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * doc: Add async context manager to changelog * example: Add example to start bot with async context manager Add basic example to start the bot with an async context manager. The example contains a `/hello` slash command which responds with a "Hellp @author". * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Signed-off-by: Lala Sabathil Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Lala Sabathil --- CHANGELOG.md | 2 ++ discord/client.py | 22 ++++++++++++++++++++++ examples/basic_async_bot.py | 29 +++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 examples/basic_async_bot.py diff --git a/CHANGELOG.md b/CHANGELOG.md index e95d08c840..0a6293f50e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ These changes are available on the `master` branch, but have not yet been releas ### Added +- Added possibility to start bot via async context manager. + ([#1801](https://github.com/Pycord-Development/pycord/pull/1801)) - Added new parameters (`author`, `footer`, `image`, `thumbnail`) to `discord.Embed`. ([#1996](https://github.com/Pycord-Development/pycord/pull/1996)) - Added new events `on_bridge_command`, `on_bridge_command_completion`, and diff --git a/discord/client.py b/discord/client.py index 654219a0bd..27e94d7c2f 100644 --- a/discord/client.py +++ b/discord/client.py @@ -30,6 +30,7 @@ import signal import sys import traceback +from types import TracebackType from typing import TYPE_CHECKING, Any, Callable, Coroutine, Generator, Sequence, TypeVar import aiohttp @@ -253,6 +254,27 @@ def __init__( VoiceClient.warn_nacl = False _log.warning("PyNaCl is not installed, voice will NOT be supported") + async def __aenter__(self) -> Client: + loop = asyncio.get_running_loop() + self.loop = loop + self.http.loop = loop + self._connection.loop = loop + + self._ready = asyncio.Event() + + return self + + async def __aexit__( + self, + exc_t: BaseException | None, + exc_v: BaseException | None, + exc_tb: TracebackType | None, + ) -> None: + if not self.is_closed(): + await self.close() + + # internals + def _get_websocket( self, guild_id: int | None = None, *, shard_id: int | None = None ) -> DiscordWebSocket: diff --git a/examples/basic_async_bot.py b/examples/basic_async_bot.py new file mode 100644 index 0000000000..a72859fb37 --- /dev/null +++ b/examples/basic_async_bot.py @@ -0,0 +1,29 @@ +import asyncio + +import discord +from discord.ext import commands + +bot = commands.Bot( + command_prefix=commands.when_mentioned_or("!"), + intents=discord.Intents.default(), +) + + +@bot.event +async def on_ready(): + print(f"Logged in as {bot.user} (ID: {bot.user.id})") + print("------") + + +@bot.slash_command(guild_ids=[...]) # Create a slash command. +async def hello(ctx: discord.ApplicationContext): + """Say hello to the bot""" # The command description can be supplied as the docstring + await ctx.respond(f"Hello {ctx.author.mention}!") + + +async def main(): + async with bot: + await bot.start("TOKEN") + + +asyncio.run(main()) From ceff3a4f96bd83a89ccc5318e54fdcb941dc555c Mon Sep 17 00:00:00 2001 From: Om <92863779+Om1609@users.noreply.github.com> Date: Tue, 18 Apr 2023 09:34:57 +0530 Subject: [PATCH 46/67] fix: store message in view when sent using webhook or when message is edited (#1997) * store message on view.py Signed-off-by: Om <92863779+Om1609@users.noreply.github.com> * Update CHANGELOG.md Signed-off-by: Om <92863779+Om1609@users.noreply.github.com> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * updates * Update CHANGELOG.md Co-authored-by: plun1331 <49261529+plun1331@users.noreply.github.com> Signed-off-by: Om <92863779+Om1609@users.noreply.github.com> --------- Signed-off-by: Om <92863779+Om1609@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: plun1331 <49261529+plun1331@users.noreply.github.com> Co-authored-by: Lala Sabathil --- CHANGELOG.md | 3 +++ discord/interactions.py | 2 ++ discord/message.py | 2 ++ discord/webhook/async_.py | 2 ++ 4 files changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a6293f50e..27fdbe7acf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,6 +50,9 @@ These changes are available on the `master` branch, but have not yet been releas - Fixed `AttributeError` caused by [#1957](https://github.com/Pycord-Development/pycord/pull/1957) when using listeners in cogs. ([#1989](https://github.com/Pycord-Development/pycord/pull/1989)) +- Fixed `View.message` not being set when view is sent using webhooks, including + `Interaction.followup.send` or when a message is edited. + ([#1997](https://github.com/Pycord-Development/pycord/pull/1997)) - Fixed `None` being handled incorrectly for avatar in `ClientUser.edit`. ([#1994](https://github.com/Pycord-Development/pycord/pull/1994)) - Fixed scheduled events breaking when changing the location from external to a channel. diff --git a/discord/interactions.py b/discord/interactions.py index 462d613374..2cd4b740b8 100644 --- a/discord/interactions.py +++ b/discord/interactions.py @@ -440,6 +440,7 @@ async def edit_original_response( state = _InteractionMessageState(self, self._state) message = InteractionMessage(state=state, channel=self.channel, data=data) # type: ignore if view and not view.is_finished(): + view.message = message self._state.store_view(view, message.id) if delete_after is not None: @@ -976,6 +977,7 @@ async def edit_message( file.close() if view and not view.is_finished(): + view.message = msg state.store_view(view, message_id) self._responded = True diff --git a/discord/message.py b/discord/message.py index 69c7a79753..77193b2920 100644 --- a/discord/message.py +++ b/discord/message.py @@ -1468,6 +1468,7 @@ async def edit( message = Message(state=self._state, channel=self.channel, data=data) if view and not view.is_finished(): + view.message = message self._state.store_view(view, self.id) if delete_after is not None: @@ -2021,5 +2022,6 @@ async def edit(self, **fields: Any) -> Message | None: # data isn't unbound msg = self._state.create_message(channel=self.channel, data=data) # type: ignore if view and not view.is_finished(): + view.message = msg self._state.store_view(view, self.id) return msg diff --git a/discord/webhook/async_.py b/discord/webhook/async_.py index 08b77a1b8c..b12c2b0007 100644 --- a/discord/webhook/async_.py +++ b/discord/webhook/async_.py @@ -1762,6 +1762,7 @@ async def send( 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 self._state.store_view(view, message_id) if delete_after is not None: @@ -1957,6 +1958,7 @@ async def edit_message( message = self._create_message(data) if view and not view.is_finished(): + view.message = message self._state.store_view(view, message_id) return message From 72f89669ba223afefe59d8ad83b3c29f831cbf09 Mon Sep 17 00:00:00 2001 From: BobDotCom <71356958+BobDotCom@users.noreply.github.com> Date: Tue, 18 Apr 2023 09:44:43 -0500 Subject: [PATCH 47/67] chore(pre-commit): add autofix_commit_msg config Signed-off-by: BobDotCom <71356958+BobDotCom@users.noreply.github.com> --- .pre-commit-config.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3005b95cbe..4f51e49c19 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,5 +1,6 @@ ci: autoupdate_commit_msg: "chore(pre-commit): pre-commit autoupdate" + autofix_commit_msg: "style(pre-commit): auto fixes from pre-commit.com hooks" repos: - repo: https://github.com/pre-commit/pre-commit-hooks From 0407f2893b8e7c8f764bf62eb224d53796eec1ba Mon Sep 17 00:00:00 2001 From: qoft <63415260+qoft@users.noreply.github.com> Date: Tue, 18 Apr 2023 15:21:58 -0400 Subject: [PATCH 48/67] fix: webhook message editing on forums missing thread_id (#1981) * Fixed webhook message editing on forums. * Update async_.py * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Added changelog * style(pre-commit): auto fixes from pre-commit.com hooks --------- Signed-off-by: Lala Sabathil Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Lala Sabathil --- CHANGELOG.md | 2 ++ discord/webhook/async_.py | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 27fdbe7acf..0e65373326 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,6 +50,8 @@ These changes are available on the `master` branch, but have not yet been releas - Fixed `AttributeError` caused by [#1957](https://github.com/Pycord-Development/pycord/pull/1957) when using listeners in cogs. ([#1989](https://github.com/Pycord-Development/pycord/pull/1989)) +- Editing a webhook message if the thread is a forum post or if the thread is a private + thread ([#1981](https://github.com/Pycord-Development/pycord/pull/1981)) - Fixed `View.message` not being set when view is sent using webhooks, including `Interaction.followup.send` or when a message is edited. ([#1997](https://github.com/Pycord-Development/pycord/pull/1997)) diff --git a/discord/webhook/async_.py b/discord/webhook/async_.py index b12c2b0007..8c73681ac1 100644 --- a/discord/webhook/async_.py +++ b/discord/webhook/async_.py @@ -38,7 +38,7 @@ from .. import utils from ..asset import Asset -from ..channel import PartialMessageable +from ..channel import ForumChannel, PartialMessageable from ..enums import WebhookType, try_enum from ..errors import ( DiscordServerError, @@ -892,6 +892,8 @@ async def edit( thread = Object(self._thread_id) elif isinstance(self.channel, Thread): thread = Object(self.channel.id) + elif isinstance(self.channel, ForumChannel): + thread = Object(self.id) if attachments is MISSING: attachments = self.attachments or MISSING From a8ce1257ab72905f994647943f001cd0476695cd Mon Sep 17 00:00:00 2001 From: UK <41271523+NeloBlivion@users.noreply.github.com> Date: Tue, 25 Apr 2023 15:39:55 +0100 Subject: [PATCH 49/67] feat: Add custom_message to AutoModActionMetadata and fix TypeError on AutoModRule (#2029) * Automod fixes and additions * style(pre-commit): auto fixes from pre-commit.com hooks --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- discord/automod.py | 19 ++++++++++++++++++- discord/types/automod.py | 1 + 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/discord/automod.py b/discord/automod.py index 5f091d0f65..2d6b5244da 100644 --- a/discord/automod.py +++ b/discord/automod.py @@ -76,6 +76,10 @@ class AutoModActionMetadata: timeout_duration: :class:`datetime.timedelta` How long the member that triggered the action should be timed out for. Only for actions of type :attr:`AutoModActionType.timeout`. + custom_message: :class:`str` + An additional message shown to members when their message is blocked. + Maximum 150 characters. + Only for actions of type :attr:`AutoModActionType.block_message`. """ # maybe add a table of action types and attributes? @@ -83,13 +87,18 @@ class AutoModActionMetadata: __slots__ = ( "channel_id", "timeout_duration", + "custom_message", ) def __init__( - self, channel_id: int = MISSING, timeout_duration: timedelta = MISSING + self, + channel_id: int = MISSING, + timeout_duration: timedelta = MISSING, + custom_message: str = MISSING, ): self.channel_id: int = channel_id self.timeout_duration: timedelta = timeout_duration + self.custom_message: str = custom_message def to_dict(self) -> dict: data = {} @@ -100,6 +109,9 @@ def to_dict(self) -> dict: if self.timeout_duration is not MISSING: data["duration_seconds"] = self.timeout_duration.total_seconds() + if self.custom_message is not MISSING: + data["custom_message"] = self.custom_message + return data @classmethod @@ -113,12 +125,16 @@ def from_dict(cls, data: AutoModActionMetadataPayload): # might need an explicit int cast kwargs["timeout_duration"] = timedelta(seconds=duration_seconds) + if (custom_message := data.get("custom_message")) is not None: + kwargs["custom_message"] = custom_message + return cls(**kwargs) def __repr__(self) -> str: repr_attrs = ( "channel_id", "timeout_duration", + "custom_message", ) inner = [] @@ -352,6 +368,7 @@ class AutoModRule(Hashable): """ __slots__ = ( + "__dict__", "_state", "id", "guild_id", diff --git a/discord/types/automod.py b/discord/types/automod.py index 4632c8d8c4..4f13b46ae0 100644 --- a/discord/types/automod.py +++ b/discord/types/automod.py @@ -47,6 +47,7 @@ class AutoModTriggerMetadata(TypedDict, total=False): class AutoModActionMetadata(TypedDict, total=False): channel_id: Snowflake duration_seconds: int + custom_message: str class AutoModAction(TypedDict): From 588cc9e7e68b0723897e5ddb088b13f701e83f93 Mon Sep 17 00:00:00 2001 From: Lala Sabathil Date: Tue, 25 Apr 2023 16:54:10 +0200 Subject: [PATCH 50/67] docs(changelog): add missing changelog (#2031) chore(changelog): add missing changelog Signed-off-by: Lala Sabathil --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e65373326..1f83c577f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,8 @@ These changes are available on the `master` branch, but have not yet been releas ([#1983](https://github.com/Pycord-Development/pycord/pull/1983)) - Added new `application_auto_moderation_rule_create_badge` to `ApplicationFlags`. ([#1992](https://github.com/Pycord-Development/pycord/pull/1992)) +- Added `custom_message` to AutoModActionMetadata. +- ([#2029](https://github.com/Pycord-Development/pycord/pull/2029)) ### Changed @@ -63,6 +65,8 @@ These changes are available on the `master` branch, but have not yet been releas working. ([#1999](https://github.com/Pycord-Development/pycord/pull/1999)) - Fixed `TypeError` being raised when passing `name` argument to bridge groups. ([#2000](https://github.com/Pycord-Development/pycord/pull/2000)) +- Fixed `TypeError` in AutoModRule. +- ([#2029](https://github.com/Pycord-Development/pycord/pull/2029)) ## [2.4.1] - 2023-03-20 From b84a51990f4ce9158b459a1ae12fc1620e227904 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Apr 2023 15:08:36 +0000 Subject: [PATCH 51/67] chore(deps-dev): Update pylint requirement from ~=2.17.2 to ~=2.17.3 (#2027) Updates the requirements on [pylint](https://github.com/PyCQA/pylint) to permit the latest version. - [Release notes](https://github.com/PyCQA/pylint/releases) - [Commits](https://github.com/PyCQA/pylint/compare/v2.17.2...v2.17.3) --- updated-dependencies: - dependency-name: pylint dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/dev.txt b/requirements/dev.txt index 696ec91da3..a7f2058db2 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -1,5 +1,5 @@ -r _.txt -pylint~=2.17.2 +pylint~=2.17.3 pytest~=7.3.1 pytest-asyncio~=0.21.0 # pytest-order~=1.0.1 From 3847a8cddf0b9355379c1d10e7216dd7ea14b6d9 Mon Sep 17 00:00:00 2001 From: JustaSqu1d <89910983+JustaSqu1d@users.noreply.github.com> Date: Tue, 25 Apr 2023 08:16:46 -0700 Subject: [PATCH 52/67] docs: add a link to guild features (#2028) Co-authored-by: Lala Sabathil --- discord/guild.py | 46 ++-------------------------------------------- 1 file changed, 2 insertions(+), 44 deletions(-) diff --git a/discord/guild.py b/discord/guild.py index a84f0d2eba..718164aa8e 100644 --- a/discord/guild.py +++ b/discord/guild.py @@ -202,50 +202,8 @@ class Guild(Hashable): The guild's notification settings. features: List[:class:`str`] A list of features that the guild has. The features that a guild can have are - subject to arbitrary change by Discord. - - They are currently as follows: - - - ``ANIMATED_BANNER``: Guild can upload an animated banner. - - ``ANIMATED_ICON``: Guild can upload an animated icon. - - ``APPLICATION_COMMAND_PERMISSIONS_V2``: Guild is using the old command permissions behavior. - - ``AUTO_MODERATION``: Guild has enabled the auto moderation system. - - ``BANNER``: Guild can upload and use a banner. (i.e. :attr:`.banner`) - - ``CHANNEL_BANNER``: Guild can upload and use a channel banners. - - ``COMMERCE``: Guild can sell things using store channels, which have now been removed. - - ``COMMUNITY``: Guild is a community server. - - ``DEVELOPER_SUPPORT_SERVER``: Guild has been set as a support server on the App Directory. - - ``DISCOVERABLE``: Guild shows up in Server Discovery. - - ``FEATURABLE``: Guild can be featured in the Server Directory. - - ``HAS_DIRECTORY_ENTRY``: Unknown. - - ``HUB``: Hubs contain a directory channel that let you find school-related, student-run servers for your school or university. - - ``INTERNAL_EMPLOYEE_ONLY``: Indicates that only users with the staff badge can join the guild. - - ``INVITES_DISABLED``: Guild Invites are disabled. - - ``INVITE_SPLASH``: Guild's invite page can have a special splash. - - ``LINKED_TO_HUB``: 'Guild is linked to a hub. - - ``MEMBER_PROFILES``: Unknown. - - ``MEMBER_VERIFICATION_GATE_ENABLED``: Guild has Membership Screening enabled. - - ``MONETIZATION_ENABLED``: Guild has enabled monetization. - - ``MORE_EMOJI``: Guild has increased custom emoji slots. - - ``MORE_STICKERS``: Guild has increased custom sticker slots. - - ``NEWS``: Guild can create news channels. - - ``NEW_THREAD_PERMISSIONS``: Guild has new thread permissions. - - ``PARTNERED``: Guild is a partnered server. - - ``PREMIUM_TIER_3_OVERRIDE``: Forces the server to server boosting level 3 (specifically created by Discord Staff Member "Jethro" for their personal server). - - ``PREVIEW_ENABLED``: Guild can be viewed before being accepted via Membership Screening. - - ``ROLE_ICONS``: Guild can set an image or emoji as a role icon. - - ``ROLE_SUBSCRIPTIONS_AVAILABLE_FOR_PURCHASE``: Role subscriptions are available for purchasing. - - ``ROLE_SUBSCRIPTIONS_ENABLED``: Guild is able to view and manage role subscriptions. - - ``SEVEN_DAY_THREAD_ARCHIVE``: Users can set the thread archive time to 7 days. - - ``TEXT_IN_VOICE_ENABLED``: Guild has a chat button inside voice channels that opens a dedicated text channel in a sidebar similar to thread view. - - ``THREADS_ENABLED_TESTING``: Used by bot developers to test their bots with threads in guilds with 5 or fewer members and a bot. Also gives the premium thread features. - - ``THREE_DAY_THREAD_ARCHIVE``: Users can set the thread archive time to 3 days. - - ``TICKETED_EVENTS_ENABLED``: Guild has enabled ticketed events. - - ``VANITY_URL``: Guild can have a vanity invite URL (e.g. discord.gg/discord-api). - - ``VERIFIED``: Guild is a verified server. - - ``VIP_REGIONS``: Guild has VIP voice regions. - - ``WELCOME_SCREEN_ENABLED``: Guild has enabled the welcome screen. - + subject to arbitrary change by Discord. You can find a catalog of guild features + `here `_. premium_tier: :class:`int` The premium tier for this guild. Corresponds to "Nitro Server" in the official UI. The number goes from 0 to 3 inclusive. From 3e534b702174cbccb24bc6cfa282e21b8734cd8c Mon Sep 17 00:00:00 2001 From: Lala Sabathil Date: Tue, 25 Apr 2023 19:11:40 +0200 Subject: [PATCH 53/67] feat: voice message support (#2016) Co-authored-by: JustaSqu1d Signed-off-by: Lala Sabathil --- CHANGELOG.md | 5 ++++- discord/flags.py | 8 ++++++++ discord/message.py | 16 +++++++++++++++- discord/permissions.py | 9 +++++++++ discord/types/message.py | 2 ++ 5 files changed, 38 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f83c577f4..aee21f704d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,7 +30,10 @@ These changes are available on the `master` branch, but have not yet been releas - Added new `application_auto_moderation_rule_create_badge` to `ApplicationFlags`. ([#1992](https://github.com/Pycord-Development/pycord/pull/1992)) - Added `custom_message` to AutoModActionMetadata. -- ([#2029](https://github.com/Pycord-Development/pycord/pull/2029)) + ([#2029](https://github.com/Pycord-Development/pycord/pull/2029)) +- Added support for + [voice messages](https://github.com/discord/discord-api-docs/pull/6082). + ([#2016](https://github.com/Pycord-Development/pycord/pull/2016)) ### Changed diff --git a/discord/flags.py b/discord/flags.py index ae5d74da82..28f78284c2 100644 --- a/discord/flags.py +++ b/discord/flags.py @@ -404,6 +404,14 @@ def suppress_notifications(self): return 4096 + @flag_value + def is_voice_message(self): + """:class:`bool`: Returns ``True`` if this message is a voice message. + + .. versionadded:: 2.5 + """ + return 8192 + @fill_with_flags() class PublicUserFlags(BaseFlags): diff --git a/discord/message.py b/discord/message.py index 77193b2920..c74f40c288 100644 --- a/discord/message.py +++ b/discord/message.py @@ -159,7 +159,7 @@ class Attachment(Hashable): case of images. When the message is deleted, this URL might be valid for a few minutes or not valid at all. content_type: Optional[:class:`str`] - The attachment's `media type `_ + The attachment's `media type `_. ephemeral: :class:`bool` Whether the attachment is ephemeral or not. @@ -169,6 +169,16 @@ class Attachment(Hashable): The attachment's description. .. versionadded:: 2.0 + + duration_secs: Optional[:class:`float`] + The duration of the audio file (currently for voice messages). + + .. versionadded:: 2.5 + + waveform: Optional[:class:`str`] + The base64 encoded bytearray representing a sampled waveform (currently for voice messages). + + .. versionadded:: 2.5 """ __slots__ = ( @@ -183,6 +193,8 @@ class Attachment(Hashable): "content_type", "ephemeral", "description", + "duration_secs", + "waveform", ) def __init__(self, *, data: AttachmentPayload, state: ConnectionState): @@ -197,6 +209,8 @@ def __init__(self, *, data: AttachmentPayload, state: ConnectionState): self.content_type: str | None = data.get("content_type") self.ephemeral: bool = data.get("ephemeral", False) self.description: str | None = data.get("description") + self.duration_secs: float | None = data.get("duration_secs") + self.waveform: str | None = data.get("waveform") def is_spoiler(self) -> bool: """Whether this attachment contains a spoiler.""" diff --git a/discord/permissions.py b/discord/permissions.py index 43dc6f2f7d..e94e6c2116 100644 --- a/discord/permissions.py +++ b/discord/permissions.py @@ -610,6 +610,14 @@ def moderate_members(self) -> int: """ return 1 << 40 + @flag_value + def send_voice_messages(self) -> int: + """:class:`bool`: Returns ``True`` if a member can send voice messages. + + .. versionadded:: 2.5 + """ + return 1 << 46 + PO = TypeVar("PO", bound="PermissionOverwrite") @@ -727,6 +735,7 @@ class PermissionOverwrite: use_external_stickers: bool | None start_embedded_activities: bool | None moderate_members: bool | None + send_voice_messages: bool | None def __init__(self, **kwargs: bool | None): self._values: dict[str, bool | None] = {} diff --git a/discord/types/message.py b/discord/types/message.py index 4d6d295d09..b141531e9a 100644 --- a/discord/types/message.py +++ b/discord/types/message.py @@ -66,6 +66,8 @@ class Attachment(TypedDict): size: int url: str proxy_url: str + duration_secs: NotRequired[float] + waveform: NotRequired[str] MessageActivityType = Literal[1, 2, 3, 5] From 0f7b46ebe96d4413431d19cf30d23831ae18ba1c Mon Sep 17 00:00:00 2001 From: UK <41271523+NeloBlivion@users.noreply.github.com> Date: Tue, 25 Apr 2023 18:20:44 +0100 Subject: [PATCH 54/67] feat: Add data attribute to all raw event payloads (#2023) Signed-off-by: Lala Sabathil Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Lala Sabathil --- CHANGELOG.md | 3 ++ discord/raw_models.py | 90 +++++++++++++++++++++++++++++++++++-------- 2 files changed, 78 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aee21f704d..b8fe3eec16 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,9 @@ These changes are available on the `master` branch, but have not yet been releas - Added support for [voice messages](https://github.com/discord/discord-api-docs/pull/6082). ([#2016](https://github.com/Pycord-Development/pycord/pull/2016)) +- Added the `data` attribute to all + [Raw Event payloads](https://docs.pycord.dev/en/master/api/models.html#events). + ([#2023](https://github.com/Pycord-Development/pycord/pull/2023)) ### Changed diff --git a/discord/raw_models.py b/discord/raw_models.py index 78f4d01903..d63d192785 100644 --- a/discord/raw_models.py +++ b/discord/raw_models.py @@ -97,9 +97,13 @@ class RawMessageDeleteEvent(_RawReprMixin): The message ID that got deleted. cached_message: Optional[:class:`Message`] The cached message, if found in the internal message cache. + data: :class:`dict` + The raw data sent by the `gateway `_. + + .. versionadded:: 2.5 """ - __slots__ = ("message_id", "channel_id", "guild_id", "cached_message") + __slots__ = ("message_id", "channel_id", "guild_id", "cached_message", "data") def __init__(self, data: MessageDeleteEvent) -> None: self.message_id: int = int(data["id"]) @@ -109,6 +113,7 @@ def __init__(self, data: MessageDeleteEvent) -> None: self.guild_id: int | None = int(data["guild_id"]) except KeyError: self.guild_id: int | None = None + self.data: MessageDeleteEvent = data class RawBulkMessageDeleteEvent(_RawReprMixin): @@ -124,9 +129,13 @@ class RawBulkMessageDeleteEvent(_RawReprMixin): The guild ID where the message got deleted, if applicable. cached_messages: List[:class:`Message`] The cached messages, if found in the internal message cache. + data: :class:`dict` + The raw data sent by the `gateway `_. + + .. versionadded:: 2.5 """ - __slots__ = ("message_ids", "channel_id", "guild_id", "cached_messages") + __slots__ = ("message_ids", "channel_id", "guild_id", "cached_messages", "data") def __init__(self, data: BulkMessageDeleteEvent) -> None: self.message_ids: set[int] = {int(x) for x in data.get("ids", [])} @@ -137,6 +146,7 @@ def __init__(self, data: BulkMessageDeleteEvent) -> None: self.guild_id: int | None = int(data["guild_id"]) except KeyError: self.guild_id: int | None = None + self.data: BulkMessageDeleteEvent = data class RawMessageUpdateEvent(_RawReprMixin): @@ -156,7 +166,7 @@ class RawMessageUpdateEvent(_RawReprMixin): .. versionadded:: 1.7 data: :class:`dict` - The raw data given by the `gateway `_ + The raw data sent by the `gateway `_ cached_message: Optional[:class:`Message`] The cached message, if found in the internal message cache. Represents the message before it is modified by the data in :attr:`RawMessageUpdateEvent.data`. @@ -204,6 +214,10 @@ class RawReactionActionEvent(_RawReprMixin): ``REACTION_REMOVE`` for reaction removal. .. versionadded:: 1.3 + data: :class:`dict` + The raw data sent by the `gateway `_. + + .. versionadded:: 2.5 """ __slots__ = ( @@ -214,6 +228,7 @@ class RawReactionActionEvent(_RawReprMixin): "emoji", "event_type", "member", + "data", ) def __init__( @@ -230,6 +245,7 @@ def __init__( self.guild_id: int | None = int(data["guild_id"]) except KeyError: self.guild_id: int | None = None + self.data: ReactionActionEvent = data class RawReactionClearEvent(_RawReprMixin): @@ -243,9 +259,13 @@ class RawReactionClearEvent(_RawReprMixin): The channel ID where the reactions got cleared. guild_id: Optional[:class:`int`] The guild ID where the reactions got cleared. + data: :class:`dict` + The raw data sent by the `gateway `_. + + .. versionadded:: 2.5 """ - __slots__ = ("message_id", "channel_id", "guild_id") + __slots__ = ("message_id", "channel_id", "guild_id", "data") def __init__(self, data: ReactionClearEvent) -> None: self.message_id: int = int(data["message_id"]) @@ -255,6 +275,7 @@ def __init__(self, data: ReactionClearEvent) -> None: self.guild_id: int | None = int(data["guild_id"]) except KeyError: self.guild_id: int | None = None + self.data: ReactionClearEvent = data class RawReactionClearEmojiEvent(_RawReprMixin): @@ -272,9 +293,13 @@ class RawReactionClearEmojiEvent(_RawReprMixin): The guild ID where the reactions got cleared. emoji: :class:`PartialEmoji` The custom or unicode emoji being removed. + data: :class:`dict` + The raw data sent by the `gateway `_. + + .. versionadded:: 2.5 """ - __slots__ = ("message_id", "channel_id", "guild_id", "emoji") + __slots__ = ("message_id", "channel_id", "guild_id", "emoji", "data") def __init__(self, data: ReactionClearEmojiEvent, emoji: PartialEmoji) -> None: self.emoji: PartialEmoji = emoji @@ -285,6 +310,7 @@ def __init__(self, data: ReactionClearEmojiEvent, emoji: PartialEmoji) -> None: self.guild_id: int | None = int(data["guild_id"]) except KeyError: self.guild_id: int | None = None + self.data: ReactionClearEmojiEvent = data class RawIntegrationDeleteEvent(_RawReprMixin): @@ -300,9 +326,13 @@ class RawIntegrationDeleteEvent(_RawReprMixin): The ID of the bot/OAuth2 application for this deleted integration. guild_id: :class:`int` The guild ID where the integration got deleted. + data: :class:`dict` + The raw data sent by the `gateway `_. + + .. versionadded:: 2.5 """ - __slots__ = ("integration_id", "application_id", "guild_id") + __slots__ = ("integration_id", "application_id", "guild_id", "data") def __init__(self, data: IntegrationDeleteEvent) -> None: self.integration_id: int = int(data["id"]) @@ -312,6 +342,7 @@ def __init__(self, data: IntegrationDeleteEvent) -> None: self.application_id: int | None = int(data["application_id"]) except KeyError: self.application_id: int | None = None + self.data: IntegrationDeleteEvent = data class RawThreadUpdateEvent(_RawReprMixin): @@ -330,7 +361,7 @@ class RawThreadUpdateEvent(_RawReprMixin): parent_id: :class:`int` The ID of the channel the thread belongs to. data: :class:`dict` - The raw data given by the `gateway `_. + The raw data sent by the `gateway `_. thread: :class:`discord.Thread` | None The thread, if it could be found in the internal cache. """ @@ -364,9 +395,13 @@ class RawThreadDeleteEvent(_RawReprMixin): The ID of the channel the thread belonged to. thread: Optional[:class:`discord.Thread`] The thread that was deleted. This may be ``None`` if deleted thread is not found in internal cache. + data: :class:`dict` + The raw data sent by the `gateway `_. + + .. versionadded:: 2.5 """ - __slots__ = ("thread_id", "thread_type", "guild_id", "parent_id", "thread") + __slots__ = ("thread_id", "thread_type", "guild_id", "parent_id", "thread", "data") def __init__(self, data: ThreadDeleteEvent) -> None: self.thread_id: int = int(data["id"]) @@ -374,6 +409,7 @@ def __init__(self, data: ThreadDeleteEvent) -> None: self.guild_id: int = int(data["guild_id"]) self.parent_id: int = int(data["parent_id"]) self.thread: Thread | None = None + self.data: ThreadDeleteEvent = data class RawTypingEvent(_RawReprMixin): @@ -393,9 +429,13 @@ class RawTypingEvent(_RawReprMixin): The guild ID where the typing originated from, if applicable. member: Optional[:class:`Member`] The member who started typing. Only available if the member started typing in a guild. + data: :class:`dict` + The raw data sent by the `gateway `_. + + .. versionadded:: 2.5 """ - __slots__ = ("channel_id", "user_id", "when", "guild_id", "member") + __slots__ = ("channel_id", "user_id", "when", "guild_id", "member", "data") def __init__(self, data: TypingEvent) -> None: self.channel_id: int = int(data["channel_id"]) @@ -409,6 +449,7 @@ def __init__(self, data: TypingEvent) -> None: self.guild_id: int | None = int(data["guild_id"]) except KeyError: self.guild_id: int | None = None + self.data: TypingEvent = data class RawMemberRemoveEvent(_RawReprMixin): @@ -422,13 +463,18 @@ class RawMemberRemoveEvent(_RawReprMixin): The user that left the guild. guild_id: :class:`int` The ID of the guild the user left. + data: :class:`dict` + The raw data sent by the `gateway `_. + + .. versionadded:: 2.5 """ - __slots__ = ("user", "guild_id") + __slots__ = ("user", "guild_id", "data") def __init__(self, data: MemberRemoveEvent, user: User): self.user: User = user self.guild_id: int = int(data["guild_id"]) + self.data: MemberRemoveEvent = data class RawScheduledEventSubscription(_RawReprMixin): @@ -448,15 +494,20 @@ class RawScheduledEventSubscription(_RawReprMixin): event_type: :class:`str` Can be either ``USER_ADD`` or ``USER_REMOVE`` depending on the event called. + data: :class:`dict` + The raw data sent by the `gateway `_. + + .. versionadded:: 2.5 """ - __slots__ = ("event_id", "guild", "user_id", "event_type") + __slots__ = ("event_id", "guild", "user_id", "event_type", "data") def __init__(self, data: ScheduledEventSubscription, event_type: str): self.event_id: int = int(data["guild_scheduled_event_id"]) self.user_id: int = int(data["user_id"]) self.guild: Guild | None = None self.event_type: str = event_type + self.data: ScheduledEventSubscription = data class AutoModActionExecutionEvent: @@ -503,6 +554,10 @@ class AutoModActionExecutionEvent: The word or phrase configured that was matched in the content. matched_content: :class:`str` The substring in the content that was matched. + data: :class:`dict` + The raw data sent by the `gateway `_. + + .. versionadded:: 2.5 """ __slots__ = ( @@ -522,6 +577,7 @@ class AutoModActionExecutionEvent: "message", "alert_system_message_id", "alert_system_message", + "data", ) def __init__(self, state: ConnectionState, data: AutoModActionExecution) -> None: @@ -570,6 +626,7 @@ def __init__(self, state: ConnectionState, data: AutoModActionExecution) -> None except KeyError: self.alert_system_message_id: int | None = None self.alert_system_message: Message | None = None + self.data: AutoModActionExecution = data def __repr__(self) -> str: return ( @@ -593,7 +650,9 @@ class RawThreadMembersUpdateEvent(_RawReprMixin): member_count: :class:`int` The approximate number of members in the thread. Maximum of 50. data: :class:`dict` - The raw data given by the `gateway `_. + The raw data sent by the `gateway `_. + + .. versionadded:: 2.5 """ __slots__ = ("thread_id", "guild_id", "member_count", "data") @@ -602,7 +661,7 @@ def __init__(self, data: ThreadMembersUpdateEvent) -> None: self.thread_id = int(data["id"]) self.guild_id = int(data["guild_id"]) self.member_count = int(data["member_count"]) - self.data = data + self.data: ThreadMembersUpdateEvent = data class RawAuditLogEntryEvent(_RawReprMixin): @@ -632,7 +691,7 @@ class RawAuditLogEntryEvent(_RawReprMixin): contains extra information. See :class:`AuditLogAction` for which actions have this field filled out. data: :class:`dict` - The raw data given by the `gateway `_. + The raw data sent by the `gateway `_. """ __slots__ = ( @@ -644,6 +703,7 @@ class RawAuditLogEntryEvent(_RawReprMixin): "reason", "extra", "changes", + "data", ) def __init__(self, data: AuditLogEntryEvent) -> None: @@ -657,4 +717,4 @@ def __init__(self, data: AuditLogEntryEvent) -> None: self.reason = data.get("reason") self.extra = data.get("options") self.changes = data.get("changes") - self.data = data + self.data: AuditLogEntryEvent = data From 33d1744e5b67606a648fd09079026d83d230166a Mon Sep 17 00:00:00 2001 From: UK <41271523+NeloBlivion@users.noreply.github.com> Date: Tue, 25 Apr 2023 18:35:48 +0100 Subject: [PATCH 55/67] feat: Move ctx.respond to Interaction and implement Interaction.edit (#2026) Signed-off-by: Lala Sabathil Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Lala Sabathil --- CHANGELOG.md | 2 ++ discord/commands/context.py | 26 +++++---------------- discord/interactions.py | 45 ++++++++++++++++++++++++++++++++++++- 3 files changed, 52 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8fe3eec16..c77691d4b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,8 @@ These changes are available on the `master` branch, but have not yet been releas - Added the `data` attribute to all [Raw Event payloads](https://docs.pycord.dev/en/master/api/models.html#events). ([#2023](https://github.com/Pycord-Development/pycord/pull/2023)) +- Added `Interaction.respond` and `Interaction.edit` as shortcut responses. + ([#2026](https://github.com/Pycord-Development/pycord/pull/2026)) ### Changed diff --git a/discord/commands/context.py b/discord/commands/context.py index f20db34e9f..c8f5a840f0 100644 --- a/discord/commands/context.py +++ b/discord/commands/context.py @@ -266,26 +266,12 @@ def unselected_options(self) -> list[Option] | None: def send_modal(self) -> Callable[..., Awaitable[Interaction]]: return self.interaction.response.send_modal - async def respond(self, *args, **kwargs) -> Interaction | WebhookMessage: - """|coro| - - Sends either a response or a message using the followup webhook determined by whether the interaction - has been responded to or not. - - Returns - ------- - Union[:class:`discord.Interaction`, :class:`discord.WebhookMessage`]: - The response, its type depending on whether it's an interaction response or a followup. - """ - try: - if not self.interaction.response.is_done(): - return await self.interaction.response.send_message( - *args, **kwargs - ) # self.response - else: - return await self.followup.send(*args, **kwargs) # self.send_followup - except discord.errors.InteractionResponded: - return await self.followup.send(*args, **kwargs) + @property + @discord.utils.copy_doc(Interaction.respond) + def respond( + self, *args, **kwargs + ) -> Callable[..., Awaitable[Interaction | WebhookMessage]]: + return self.interaction.respond @property @discord.utils.copy_doc(InteractionResponse.send_message) diff --git a/discord/interactions.py b/discord/interactions.py index 2cd4b740b8..d4120a961a 100644 --- a/discord/interactions.py +++ b/discord/interactions.py @@ -38,7 +38,12 @@ from .object import Object from .permissions import Permissions from .user import User -from .webhook.async_ import Webhook, async_context, handle_message_parameters +from .webhook.async_ import ( + Webhook, + WebhookMessage, + async_context, + handle_message_parameters, +) __all__ = ( "Interaction", @@ -519,6 +524,44 @@ async def delete_original_message(self, **kwargs): """ return await self.delete_original_response(**kwargs) + async def respond(self, *args, **kwargs) -> Interaction | WebhookMessage: + """|coro| + + Sends either a response or a message using the followup webhook determined by whether the interaction + has been responded to or not. + + Returns + ------- + Union[:class:`discord.Interaction`, :class:`discord.WebhookMessage`]: + The response, its type depending on whether it's an interaction response or a followup. + """ + try: + if not self.response.is_done(): + return await self.response.send_message(*args, **kwargs) + else: + return await self.followup.send(*args, **kwargs) + except InteractionResponded: + return await self.followup.send(*args, **kwargs) + + async def edit(self, *args, **kwargs) -> InteractionMessage | None: + """|coro| + + Either respond to the interaction with an edit_message or edits the existing response, determined by + whether the interaction has been responded to or not. + + Returns + ------- + Union[:class:`discord.InteractionMessage`, :class:`discord.WebhookMessage`]: + The response, its type depending on whether it's an interaction response or a followup. + """ + try: + if not self.response.is_done(): + return await self.response.edit_message(*args, **kwargs) + else: + return await self.edit_original_response(*args, **kwargs) + except InteractionResponded: + return await self.edit_original_response(*args, **kwargs) + def to_dict(self) -> dict[str, Any]: """ Converts this interaction object into a dict. From 6a72ff0eede452d55d22b6134bd519d5669b263c Mon Sep 17 00:00:00 2001 From: UK <41271523+NeloBlivion@users.noreply.github.com> Date: Tue, 25 Apr 2023 18:43:25 +0100 Subject: [PATCH 56/67] feat: Received Interactions come with a channel object (#2025) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Lala Sabathil --- CHANGELOG.md | 4 +++ discord/channel.py | 4 ++- discord/interactions.py | 46 +++++++++++++++++++++++++++-------- discord/types/interactions.py | 2 ++ 4 files changed, 45 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c77691d4b6..5992376353 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,10 @@ These changes are available on the `master` branch, but have not yet been releas - Changed file-upload size limit from 8 MB to 25 MB accordingly. ([#2014](https://github.com/Pycord-Development/pycord/pull/2014)) +- `Interaction.channel` is received from the gateway, so it can now be `DMChannel` and + `GroupChannel`. ([#2025](https://github.com/Pycord-Development/pycord/pull/2025)) +- `DMChannel.recipients` can now be `None` + ([#2025](https://github.com/Pycord-Development/pycord/pull/2025)) ### Removed diff --git a/discord/channel.py b/discord/channel.py index 88ba717db5..ce2e87aad9 100644 --- a/discord/channel.py +++ b/discord/channel.py @@ -2838,7 +2838,9 @@ def __init__( self, *, me: ClientUser, state: ConnectionState, data: DMChannelPayload ): self._state: ConnectionState = state - self.recipient: User | None = state.store_user(data["recipients"][0]) + 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"]) diff --git a/discord/interactions.py b/discord/interactions.py index d4120a961a..c207da7105 100644 --- a/discord/interactions.py +++ b/discord/interactions.py @@ -29,7 +29,7 @@ from typing import TYPE_CHECKING, Any, Coroutine, Union from . import utils -from .channel import ChannelType, PartialMessageable +from .channel import ChannelType, PartialMessageable, _threaded_channel_factory from .enums import InteractionResponseType, InteractionType, try_enum from .errors import ClientException, InteractionResponded, InvalidArgument from .file import File @@ -57,7 +57,9 @@ from .channel import ( CategoryChannel, + DMChannel, ForumChannel, + GroupChannel, StageChannel, TextChannel, VoiceChannel, @@ -82,6 +84,8 @@ ForumChannel, CategoryChannel, Thread, + DMChannel, + GroupChannel, PartialMessageable, ] @@ -104,8 +108,10 @@ class Interaction: The interaction type. guild_id: Optional[:class:`int`] The guild ID the interaction was sent from. + channel: Optional[Union[:class:`abc.GuildChannel`, :class:`abc.PrivateChannel`, :class:`Thread`]] + The channel the interaction was sent from. channel_id: Optional[:class:`int`] - The channel ID the interaction was sent from. + The ID of the channel the interaction was sent from. application_id: :class:`int` The application ID that the interaction was for. user: Optional[Union[:class:`User`, :class:`Member`]] @@ -129,6 +135,7 @@ class Interaction: "id", "type", "guild_id", + "channel", "channel_id", "data", "application_id", @@ -139,6 +146,7 @@ class Interaction: "token", "version", "custom_id", + "_channel_data", "_message_data", "_permissions", "_app_permissions", @@ -174,13 +182,7 @@ def _from_data(self, data: InteractionPayload): self._app_permissions: int = int(data.get("app_permissions", 0)) self.message: Message | None = None - - if message_data := data.get("message"): - self.message = Message( - state=self._state, channel=self.channel, data=message_data - ) - - self._message_data = message_data + self.channel = None self.user: User | Member | None = None self._permissions: int = 0 @@ -211,6 +213,30 @@ def _from_data(self, data: InteractionPayload): except KeyError: pass + if channel := data.get("channel"): + if (ch_type := channel.get("type")) is not None: + factory, ch_type = _threaded_channel_factory(ch_type) + + if ch_type in (ChannelType.group, ChannelType.private): + self.channel = factory( + me=self.user, data=channel, state=self._state + ) + elif self.guild: + self.channel = factory( + guild=self.guild, state=self._state, data=channel + ) + else: + self.channel = self.cached_channel + + self._channel_data = channel + + if message_data := data.get("message"): + self.message = Message( + state=self._state, channel=self.channel, data=message_data + ) + + self._message_data = message_data + @property def client(self) -> Client: """Returns the client that sent the interaction.""" @@ -230,7 +256,7 @@ def is_component(self) -> bool: return self.type == InteractionType.component @utils.cached_slot_property("_cs_channel") - def channel(self) -> InteractionChannel | None: + def cached_channel(self) -> InteractionChannel | None: """The channel the interaction was sent from. diff --git a/discord/types/interactions.py b/discord/types/interactions.py index 458247709d..ad891e3203 100644 --- a/discord/types/interactions.py +++ b/discord/types/interactions.py @@ -39,6 +39,7 @@ if TYPE_CHECKING: from .message import AllowedMentions, Message + from ..interactions import InteractionChannel from .._typed_dict import NotRequired, TypedDict @@ -196,6 +197,7 @@ class Interaction(TypedDict): data: NotRequired[InteractionData] guild_id: NotRequired[Snowflake] channel_id: NotRequired[Snowflake] + channel: NotRequired[InteractionChannel] member: NotRequired[Member] user: NotRequired[User] message: NotRequired[Message] From 2544830b7a41cfe3f32346223e592149d42d54d1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 26 Apr 2023 07:59:36 -0500 Subject: [PATCH 57/67] chore(pre-commit): pre-commit autoupdate (#2024) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/PyCQA/autoflake: v2.0.2 → v2.1.1](https://github.com/PyCQA/autoflake/compare/v2.0.2...v2.1.1) - [github.com/pre-commit/mirrors-prettier: v3.0.0-alpha.6 → v3.0.0-alpha.9-for-vscode](https://github.com/pre-commit/mirrors-prettier/compare/v3.0.0-alpha.6...v3.0.0-alpha.9-for-vscode) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Lala Sabathil --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4f51e49c19..5f8cee5007 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -9,7 +9,7 @@ repos: - id: trailing-whitespace - id: end-of-file-fixer - repo: https://github.com/PyCQA/autoflake - rev: v2.0.2 + rev: v2.1.1 hooks: - id: autoflake # args: @@ -77,7 +77,7 @@ repos: # - id: mypy - repo: https://github.com/pre-commit/mirrors-prettier - rev: v3.0.0-alpha.6 + rev: v3.0.0-alpha.9-for-vscode hooks: - id: prettier args: [--prose-wrap=always, --print-width=88] From 05b5ae3b8bdc3f693c90e22bc8223de547698831 Mon Sep 17 00:00:00 2001 From: UK <41271523+NeloBlivion@users.noreply.github.com> Date: Wed, 26 Apr 2023 14:53:38 +0100 Subject: [PATCH 58/67] fix: Improve Automod compatibility with Audit Logs + minor fixes (#2030) Signed-off-by: Lala Sabathil Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: plun1331 <49261529+plun1331@users.noreply.github.com> Co-authored-by: Lala Sabathil --- CHANGELOG.md | 13 ++++--- discord/audit_logs.py | 80 +++++++++++++++++++++++++++++++++++++- discord/automod.py | 2 +- discord/enums.py | 6 ++- discord/types/audit_log.py | 3 ++ docs/api/enums.rst | 68 ++++++++++++++++++++++++++++++++ 6 files changed, 163 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5992376353..ea9772dd19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,11 +37,17 @@ These changes are available on the `master` branch, but have not yet been releas - Added the `data` attribute to all [Raw Event payloads](https://docs.pycord.dev/en/master/api/models.html#events). ([#2023](https://github.com/Pycord-Development/pycord/pull/2023)) +- Added and documented missing `AuditLogAction` enums. + ([#2030](https://github.com/Pycord-Development/pycord/pull/2030)) +- `AuditLogDiff` now supports AutoMod related models. + ([#2030](https://github.com/Pycord-Development/pycord/pull/2030)) - Added `Interaction.respond` and `Interaction.edit` as shortcut responses. ([#2026](https://github.com/Pycord-Development/pycord/pull/2026)) ### Changed +- Suppressed FFMPEG output when recording voice channels. + ([#1993](https://github.com/Pycord-Development/pycord/pull/1993)) - Changed file-upload size limit from 8 MB to 25 MB accordingly. ([#2014](https://github.com/Pycord-Development/pycord/pull/2014)) - `Interaction.channel` is received from the gateway, so it can now be `DMChannel` and @@ -54,11 +60,6 @@ These changes are available on the `master` branch, but have not yet been releas - Removed `@client.once()` in favour of `@client.listen(once=True)`. ([#1957](https://github.com/Pycord-Development/pycord/pull/1957)) -### Changed - -- Suppressed FFMPEG output when recording voice channels. - ([#1993](https://github.com/Pycord-Development/pycord/pull/1993)) - ### Fixed - Fixed `AttributeError` caused by @@ -78,7 +79,7 @@ These changes are available on the `master` branch, but have not yet been releas - Fixed `TypeError` being raised when passing `name` argument to bridge groups. ([#2000](https://github.com/Pycord-Development/pycord/pull/2000)) - Fixed `TypeError` in AutoModRule. -- ([#2029](https://github.com/Pycord-Development/pycord/pull/2029)) + ([#2029](https://github.com/Pycord-Development/pycord/pull/2029)) ## [2.4.1] - 2023-03-20 diff --git a/discord/audit_logs.py b/discord/audit_logs.py index c427534ea7..190c7b59b6 100644 --- a/discord/audit_logs.py +++ b/discord/audit_logs.py @@ -29,6 +29,7 @@ from . import enums, utils from .asset import Asset +from .automod import AutoModAction, AutoModTriggerMetadata from .colour import Colour from .invite import Invite from .mixins import Hashable @@ -57,6 +58,8 @@ from .threads import Thread from .types.audit_log import AuditLogChange as AuditLogChangePayload from .types.audit_log import AuditLogEntry as AuditLogEntryPayload + from .types.automod import AutoModAction as AutoModActionPayload + from .types.automod import AutoModTriggerMetadata as AutoModTriggerMetadataPayload from .types.channel import PermissionOverwrite as PermissionOverwritePayload from .types.role import Role as RolePayload from .types.snowflake import Snowflake @@ -83,6 +86,22 @@ def _transform_channel( return entry.guild.get_channel(int(data)) or Object(id=data) +def _transform_channels( + entry: AuditLogEntry, data: list[Snowflake] | None +) -> list[abc.GuildChannel | Object] | None: + if data is None: + return None + return [_transform_channel(entry, channel) for channel in data] + + +def _transform_roles( + entry: AuditLogEntry, data: list[Snowflake] | None +) -> list[Role | Object] | None: + if data is None: + return None + return [entry.guild.get_role(int(r)) or Object(id=r) for r in data] + + def _transform_member_id( entry: AuditLogEntry, data: Snowflake | None ) -> Member | User | None: @@ -172,6 +191,24 @@ def _transform_type( return enums.try_enum(enums.ChannelType, data) +def _transform_actions( + entry: AuditLogEntry, data: list[AutoModActionPayload] | None +) -> AutoModAction | None: + if data is None: + return None + else: + return [AutoModAction.from_dict(d) for d in data] + + +def _transform_trigger_metadata( + entry: AuditLogEntry, data: list[AutoModActionPayload] | None +) -> AutoModAction | None: + if data is None: + return None + else: + return AutoModTriggerMetadata.from_dict(data) + + class AuditLogDiff: def __len__(self) -> int: return len(self.__dict__) @@ -240,6 +277,12 @@ class AuditLogChanges: ), "command_id": ("command_id", _transform_snowflake), "image_hash": ("cover", _transform_scheduled_event_cover), + "trigger_type": (None, _enum_transformer(enums.AutoModTriggerType)), + "event_type": (None, _enum_transformer(enums.AutoModEventType)), + "actions": (None, _transform_actions), + "trigger_metadata": (None, _transform_trigger_metadata), + "exempt_roles": (None, _transform_roles), + "exempt_channels": (None, _transform_channels), } def __init__( @@ -255,13 +298,31 @@ def __init__( for elem in sorted(data, key=lambda i: i["key"]): attr = elem["key"] - # special cases for role add/remove + # special cases for role/trigger_metadata add/remove if attr == "$add": self._handle_role(self.before, self.after, entry, elem["new_value"]) # type: ignore continue elif attr == "$remove": self._handle_role(self.after, self.before, entry, elem["new_value"]) # type: ignore continue + elif attr in [ + "$add_keyword_filter", + "$add_regex_patterns", + "$add_allow_list", + ]: + self._handle_trigger_metadata( + self.before, self.after, entry, elem["new_value"], attr + ) + continue + elif attr in [ + "$remove_keyword_filter", + "$remove_regex_patterns", + "$remove_allow_list", + ]: + self._handle_trigger_metadata( + self.after, self.before, entry, elem["new_value"], attr + ) + continue try: key, transformer = self.TRANSFORMERS[attr] @@ -355,6 +416,23 @@ def _handle_role( setattr(second, "roles", data) + def _handle_trigger_metadata( + self, + first: AuditLogDiff, + second: AuditLogDiff, + entry: AuditLogEntry, + elem: list[AutoModTriggerMetadataPayload], + attr: str, + ) -> None: + if not hasattr(first, "trigger_metadata"): + setattr(first, "trigger_metadata", None) + + key = attr.split("_", 1)[-1] + data = {key: elem} + tm = AutoModTriggerMetadata.from_dict(data) + + setattr(second, "trigger_metadata", tm) + class _AuditLogProxyMemberPrune: delete_member_days: int diff --git a/discord/automod.py b/discord/automod.py index 2d6b5244da..c4b1e23c0e 100644 --- a/discord/automod.py +++ b/discord/automod.py @@ -317,7 +317,7 @@ def __repr__(self) -> str: inner.append(f"{attr}={value}") inner = " ".join(inner) - return f"" + return f"" class AutoModRule(Hashable): diff --git a/discord/enums.py b/discord/enums.py index 75af244382..ddc2e0d2b2 100644 --- a/discord/enums.py +++ b/discord/enums.py @@ -438,6 +438,8 @@ class AuditLogAction(Enum): auto_moderation_rule_update = 141 auto_moderation_rule_delete = 142 auto_moderation_block_message = 143 + auto_moderation_flag_to_channel = 144 + auto_moderation_user_communication_disabled = 145 @property def category(self) -> AuditLogActionCategory | None: @@ -496,6 +498,8 @@ def category(self) -> AuditLogActionCategory | None: AuditLogAction.auto_moderation_rule_update: AuditLogActionCategory.update, AuditLogAction.auto_moderation_rule_delete: AuditLogActionCategory.delete, AuditLogAction.auto_moderation_block_message: None, + AuditLogAction.auto_moderation_flag_to_channel: None, + AuditLogAction.auto_moderation_user_communication_disabled: None, } return lookup[self] @@ -534,7 +538,7 @@ def target_type(self) -> str | None: return "thread" elif v < 122: return "application_command_permission" - elif v < 144: + elif v < 146: return "auto_moderation_rule" diff --git a/discord/types/audit_log.py b/discord/types/audit_log.py index 7e00526e6b..c0b1303947 100644 --- a/discord/types/audit_log.py +++ b/discord/types/audit_log.py @@ -267,6 +267,9 @@ class AuditEntryInfo(TypedDict): id: Snowflake type: Literal["0", "1"] role_name: str + application_id: Snowflake + auto_moderation_rule_name: str + auto_moderation_rule_trigger_type: str class AuditLogEntry(TypedDict): diff --git a/docs/api/enums.rst b/docs/api/enums.rst index 49c105878f..17f6a61f06 100644 --- a/docs/api/enums.rst +++ b/docs/api/enums.rst @@ -1512,6 +1512,74 @@ of :class:`enum.Enum`. .. versionadded:: 2.0 + .. attribute:: auto_moderation_rule_create + + A guild auto moderation rule was created. + + Possible attributes for :class:`AuditLogDiff`: + + - :attr:`~AuditLogDiff.name` + - :attr:`~AuditLogDiff.enabled` + - :attr:`~AuditLogDiff.trigger_type` + - :attr:`~AuditLogDiff.event_type` + - :attr:`~AuditLogDiff.trigger_metadata` + - :attr:`~AuditLogDiff.actions` + - :attr:`~AuditLogDiff.exempt_roles` + - :attr:`~AuditLogDiff.exempt_channels` + + .. versionadded:: 2.5 + + .. attribute:: auto_moderation_rule_update + + A guild auto moderation rule was updated. + + Possible attributes for :class:`AuditLogDiff`: + + - :attr:`~AuditLogDiff.name` + - :attr:`~AuditLogDiff.enabled` + - :attr:`~AuditLogDiff.trigger_type` + - :attr:`~AuditLogDiff.trigger_metadata` + - :attr:`~AuditLogDiff.actions` + - :attr:`~AuditLogDiff.exempt_roles` + - :attr:`~AuditLogDiff.exempt_channels` + + .. versionadded:: 2.5 + + .. attribute:: auto_moderation_rule_delete + + A guild auto moderation rule was deleted. + + Possible attributes for :class:`AuditLogDiff`: + + - :attr:`~AuditLogDiff.name` + - :attr:`~AuditLogDiff.enabled` + - :attr:`~AuditLogDiff.trigger_type` + - :attr:`~AuditLogDiff.event_type` + - :attr:`~AuditLogDiff.trigger_metadata` + - :attr:`~AuditLogDiff.actions` + - :attr:`~AuditLogDiff.exempt_roles` + - :attr:`~AuditLogDiff.exempt_channels` + + .. versionadded:: 2.5 + + .. attribute:: auto_moderation_block_message + + A message was blocked by auto moderation. + + .. versionadded:: 2.5 + + .. attribute:: auto_moderation_flag_to_channel + + A message was flagged by auto moderation. + + .. versionadded:: 2.5 + + .. attribute:: auto_moderation_user_communication_disabled + + A member was timed out by auto moderation. + + .. versionadded:: 2.5 + .. class:: AuditLogActionCategory From 111010997957e0ca04922932ab8b656d8b789a53 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 26 Apr 2023 16:30:26 +0000 Subject: [PATCH 59/67] chore(deps-dev): Bump bandit from 1.7.4 to 1.7.5 (#1971) * chore(deps-dev): Bump bandit from 1.7.4 to 1.7.5 Bumps [bandit](https://github.com/PyCQA/bandit) from 1.7.4 to 1.7.5. - [Release notes](https://github.com/PyCQA/bandit/releases) - [Commits](https://github.com/PyCQA/bandit/compare/1.7.4...1.7.5) --- updated-dependencies: - dependency-name: bandit dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * docs: add warning comment * style(pre-commit): auto fixes from pre-commit.com hooks --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: plun1331 <49261529+plun1331@users.noreply.github.com> Co-authored-by: Lala Sabathil Co-authored-by: BobDotCom <71356958+BobDotCom@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- discord/state.py | 4 +++- requirements/dev.txt | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/discord/state.py b/discord/state.py index 90fd97ab53..1f92da71c7 100644 --- a/discord/state.py +++ b/discord/state.py @@ -1256,8 +1256,10 @@ 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) + 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 diff --git a/requirements/dev.txt b/requirements/dev.txt index a7f2058db2..6e91c45c1c 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -7,5 +7,5 @@ mypy~=1.2.0 coverage~=7.2 pre-commit==3.2.2 codespell==2.2.4 -bandit==1.7.4 +bandit==1.7.5 flake8==6.0.0 From 04da6edb42917e58bd5c9211c5e304af4a81a73a Mon Sep 17 00:00:00 2001 From: plun1331 <49261529+plun1331@users.noreply.github.com> Date: Fri, 28 Apr 2023 12:24:26 -0700 Subject: [PATCH 60/67] docs: update thread edit docs (#2034) Signed-off-by: plun1331 <49261529+plun1331@users.noreply.github.com> Signed-off-by: Lala Sabathil Co-authored-by: Lala Sabathil --- discord/threads.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/discord/threads.py b/discord/threads.py index 6eb1bfc0a9..232fdbb66f 100644 --- a/discord/threads.py +++ b/discord/threads.py @@ -611,7 +611,7 @@ async def edit( Editing the thread requires :attr:`.Permissions.manage_threads`. The thread creator can also edit ``name``, ``archived`` or ``auto_archive_duration``. Note that if the thread is locked then only those with :attr:`.Permissions.manage_threads` - can unarchive a thread. + can send messages in it or unarchive a thread. The thread must be unarchived to be edited. From 4675c6ce49edbc15bebce5ff1446f9aa8d6a4faa Mon Sep 17 00:00:00 2001 From: Lala Sabathil Date: Mon, 1 May 2023 18:36:24 +0200 Subject: [PATCH 61/67] fix: Reflect api for bans correctly (#1922) Co-authored-by: Dorukyum <53639936+Dorukyum@users.noreply.github.com> Co-authored-by: plun1331 <49261529+plun1331@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- CHANGELOG.md | 2 ++ discord/guild.py | 22 ++++++++++++---------- discord/iterators.py | 6 ------ 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea9772dd19..31ff4a2666 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -80,6 +80,8 @@ These changes are available on the `master` branch, but have not yet been releas ([#2000](https://github.com/Pycord-Development/pycord/pull/2000)) - Fixed `TypeError` in AutoModRule. ([#2029](https://github.com/Pycord-Development/pycord/pull/2029)) +- Reflecting the api for gettings bans correctly. + ([#1922](https://github.com/Pycord-Development/pycord/pull/1922)) ## [2.4.1] - 2023-03-20 diff --git a/discord/guild.py b/discord/guild.py index 718164aa8e..8d4517e5fc 100644 --- a/discord/guild.py +++ b/discord/guild.py @@ -2116,13 +2116,19 @@ async def fetch_channel(self, channel_id: int, /) -> GuildChannel | Thread: def bans( self, limit: int | None = None, - before: SnowflakeTime | None = None, - after: SnowflakeTime | None = None, + before: Snowflake | None = None, + after: Snowflake | None = None, ) -> BanIterator: """|coro| Retrieves an :class:`.AsyncIterator` that enables receiving the guild's bans. In order to use this, you must have the :attr:`~Permissions.ban_members` permission. + Users will always be returned in ascending order sorted by user ID. + If both the ``before`` and ``after`` parameters are provided, only before is respected. + + .. versionchanged:: 2.5 + The ``before``. and ``after`` parameters were changed. They are now of the type :class:`.abc.Snowflake` instead of + `SnowflakeTime` to comply with the discord api. .. versionchanged:: 2.0 The ``limit``, ``before``. and ``after`` parameters were added. Now returns a :class:`.BanIterator` instead @@ -2134,14 +2140,10 @@ def bans( ---------- limit: Optional[:class:`int`] The number of bans to retrieve. Defaults to 1000. - before: Optional[Union[:class:`.abc.Snowflake`, :class:`datetime.datetime`]] - Retrieve bans before this date or object. - If a datetime is provided, it is recommended to use a UTC aware datetime. - If the datetime is naive, it is assumed to be local time. - after: Optional[Union[:class:`.abc.Snowflake`, :class:`datetime.datetime`]] - Retrieve bans after this date or object. - If a datetime is provided, it is recommended to use a UTC aware datetime. - If the datetime is naive, it is assumed to be local time. + before: Optional[:class:`.abc.Snowflake`] + Retrieve bans before the given user. + after: Optional[:class:`.abc.Snowflake`] + Retrieve bans after the given user. Yields ------ diff --git a/discord/iterators.py b/discord/iterators.py index f4ec6cda28..78edb7570d 100644 --- a/discord/iterators.py +++ b/discord/iterators.py @@ -689,12 +689,6 @@ def create_member(self, data): class BanIterator(_AsyncIterator["BanEntry"]): def __init__(self, guild, limit=None, before=None, after=None): - if isinstance(after, datetime.datetime): - after = Object(id=time_snowflake(after, high=True)) - - if isinstance(before, datetime.datetime): - before = Object(id=time_snowflake(before, high=True)) - self.guild = guild self.limit = limit self.after = after From 7a6a42c5d17f8cbb4bce189e99293d644e6b38c5 Mon Sep 17 00:00:00 2001 From: Om <92863779+Om1609@users.noreply.github.com> Date: Mon, 1 May 2023 22:57:16 +0530 Subject: [PATCH 62/67] feat: Add synchronization to start of audio recordings (#1984) Signed-off-by: Om <92863779+Om1609@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: VincentRPS Co-authored-by: plun1331 <49261529+plun1331@users.noreply.github.com> Co-authored-by: Lala Sabathil Co-authored-by: JustaSqu1d --- CHANGELOG.md | 3 + discord/sinks/core.py | 1 + discord/voice_client.py | 52 +++++++++---- examples/audio_recording_merged.py | 115 +++++++++++++++++++++++++++++ 4 files changed, 157 insertions(+), 14 deletions(-) create mode 100644 examples/audio_recording_merged.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 31ff4a2666..d0047df41b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,9 @@ These changes are available on the `master` branch, but have not yet been releas ([#1983](https://github.com/Pycord-Development/pycord/pull/1983)) - Added new `application_auto_moderation_rule_create_badge` to `ApplicationFlags`. ([#1992](https://github.com/Pycord-Development/pycord/pull/1992)) +- Added `sync_start` argument to `VoiceClient.start_recording()`. This adds silence to + the start of audio recordings. + ([#1984](https://github.com/Pycord-Development/pycord/pull/1984)) - Added `custom_message` to AutoModActionMetadata. ([#2029](https://github.com/Pycord-Development/pycord/pull/2029)) - Added support for diff --git a/discord/sinks/core.py b/discord/sinks/core.py index 479acbe179..561f875701 100644 --- a/discord/sinks/core.py +++ b/discord/sinks/core.py @@ -115,6 +115,7 @@ def __init__(self, data, client): self.decoded_data = None self.user_id = None + self.receive_time = time.perf_counter() class AudioData: diff --git a/discord/voice_client.py b/discord/voice_client.py index 110977d214..f1e16cf812 100644 --- a/discord/voice_client.py +++ b/discord/voice_client.py @@ -700,7 +700,7 @@ def unpack_audio(self, data): self.decoder.decode(data) - def start_recording(self, sink, callback, *args): + def start_recording(self, sink, callback, *args, sync_start: bool = False): """The bot will begin recording audio from the current voice channel it is in. This function uses a thread so the current code line will not be stopped. Must be in a voice channel to use. @@ -716,6 +716,9 @@ def start_recording(self, sink, callback, *args): A function which is called after the bot has stopped recording. *args: Args which will be passed to the callback function. + sync_start: :class:`bool` + If True, the recordings of subsequent users will start with silence. + This is useful for recording audio just as it was heard. Raises ------ @@ -738,6 +741,7 @@ def start_recording(self, sink, callback, *args): self.decoder = opus.DecodeManager(self) self.decoder.start() self.recording = True + self.sync_start = sync_start self.sink = sink sink.init(self) @@ -796,8 +800,9 @@ def recv_audio(self, sink, callback, *args): # it by user, handles pcm files and # silence that should be added. - self.user_timestamps = {} + self.user_timestamps: dict[int, tuple[int, float]] = {} self.starting_time = time.perf_counter() + self.first_packet_timestamp: float while self.recording: ready, _, err = select.select([self.socket], [], [self.socket], 0.01) if not ready: @@ -815,27 +820,46 @@ def recv_audio(self, sink, callback, *args): self.stopping_time = time.perf_counter() self.sink.cleanup() - callback = asyncio.run_coroutine_threadsafe( - callback(self.sink, *args), self.loop - ) + callback = asyncio.run_coroutine_threadsafe(callback(sink, *args), self.loop) result = callback.result() if result is not None: print(result) - def recv_decoded_audio(self, data): - if data.ssrc not in self.user_timestamps: - self.user_timestamps.update({data.ssrc: data.timestamp}) - # Add silence when they were not being recorded. - silence = 0 - else: - silence = data.timestamp - self.user_timestamps[data.ssrc] - 960 - self.user_timestamps[data.ssrc] = data.timestamp + def recv_decoded_audio(self, data: RawData): + # Add silence when they were not being recorded. + if data.ssrc not in self.user_timestamps: # First packet from user + if ( + not self.user_timestamps or not self.sync_start + ): # First packet from anyone + self.first_packet_timestamp = data.receive_time + silence = 0 + + else: # Previously received a packet from someone else + silence = ( + (data.receive_time - self.first_packet_timestamp) * 48000 + ) - 960 + + else: # Previously received a packet from user + dRT = ( + data.receive_time - self.user_timestamps[data.ssrc][1] + ) * 48000 # delta receive time + dT = data.timestamp - self.user_timestamps[data.ssrc][0] # delta timestamp + diff = abs(100 - dT * 100 / dRT) + if ( + diff > 60 and dT != 960 + ): # If the difference in change is more than 60% threshold + silence = dRT - 960 + else: + silence = dT - 960 + + self.user_timestamps.update({data.ssrc: (data.timestamp, data.receive_time)}) data.decoded_data = ( - struct.pack("") + + seg = pydub.AudioSegment.from_file(audio.file, format="mp3") + + # Determine the longest audio segment + if len(seg) > len(longest): + audio_segs.append(longest) + longest = seg + else: + audio_segs.append(seg) + + audio.file.seek(0) + files.append(discord.File(audio.file, filename=f"{user_id}.mp3")) + + for seg in audio_segs: + longest = longest.overlay(seg) + + with io.BytesIO() as f: + longest.export(f, format="mp3") + await channel.send( + f"Finished! Recorded audio for {', '.join(mention_strs)}.", + files=files + [discord.File(f, filename="recording.mp3")], + ) + + +@bot.command() +async def join(ctx: discord.ApplicationContext): + """Join the voice channel!""" + voice = ctx.author.voice + + if not voice: + return await ctx.respond("You're not in a vc right now") + + vc = await voice.channel.connect() + connections.update({ctx.guild.id: vc}) + + await ctx.respond("Joined!") + + +@bot.command() +async def start(ctx: discord.ApplicationContext): + """Record the voice channel!""" + voice = ctx.author.voice + + if not voice: + return await ctx.respond("You're not in a vc right now") + + vc = connections.get(ctx.guild.id) + + if not vc: + return await ctx.respond( + "I'm not in a vc right now. Use `/join` to make me join!" + ) + + vc.start_recording( + MP3Sink(), + finished_callback, + ctx.channel, + sync_start=True, + ) + + await ctx.respond("The recording has started!") + + +@bot.command() +async def stop(ctx: discord.ApplicationContext): + """Stop the recording""" + vc = connections.get(ctx.guild.id) + + if not vc: + return await ctx.respond("There's no recording going on right now") + + vc.stop_recording() + + await ctx.respond("The recording has stopped!") + + +@bot.command() +async def leave(ctx: discord.ApplicationContext): + """Leave the voice channel!""" + vc = connections.get(ctx.guild.id) + + if not vc: + return await ctx.respond("I'm not in a vc right now") + + await vc.disconnect() + + await ctx.respond("Left!") + + +bot.run("TOKEN") From 5096622b9f07cd2e690b3b50f48006ef5206cee3 Mon Sep 17 00:00:00 2001 From: Lala Sabathil Date: Wed, 3 May 2023 14:49:41 +0200 Subject: [PATCH 63/67] chore!: move configs to global .github (#2041) * chore!: move configs to global .github * chore!: move configs to global .github --- .github/CODE_OF_CONDUCT.md | 120 --------------------- .github/DEVELOPER_CERTIFICATE_OF_ORIGIN.md | 37 ------- .github/FUNDING.yml | 1 - .github/PULL_REQUEST_TEMPLATE.md | 23 ---- .github/CONTRIBUTING.md => CONTRIBUTING.md | 0 5 files changed, 181 deletions(-) delete mode 100644 .github/CODE_OF_CONDUCT.md delete mode 100644 .github/DEVELOPER_CERTIFICATE_OF_ORIGIN.md delete mode 100644 .github/FUNDING.yml delete mode 100644 .github/PULL_REQUEST_TEMPLATE.md rename .github/CONTRIBUTING.md => CONTRIBUTING.md (100%) diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md deleted file mode 100644 index 4f0af8ed63..0000000000 --- a/.github/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,120 +0,0 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -We as members, contributors, and leaders pledge to make participation in our community a -harassment-free experience for everyone, regardless of age, body size, visible or -invisible disability, ethnicity, sex characteristics, gender identity and expression, -level of experience, education, socio-economic status, nationality, personal appearance, -race, religion, or sexual identity and orientation. - -We pledge to act and interact in ways that contribute to an open, welcoming, diverse, -inclusive, and healthy community. - -## Our Standards - -Examples of behavior that contributes to a positive environment for our community -include: - -- Demonstrating empathy and kindness toward other people -- Being respectful of differing opinions, viewpoints, and experiences -- Giving and gracefully accepting constructive feedback -- Accepting responsibility and apologizing to those affected by our mistakes, and - learning from the experience -- Focusing on what is best not just for us as individuals, but for the overall community - -Examples of unacceptable behavior include: - -- The use of sexualized language or imagery, and sexual attention or advances of any - kind -- Trolling, insulting or derogatory comments, and personal or political attacks -- Public or private harassment -- Publishing others' private information, such as a physical or email address, without - their explicit permission -- Other conduct which could reasonably be considered inappropriate in a professional - setting - -## Enforcement Responsibilities - -Community leaders are responsible for clarifying and enforcing our standards of -acceptable behavior and will take appropriate and fair corrective action in response to -any behavior that they deem inappropriate, threatening, offensive, or harmful. - -Community leaders have the right and responsibility to remove, edit, or reject comments, -commits, code, wiki edits, issues, and other contributions that are not aligned to this -Code of Conduct, and will communicate reasons for moderation decisions when appropriate. - -## Scope - -This Code of Conduct applies within all community spaces, and also applies when an -individual is officially representing the community in public spaces. Examples of -representing our community include using an official e-mail address, posting via an -official social media account, or acting as an appointed representative at an online or -offline event. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to -the community leaders responsible for enforcement at Our Discord server. All complaints -will be reviewed and investigated promptly and fairly. - -All community leaders are obligated to respect the privacy and security of the reporter -of any incident. - -## Enforcement Guidelines - -Community leaders will follow these Community Impact Guidelines in determining the -consequences for any action they deem in violation of this Code of Conduct: - -### 1. Correction - -**Community Impact**: Use of inappropriate language or other behavior deemed -unprofessional or unwelcome in the community. - -**Consequence**: A private, written warning from community leaders, providing clarity -around the nature of the violation and an explanation of why the behavior was -inappropriate. A public apology may be requested. - -### 2. Warning - -**Community Impact**: A violation through a single incident or series of actions. - -**Consequence**: A warning with consequences for continued behavior. No interaction with -the people involved, including unsolicited interaction with those enforcing the Code of -Conduct, for a specified period of time. This includes avoiding interactions in -community spaces as well as external channels like social media. Violating these terms -may lead to a temporary or permanent ban. - -### 3. Temporary Ban - -**Community Impact**: A serious violation of community standards, including sustained -inappropriate behavior. - -**Consequence**: A temporary ban from any sort of interaction or public communication -with the community for a specified period of time. No public or private interaction with -the people involved, including unsolicited interaction with those enforcing the Code of -Conduct, is allowed during this period. Violating these terms may lead to a permanent -ban. - -### 4. Permanent Ban - -**Community Impact**: Demonstrating a pattern of violation of community standards, -including sustained inappropriate behavior, harassment of an individual, or aggression -toward or disparagement of classes of individuals. - -**Consequence**: A permanent ban from any sort of public interaction within the -community. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, -available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. - -Community Impact Guidelines were inspired by -[Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity). - -[homepage]: https://www.contributor-covenant.org - -For answers to common questions about this code of conduct, see the FAQ at -https://www.contributor-covenant.org/faq. Translations are available at -https://www.contributor-covenant.org/translations. diff --git a/.github/DEVELOPER_CERTIFICATE_OF_ORIGIN.md b/.github/DEVELOPER_CERTIFICATE_OF_ORIGIN.md deleted file mode 100644 index e003b3bd6d..0000000000 --- a/.github/DEVELOPER_CERTIFICATE_OF_ORIGIN.md +++ /dev/null @@ -1,37 +0,0 @@ -# Developer Certificate of Origin (DCO) - -``` -Version 1.1 - -Copyright (C) 2004, 2006 The Linux Foundation and its contributors. - -Everyone is permitted to copy and distribute verbatim copies of this -license document, but changing it is not allowed. - - -Developer's Certificate of Origin 1.1 - -By making a contribution to this project, I certify that: - -(a) The contribution was created in whole or in part by me and I - have the right to submit it under the open source license - indicated in the file; or - -(b) The contribution is based upon previous work that, to the best - of my knowledge, is covered under an appropriate open source - license and I have the right under that license to submit that - work with modifications, whether created in whole or in part - by me, under the same open source license (unless I am - permitted to submit under a different license), as indicated - in the file; or - -(c) The contribution was provided directly to me by some other - person who certified (a), (b) or (c) and I have not modified - it. - -(d) I understand and agree that this project and the contribution - are public and that a record of the contribution (including all - personal information I submit with it, including my sign-off) is - maintained indefinitely and may be redistributed consistent with - this project or the open source license(s) involved. -``` diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index e171b7955b..0000000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1 +0,0 @@ -patreon: pycord diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index d6ae4ca6aa..0000000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,23 +0,0 @@ -## Summary - - - -## Information - - - -- [ ] This PR fixes an issue. -- [ ] This PR adds something new (e.g. new method or parameters). -- [ ] This PR is a breaking change (e.g. methods or parameters removed/renamed). -- [ ] This PR is **not** a code change (e.g. documentation, README, typehinting, - examples, ...). - -## Checklist - - - -- [ ] I have searched the open pull requests for duplicates. -- [ ] If code changes were made then they have been tested. - - [ ] I have updated the documentation to reflect the changes. -- [ ] If `type: ignore` comments were used, a comment is also left explaining why. -- [ ] I have updated the changelog to include these changes. diff --git a/.github/CONTRIBUTING.md b/CONTRIBUTING.md similarity index 100% rename from .github/CONTRIBUTING.md rename to CONTRIBUTING.md From b690b44bcdaa67fa1769d42b86c305321eba17c9 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 3 May 2023 08:17:14 -0500 Subject: [PATCH 64/67] chore(pre-commit): pre-commit autoupdate (#2037) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v3.3.1 → v3.3.2](https://github.com/asottile/pyupgrade/compare/v3.3.1...v3.3.2) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5f8cee5007..e529824bb0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,7 +19,7 @@ repos: # - --remove-duplicate-keys # - --remove-unused-variables - repo: https://github.com/asottile/pyupgrade - rev: v3.3.1 + rev: v3.3.2 hooks: - id: pyupgrade args: [--py38-plus] From 71944ef450e9c10950f5403e7768f9ffb5d212c5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 May 2023 13:24:49 +0000 Subject: [PATCH 65/67] chore(deps-dev): Bump pre-commit from 3.2.2 to 3.3.1 (#2040) Bumps [pre-commit](https://github.com/pre-commit/pre-commit) from 3.2.2 to 3.3.1. - [Release notes](https://github.com/pre-commit/pre-commit/releases) - [Changelog](https://github.com/pre-commit/pre-commit/blob/main/CHANGELOG.md) - [Commits](https://github.com/pre-commit/pre-commit/compare/v3.2.2...v3.3.1) --- updated-dependencies: - dependency-name: pre-commit dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: BobDotCom <71356958+BobDotCom@users.noreply.github.com> --- requirements/dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/dev.txt b/requirements/dev.txt index 6e91c45c1c..487cb58244 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -5,7 +5,7 @@ pytest-asyncio~=0.21.0 # pytest-order~=1.0.1 mypy~=1.2.0 coverage~=7.2 -pre-commit==3.2.2 +pre-commit==3.3.1 codespell==2.2.4 bandit==1.7.5 flake8==6.0.0 From b4a1bc986b7b1bb7598bda5a2f4acf14b04e7f0d Mon Sep 17 00:00:00 2001 From: Om <92863779+Om1609@users.noreply.github.com> Date: Wed, 3 May 2023 22:30:32 +0530 Subject: [PATCH 66/67] feat!: Add `view.parent` and store `view.message` on receiving Interaction for a component (#2036) Signed-off-by: Om <92863779+Om1609@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- CHANGELOG.md | 8 ++++++++ discord/interactions.py | 2 +- discord/ui/view.py | 16 +++++++++++++--- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d0047df41b..bbecc9869c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,9 @@ These changes are available on the `master` branch, but have not yet been releas ([#2030](https://github.com/Pycord-Development/pycord/pull/2030)) - Added `Interaction.respond` and `Interaction.edit` as shortcut responses. ([#2026](https://github.com/Pycord-Development/pycord/pull/2026)) +- Added `view.parent` which is set when the view was sent by + `interaction.response.send_message`. + ([#2036](https://github.com/Pycord-Development/pycord/pull/2036)) ### Changed @@ -57,11 +60,16 @@ These changes are available on the `master` branch, but have not yet been releas `GroupChannel`. ([#2025](https://github.com/Pycord-Development/pycord/pull/2025)) - `DMChannel.recipients` can now be `None` ([#2025](https://github.com/Pycord-Development/pycord/pull/2025)) +- Store `view.message` on receiving Interaction for a component. + ([#2036](https://github.com/Pycord-Development/pycord/pull/2036)) ### Removed - Removed `@client.once()` in favour of `@client.listen(once=True)`. ([#1957](https://github.com/Pycord-Development/pycord/pull/1957)) +- Removed `view.message` being set when the view was sent by + `interaction.response.send_message`. + ([#2036](https://github.com/Pycord-Development/pycord/pull/2036)) ### Fixed diff --git a/discord/interactions.py b/discord/interactions.py index c207da7105..944b50e336 100644 --- a/discord/interactions.py +++ b/discord/interactions.py @@ -913,7 +913,7 @@ async def send_message( if ephemeral and view.timeout is None: view.timeout = 15 * 60.0 - view.message = await self._parent.original_response() + view.parent = self._parent self._parent._state.store_view(view) self._responded = True diff --git a/discord/ui/view.py b/discord/ui/view.py index 8172e726f8..5bf96f2612 100644 --- a/discord/ui/view.py +++ b/discord/ui/view.py @@ -141,6 +141,9 @@ class View: message: Optional[:class:`.Message`] The message that this view is attached to. If ``None`` then the view has not been sent with a message. + parent: Optional[:class:`.Interaction`] + The parent interaction which this view was sent from. + If ``None`` then the view was not sent using :meth:`InteractionResponse.send_message`. """ __discord_ui_view__: ClassVar[bool] = True @@ -187,6 +190,7 @@ def __init__( self.__timeout_task: asyncio.Task[None] | None = None self.__stopped: asyncio.Future[bool] = loop.create_future() self._message: Message | InteractionMessage | None = None + self.parent: Interaction | None = None def __repr__(self) -> str: return f"<{self.__class__.__name__} timeout={self.timeout} children={len(self.children)}>" @@ -363,9 +367,12 @@ async def on_timeout(self) -> None: A callback that is called when a view's timeout elapses without being explicitly stopped. """ if self.disable_on_timeout: - if self._message: - self.disable_all_items() - await self._message.edit(view=self) + self.disable_all_items() + message = self._message or self.parent + if message: + m = await message.edit(view=self) + if m: + self._message = m async def on_check_failure(self, interaction: Interaction) -> None: """|coro| @@ -438,6 +445,9 @@ def _dispatch_item(self, item: Item, interaction: Interaction): if self.__stopped.done(): return + if interaction.message: + self.message = interaction.message + asyncio.create_task( self._scheduled_task(item, interaction), name=f"discord-ui-view-dispatch-{self.id}", From ea3e3db03fbd35c409b1d448c0525fdad6468ffc Mon Sep 17 00:00:00 2001 From: BobDotCom <71356958+BobDotCom@users.noreply.github.com> Date: Fri, 5 May 2023 13:13:07 -0500 Subject: [PATCH 67/67] fix(docs): Fix readthedocs build failures (#2046) fix(docs): Use new readthedocs config References: - urllib3/urllib3#2168 - readthedocs/readthedocs.org#10290 - https://docs.readthedocs.io/en/stable/config-file/v2.html#legacy-build-specification Signed-off-by: BobDotCom <71356958+BobDotCom@users.noreply.github.com> --- .readthedocs.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.readthedocs.yml b/.readthedocs.yml index b12d1ab002..59842ef8bb 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -2,7 +2,9 @@ version: 2 formats: [] build: - image: latest + os: ubuntu-22.04 + tools: + python: "3.8" sphinx: configuration: docs/conf.py @@ -10,7 +12,6 @@ sphinx: builder: html python: - version: "3.8" install: - method: pip path: .