From fdf03d4bca0f4a2347e14c224179e6ada8d07748 Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Tue, 18 Apr 2023 05:11:39 +0100 Subject: [PATCH 1/9] [commands] Use get_role where appropriate in role decorators --- discord/ext/commands/core.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/discord/ext/commands/core.py b/discord/ext/commands/core.py index f3850a224..8140dca00 100644 --- a/discord/ext/commands/core.py +++ b/discord/ext/commands/core.py @@ -2036,7 +2036,7 @@ def has_role(item: Union[int, str], /) -> Check[Any]: # ctx.guild is None doesn't narrow ctx.author to Member if isinstance(item, int): - role = discord.utils.get(ctx.author.roles, id=item) # type: ignore + role = ctx.author.get_role(item) # type: ignore else: role = discord.utils.get(ctx.author.roles, name=item) # type: ignore if role is None: @@ -2083,8 +2083,12 @@ def has_any_role(*items: Union[int, str]) -> Callable[[T], T]: raise NoPrivateMessage() # ctx.guild is None doesn't narrow ctx.author to Member - getter = functools.partial(discord.utils.get, ctx.author.roles) - if any(getter(id=item) is not None if isinstance(item, int) else getter(name=item) is not None for item in items): + if any( + ctx.author.get_role(item) is not None + if isinstance(item, int) + else discord.utils.get(ctx.author.roles, name=item) is not None + for item in items + ): return True raise MissingAnyRole(list(items)) @@ -2113,11 +2117,10 @@ def bot_has_role(item: int, /) -> Callable[[T], T]: if ctx.guild is None: raise NoPrivateMessage() - me = ctx.me if isinstance(item, int): - role = discord.utils.get(me.roles, id=item) + role = ctx.me.get_role(item) else: - role = discord.utils.get(me.roles, name=item) + role = discord.utils.get(ctx.me.roles, name=item) if role is None: raise BotMissingRole(item) return True @@ -2144,8 +2147,10 @@ def bot_has_any_role(*items: int) -> Callable[[T], T]: raise NoPrivateMessage() me = ctx.me - getter = functools.partial(discord.utils.get, me.roles) - if any(getter(id=item) is not None if isinstance(item, int) else getter(name=item) is not None for item in items): + if any( + me.get_role(item) is not None if isinstance(item, int) else discord.utils.get(me.roles, name=item) is not None + for item in items + ): return True raise BotMissingAnyRole(list(items)) From 2247ffd9b5f4f65e1ee1936781fe1ac84631ccad Mon Sep 17 00:00:00 2001 From: z03h <7235242+z03h@users.noreply.github.com> Date: Mon, 17 Apr 2023 21:36:53 -0700 Subject: [PATCH 2/9] Convert Webhook targets in AuditlogEntry --- discord/audit_logs.py | 12 ++++++++++++ discord/guild.py | 5 +++++ discord/state.py | 1 + 3 files changed, 18 insertions(+) diff --git a/discord/audit_logs.py b/discord/audit_logs.py index 47f397a8a..489e064b7 100644 --- a/discord/audit_logs.py +++ b/discord/audit_logs.py @@ -74,6 +74,7 @@ if TYPE_CHECKING: from .types.automod import AutoModerationTriggerMetadata, AutoModerationAction from .user import User from .app_commands import AppCommand + from .webhook import Webhook TargetType = Union[ Guild, @@ -89,6 +90,9 @@ if TYPE_CHECKING: Object, PartialIntegration, AutoModRule, + ScheduledEvent, + Webhook, + AppCommand, None, ] @@ -580,6 +584,7 @@ class AuditLogEntry(Hashable): integrations: Mapping[int, PartialIntegration], app_commands: Mapping[int, AppCommand], automod_rules: Mapping[int, AutoModRule], + webhooks: Mapping[int, Webhook], data: AuditLogEntryPayload, guild: Guild, ): @@ -589,6 +594,7 @@ class AuditLogEntry(Hashable): self._integrations: Mapping[int, PartialIntegration] = integrations self._app_commands: Mapping[int, AppCommand] = app_commands self._automod_rules: Mapping[int, AutoModRule] = automod_rules + self._webhooks: Mapping[int, Webhook] = webhooks self._from_data(data) def _from_data(self, data: AuditLogEntryPayload) -> None: @@ -845,3 +851,9 @@ class AuditLogEntry(Hashable): def _convert_target_auto_moderation(self, target_id: int) -> Union[AutoModRule, Object]: return self._automod_rules.get(target_id) or Object(target_id, type=AutoModRule) + + def _convert_target_webhook(self, target_id: int) -> Union[Webhook, Object]: + # circular import + from .webhook import Webhook + + return self._webhooks.get(target_id) or Object(target_id, type=Webhook) diff --git a/discord/guild.py b/discord/guild.py index 0f91eebe1..fdf30d6f8 100644 --- a/discord/guild.py +++ b/discord/guild.py @@ -3860,6 +3860,7 @@ class Guild(Hashable): # avoid circular import from .app_commands import AppCommand + from .webhook import Webhook while True: retrieve = 100 if limit is None else min(limit, 100) @@ -3886,6 +3887,9 @@ class Guild(Hashable): ) automod_rule_map = {rule.id: rule for rule in automod_rules} + webhooks = (Webhook.from_state(data=raw_webhook, state=self._state) for raw_webhook in data.get('webhooks', [])) + webhook_map = {webhook.id: webhook for webhook in webhooks} + count = 0 for count, raw_entry in enumerate(raw_entries, 1): @@ -3899,6 +3903,7 @@ class Guild(Hashable): integrations=integration_map, app_commands=app_command_map, automod_rules=automod_rule_map, + webhooks=webhook_map, guild=self, ) diff --git a/discord/state.py b/discord/state.py index 8b556f28c..f2f2a0a83 100644 --- a/discord/state.py +++ b/discord/state.py @@ -1108,6 +1108,7 @@ class ConnectionState(Generic[ClientT]): integrations={}, app_commands={}, automod_rules={}, + webhooks={}, data=data, guild=guild, ) From 7f578fde22a93af08e686ec846ae95ab84f034e2 Mon Sep 17 00:00:00 2001 From: Vioshim <63890837+Vioshim@users.noreply.github.com> Date: Mon, 17 Apr 2023 23:53:43 -0500 Subject: [PATCH 3/9] Update base file size limit --- discord/guild.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/discord/guild.py b/discord/guild.py index fdf30d6f8..e86d121ba 100644 --- a/discord/guild.py +++ b/discord/guild.py @@ -318,9 +318,9 @@ class Guild(Hashable): ) _PREMIUM_GUILD_LIMITS: ClassVar[Dict[Optional[int], _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 9845eb2f9c4ab453eb09363c8ac7191d00f9a127 Mon Sep 17 00:00:00 2001 From: Andrin S <65789180+Puncher1@users.noreply.github.com> Date: Tue, 18 Apr 2023 06:58:07 +0200 Subject: [PATCH 4/9] Update docs on creating bot user --- docs/discord.rst | 7 +------ docs/images/discord_create_bot_user.png | Bin 12522 -> 0 bytes 2 files changed, 1 insertion(+), 6 deletions(-) delete mode 100644 docs/images/discord_create_bot_user.png diff --git a/docs/discord.rst b/docs/discord.rst index ac12417f0..63485138e 100644 --- a/docs/discord.rst +++ b/docs/discord.rst @@ -21,12 +21,7 @@ Creating a Bot account is a pretty straightforward process. .. image:: /images/discord_create_app_form.png :alt: The new application form filled in. -5. Create a Bot User by navigating to the "Bot" tab and clicking "Add Bot". - - - Click "Yes, do it!" to continue. - - .. image:: /images/discord_create_bot_user.png - :alt: The Add Bot button. +5. Navigate to the "Bot" tab to configure it. 6. Make sure that **Public Bot** is ticked if you want others to invite your bot. - You should also make sure that **Require OAuth2 Code Grant** is unchecked unless you diff --git a/docs/images/discord_create_bot_user.png b/docs/images/discord_create_bot_user.png deleted file mode 100644 index b66e64c75eb0dcb1a0701b8e65c21441e7a82763..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12522 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 Date: Tue, 18 Apr 2023 07:01:01 +0200 Subject: [PATCH 5/9] Escape # and - in markdown utilities --- discord/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/discord/utils.py b/discord/utils.py index 6b4e14347..fd711387b 100644 --- a/discord/utils.py +++ b/discord/utils.py @@ -900,7 +900,7 @@ _MARKDOWN_ESCAPE_REGEX = re.compile(fr'(?P{_MARKDOWN_ESCAPE_SUBREGEX}| _URL_REGEX = r'(?P<[^: >]+:\/[^ >]+>|(?:https?|steam):\/\/[^\s<]+[^<.,:;\"\'\]\s])' -_MARKDOWN_STOCK_REGEX = fr'(?P[_\\~|\*`]|{_MARKDOWN_ESCAPE_COMMON})' +_MARKDOWN_STOCK_REGEX = fr'(?P[_\\~|\*`#-]|{_MARKDOWN_ESCAPE_COMMON})' def remove_markdown(text: str, *, ignore_links: bool = True) -> str: From 8991525215622d842f1115b27a0bc41f76b6154d Mon Sep 17 00:00:00 2001 From: Michael H Date: Tue, 18 Apr 2023 04:03:40 -0400 Subject: [PATCH 6/9] Improve handling of ArrayFlags Why discord did it this way instead of as an integer bitfield like everything reasonable is unknowable, but this does less work to get to the same result. Add comment detailing what many would find unreadbale --- discord/flags.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/discord/flags.py b/discord/flags.py index 1dbb7c3c3..1b0005bd2 100644 --- a/discord/flags.py +++ b/discord/flags.py @@ -25,6 +25,7 @@ DEALINGS IN THE SOFTWARE. from __future__ import annotations from functools import reduce +from operator import or_ from typing import TYPE_CHECKING, Any, Callable, ClassVar, Dict, Iterator, List, Optional, Tuple, Type, TypeVar, overload from .enums import UserFlags @@ -1566,7 +1567,15 @@ class ArrayFlags(BaseFlags): @classmethod def _from_value(cls: Type[Self], value: List[int]) -> Self: self = cls.__new__(cls) - self.value = reduce(lambda a, b: a | (1 << b - 1), value, 0) + # This is a micro-optimization given the frequency this object can be created. + # (1).__lshift__ is used in place of lambda x: 1 << x + # prebinding to a method of a constant rather than define a lambda. + # Pairing this with map, is essentially equivalent to (1 << x for x in value) + # reduction using operator.or_ instead of defining a lambda each call + # Discord sends these starting with a value of 1 + # Rather than subtract 1 from each element prior to left shift, + # we shift right by 1 once at the end. + self.value = reduce(or_, map((1).__lshift__, value), 0) >> 1 return self def to_array(self) -> List[int]: From 0adef0ec8979a9f6c52d8062c8cdbe021f6810ac Mon Sep 17 00:00:00 2001 From: Rapptz Date: Tue, 18 Apr 2023 01:08:52 -0400 Subject: [PATCH 7/9] Update auto_archive_duration documentation Fix #9351 --- discord/app_commands/models.py | 2 +- discord/channel.py | 4 ++-- discord/message.py | 2 +- discord/threads.py | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/discord/app_commands/models.py b/discord/app_commands/models.py index ef2e1849d..3e9d250b2 100644 --- a/discord/app_commands/models.py +++ b/discord/app_commands/models.py @@ -673,7 +673,7 @@ class AppCommandThread(Hashable): archiver_id: Optional[:class:`int`] The user's ID that archived this thread. auto_archive_duration: :class:`int` - The duration in minutes until the thread is automatically archived due to inactivity. + The duration in minutes until the thread is automatically hidden from the channel list. Usually a value of 60, 1440, 4320 and 10080. archive_timestamp: :class:`datetime.datetime` An aware timestamp of when the thread's archived status was last updated in UTC. diff --git a/discord/channel.py b/discord/channel.py index 3c93832f3..cd5490b2e 100644 --- a/discord/channel.py +++ b/discord/channel.py @@ -737,7 +737,7 @@ class TextChannel(discord.abc.Messageable, discord.abc.GuildChannel, Hashable): If ``None`` is passed then a private thread is created. Defaults to ``None``. auto_archive_duration: :class:`int` - The duration in minutes before a thread is automatically archived for inactivity. + The duration in minutes before a thread is automatically hidden from the channel list. If not provided, the channel's default auto archive duration is used. Must be one of ``60``, ``1440``, ``4320``, or ``10080``, if provided. @@ -2607,7 +2607,7 @@ class ForumChannel(discord.abc.GuildChannel, Hashable): name: :class:`str` The name of the thread. auto_archive_duration: :class:`int` - The duration in minutes before a thread is automatically archived for inactivity. + The duration in minutes before a thread is automatically hidden from the channel list. If not provided, the channel's default auto archive duration is used. Must be one of ``60``, ``1440``, ``4320``, or ``10080``, if provided. diff --git a/discord/message.py b/discord/message.py index 8c9b732f5..c96c7e022 100644 --- a/discord/message.py +++ b/discord/message.py @@ -1215,7 +1215,7 @@ class PartialMessage(Hashable): name: :class:`str` The name of the thread. auto_archive_duration: :class:`int` - The duration in minutes before a thread is automatically archived for inactivity. + The duration in minutes before a thread is automatically hidden from the channel list. If not provided, the channel's default auto archive duration is used. Must be one of ``60``, ``1440``, ``4320``, or ``10080``, if provided. diff --git a/discord/threads.py b/discord/threads.py index c5551a55a..b47c189d2 100644 --- a/discord/threads.py +++ b/discord/threads.py @@ -122,7 +122,7 @@ class Thread(Messageable, Hashable): archiver_id: Optional[:class:`int`] The user's ID that archived this thread. auto_archive_duration: :class:`int` - The duration in minutes until the thread is automatically archived due to inactivity. + The duration in minutes until the thread is automatically hidden from the channel list. Usually a value of 60, 1440, 4320 and 10080. archive_timestamp: :class:`datetime.datetime` An aware timestamp of when the thread's archived status was last updated in UTC. @@ -608,7 +608,7 @@ class Thread(Messageable, Hashable): Whether non-moderators can add other non-moderators to this thread. Only available for private threads. auto_archive_duration: :class:`int` - The new duration in minutes before a thread is automatically archived for inactivity. + The new duration in minutes before a thread is automatically hidden from the channel list. Must be one of ``60``, ``1440``, ``4320``, or ``10080``. slowmode_delay: :class:`int` Specifies the slowmode rate limit for user in this thread, in seconds. From cb6170a7247958294b85a3bd0ab29b71088e86a2 Mon Sep 17 00:00:00 2001 From: Rapptz Date: Tue, 18 Apr 2023 06:14:49 -0400 Subject: [PATCH 8/9] Fix AuditLogEntry.target being None for invites Fix #9336 --- discord/audit_logs.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/discord/audit_logs.py b/discord/audit_logs.py index 489e064b7..17f308c45 100644 --- a/discord/audit_logs.py +++ b/discord/audit_logs.py @@ -733,12 +733,11 @@ class AuditLogEntry(Hashable): if self.action.target_type is None: return None - if self._target_id is None: - return None - try: converter = getattr(self, '_convert_target_' + self.action.target_type) except AttributeError: + if self._target_id is None: + return None return Object(id=self._target_id) else: return converter(self._target_id) @@ -771,7 +770,12 @@ class AuditLogEntry(Hashable): def _convert_target_channel(self, target_id: int) -> Union[abc.GuildChannel, Object]: return self.guild.get_channel(target_id) or Object(id=target_id) - def _convert_target_user(self, target_id: int) -> Union[Member, User, Object]: + def _convert_target_user(self, target_id: Optional[int]) -> Optional[Union[Member, User, Object]]: + # For some reason the member_disconnect and member_move action types + # do not have a non-null target_id so safeguard against that + if target_id is None: + return None + return self._get_member(target_id) or Object(id=target_id, type=Member) def _convert_target_role(self, target_id: int) -> Union[Role, Object]: From 952558d5948d376980abdf676e1330451e8a964d Mon Sep 17 00:00:00 2001 From: Andrin S <65789180+Puncher1@users.noreply.github.com> Date: Tue, 18 Apr 2023 14:04:47 +0200 Subject: [PATCH 9/9] [docs] Add missing attributes to AuditLogDiff --- docs/api.rst | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/docs/api.rst b/docs/api.rst index 316dbda14..e2f77de97 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -3422,6 +3422,12 @@ AuditLogDiff :type: :class:`str` + .. attribute:: guild + + The guild of something. + + :type: :class:`Guild` + .. attribute:: icon A guild's or role's icon. See also :attr:`Guild.icon` or :attr:`Role.icon`. @@ -3996,6 +4002,38 @@ AuditLogDiff :type: :class:`ChannelFlags` + .. attribute:: default_thread_slowmode_delay + + The default slowmode delay for threads created in this text channel or forum. + + See also :attr:`TextChannel.default_thread_slowmode_delay` and :attr:`ForumChannel.default_thread_slowmode_delay` + + :type: :class:`int` + + .. attribute:: applied_tags + + The applied tags of a forum post. + + See also :attr:`Thread.applied_tags` + + :type: List[Union[:class:`ForumTag`, :class:`Object`]] + + .. attribute:: available_tags + + The available tags of a forum. + + See also :attr:`ForumChannel.available_tags` + + :type: Sequence[:class:`ForumTag`] + + .. attribute:: default_reaction_emoji + + The default_reaction_emoji for forum posts. + + See also :attr:`ForumChannel.default_reaction_emoji` + + :type: :class:`default_reaction_emoji` + .. this is currently missing the following keys: reason and application_id I'm not sure how to port these