Skip to content

Commit f5be720

Browse files
authored
Merge branch 'master' into modal_select
Signed-off-by: UK <[email protected]>
2 parents 09f80dd + 233ca64 commit f5be720

18 files changed

+419
-72
lines changed

.github/dependabot.yml

Lines changed: 0 additions & 31 deletions
This file was deleted.

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ cython_debug/
159159

160160
# Custom
161161
*.json
162+
!renovate.json
162163
*.egg-info
163164
.venv/
164165
docs/_build

CHANGELOG.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,12 @@ These changes are available on the `master` branch, but have not yet been releas
6969
([#2818](https://github.com/Pycord-Development/pycord/pull/2818))
7070
- Added `Interaction.attachment_size_limit`.
7171
([#2854](https://github.com/Pycord-Development/pycord/pull/2854))
72-
- Added support for string selects in modals.
72+
- Added support for selects and text displays in modals.
7373
([#2858](https://github.com/Pycord-Development/pycord/pull/2858))
74+
- Added `AuditLogDiff.communication_disabled_until`.
75+
([#2883](https://github.com/Pycord-Development/pycord/pull/2883))
76+
- Added `discord.User.primary_guild` and the `PrimaryGuild` class.
77+
([#2876](https://github.com/Pycord-Development/pycord/pull/2876))
7478

7579
### Fixed
7680

@@ -142,6 +146,8 @@ These changes are available on the `master` branch, but have not yet been releas
142146
([#2843](https://github.com/Pycord-Development/pycord/pull/2843))
143147
- Fixed `TypeError` when using `@option` with certain annotations and along with
144148
`channel_types`. ([#2835](https://github.com/Pycord-Development/pycord/pull/2835))
149+
- Fixed `AttributeError` when accessing `AuditLogEntry.changes` more than once.
150+
([#2882])(https://github.com/Pycord-Development/pycord/pull/2882))
145151

146152
### Changed
147153

@@ -163,6 +169,8 @@ These changes are available on the `master` branch, but have not yet been releas
163169
([#2797](https://github.com/Pycord-Development/pycord/pull/2797))
164170
- Upgraded voice websocket version to v8.
165171
([#2812](https://github.com/Pycord-Development/pycord/pull/2812))
172+
- `Messageable.pins()` now returns a `MessagePinIterator` and has new arguments.
173+
([#2872](https://github.com/Pycord-Development/pycord/pull/2872))
166174

167175
### Deprecated
168176

@@ -172,6 +180,9 @@ These changes are available on the `master` branch, but have not yet been releas
172180
([#2501](https://github.com/Pycord-Development/pycord/pull/2501))
173181
- Deprecated `Interaction.cached_channel` in favor of `Interaction.channel`.
174182
([#2658](https://github.com/Pycord-Development/pycord/pull/2658))
183+
- Deprecated `Messageable.pins()` returning a list of `Message`; it should be used as an
184+
iterator of `MessagePin` instead.
185+
([#2872](https://github.com/Pycord-Development/pycord/pull/2872))
175186

176187
### Removed
177188

discord/abc.py

Lines changed: 50 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
from .file import File, VoiceMessage
4949
from .flags import ChannelFlags, MessageFlags
5050
from .invite import Invite
51-
from .iterators import HistoryIterator
51+
from .iterators import HistoryIterator, MessagePinIterator
5252
from .mentions import AllowedMentions
5353
from .partial_emoji import PartialEmoji, _EmojiTag
5454
from .permissions import PermissionOverwrite, Permissions
@@ -1754,32 +1754,64 @@ async def fetch_message(self, id: int, /) -> Message:
17541754
data = await self._state.http.get_message(channel.id, id)
17551755
return self._state.create_message(channel=channel, data=data)
17561756

1757-
async def pins(self) -> list[Message]:
1758-
"""|coro|
1757+
def pins(
1758+
self,
1759+
*,
1760+
limit: int | None = 50,
1761+
before: SnowflakeTime | None = None,
1762+
) -> MessagePinIterator:
1763+
"""Returns a :class:`~discord.MessagePinIterator` that enables receiving the destination's pinned messages.
17591764
1760-
Retrieves all messages that are currently pinned in the channel.
1765+
You must have :attr:`~discord.Permissions.read_message_history` permissions to use this.
17611766
1762-
.. note::
1767+
.. warning::
17631768
1764-
Due to a limitation with the Discord API, the :class:`.Message`
1765-
objects returned by this method do not contain complete
1766-
:attr:`.Message.reactions` data.
1769+
Starting from version 3.0, `await channel.pins()` will no longer return a list of :class:`Message`. See examples below for new usage instead.
17671770
1768-
Returns
1769-
-------
1770-
List[:class:`~discord.Message`]
1771-
The messages that are currently pinned.
1771+
Parameters
1772+
----------
1773+
limit: Optional[:class:`int`]
1774+
The number of pinned messages to retrieve.
1775+
If ``None``, retrieves every pinned message in the channel.
1776+
before: Optional[Union[:class:`~discord.abc.Snowflake`, :class:`datetime.datetime`]]
1777+
Retrieve messages pinned before this datetime.
1778+
If a datetime is provided, it is recommended to use a UTC aware datetime.
1779+
If the datetime is naive, it is assumed to be local time.
1780+
1781+
Yields
1782+
------
1783+
:class:`~discord.MessagePin`
1784+
The pinned message.
17721785
17731786
Raises
17741787
------
1788+
~discord.Forbidden
1789+
You do not have permissions to get pinned messages.
17751790
~discord.HTTPException
1776-
Retrieving the pinned messages failed.
1777-
"""
1791+
The request to get pinned messages failed.
17781792
1779-
channel = await self._get_channel()
1780-
state = self._state
1781-
data = await state.http.pins_from(channel.id)
1782-
return [state.create_message(channel=channel, data=m) for m in data]
1793+
Examples
1794+
--------
1795+
1796+
Usage ::
1797+
1798+
counter = 0
1799+
async for pin in channel.pins(limit=250):
1800+
if pin.message.author == client.user:
1801+
counter += 1
1802+
1803+
Flattening into a list: ::
1804+
1805+
pins = await channel.pins(limit=None).flatten()
1806+
# pins is now a list of MessagePin...
1807+
1808+
All parameters are optional.
1809+
"""
1810+
return MessagePinIterator(
1811+
self,
1812+
limit=limit,
1813+
before=before,
1814+
)
17831815

17841816
def can_send(self, *objects) -> bool:
17851817
"""Returns a :class:`bool` indicating whether you have the permissions to send the object(s).

discord/asset.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939
if TYPE_CHECKING:
4040
ValidStaticFormatTypes = Literal["webp", "jpeg", "jpg", "png"]
4141
ValidAssetFormatTypes = Literal["webp", "jpeg", "jpg", "png", "gif"]
42+
from .state import ConnectionState
43+
4244

4345
VALID_STATIC_FORMATS = frozenset({"jpeg", "jpg", "webp", "png"})
4446
VALID_ASSET_FORMATS = VALID_STATIC_FORMATS | {"gif"}
@@ -201,6 +203,33 @@ def _from_avatar_decoration(
201203
animated=animated,
202204
)
203205

206+
@classmethod
207+
def _from_user_primary_guild_tag(
208+
cls, state: ConnectionState, identity_guild_id: int, badge_id: str
209+
) -> Asset:
210+
"""Creates an Asset for a user's primary guild (tag) badge.
211+
212+
Parameters
213+
----------
214+
state: ConnectionState
215+
The connection state.
216+
identity_guild_id: int
217+
The ID of the guild.
218+
badge_id: str
219+
The badge hash/id.
220+
221+
Returns
222+
-------
223+
:class:`Asset`
224+
The primary guild badge asset.
225+
"""
226+
return cls(
227+
state,
228+
url=f"{Asset.BASE}/guild-tag-badges/{identity_guild_id}/{badge_id}.png?size=256",
229+
key=badge_id,
230+
animated=False,
231+
)
232+
204233
@classmethod
205234
def _from_guild_avatar(
206235
cls, state, guild_id: int, member_id: int, avatar: str

discord/audit_logs.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525

2626
from __future__ import annotations
2727

28+
import datetime
29+
from functools import cached_property
2830
from typing import TYPE_CHECKING, Any, Callable, ClassVar, Generator, TypeVar
2931

3032
from . import enums, utils
@@ -44,8 +46,6 @@
4446

4547

4648
if TYPE_CHECKING:
47-
import datetime
48-
4949
from . import abc
5050
from .emoji import GuildEmoji
5151
from .guild import Guild
@@ -209,6 +209,14 @@ def _transform_trigger_metadata(
209209
return AutoModTriggerMetadata.from_dict(data)
210210

211211

212+
def _transform_communication_disabled_until(
213+
entry: AuditLogEntry, data: str
214+
) -> datetime.datetime | None:
215+
if data:
216+
return datetime.datetime.fromisoformat(data)
217+
return None
218+
219+
212220
class AuditLogDiff:
213221
def __len__(self) -> int:
214222
return len(self.__dict__)
@@ -281,6 +289,7 @@ class AuditLogChanges:
281289
"trigger_metadata": (None, _transform_trigger_metadata),
282290
"exempt_roles": (None, _transform_roles),
283291
"exempt_channels": (None, _transform_channels),
292+
"communication_disabled_until": (None, _transform_communication_disabled_until),
284293
}
285294

286295
def __init__(
@@ -636,7 +645,7 @@ def category(self) -> enums.AuditLogActionCategory:
636645
"""The category of the action, if applicable."""
637646
return self.action.category
638647

639-
@property
648+
@cached_property
640649
def changes(self) -> AuditLogChanges:
641650
"""The list of changes this entry has."""
642651
obj = AuditLogChanges(self, self._changes, state=self._state)

discord/collectibles.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@ class Nameplate:
3939
4040
Attributes
4141
----------
42-
sku_id: int
43-
The SKU ID of the nameplate.
44-
palette: str
45-
The color palette of the nameplate.
42+
sku_id: :class:`int`
43+
The SKU ID of the nameplate.
44+
palette: :class:`str`
45+
The color palette of the nameplate.
4646
"""
4747

4848
def __init__(self, data: NameplatePayload, state: "ConnectionState") -> None:

discord/http.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -888,7 +888,7 @@ def pin_message(
888888
) -> Response[None]:
889889
r = Route(
890890
"PUT",
891-
"/channels/{channel_id}/pins/{message_id}",
891+
"/channels/{channel_id}/messages/pins/{message_id}",
892892
channel_id=channel_id,
893893
message_id=message_id,
894894
)
@@ -899,13 +899,30 @@ def unpin_message(
899899
) -> Response[None]:
900900
r = Route(
901901
"DELETE",
902-
"/channels/{channel_id}/pins/{message_id}",
902+
"/channels/{channel_id}/messages/pins/{message_id}",
903903
channel_id=channel_id,
904904
message_id=message_id,
905905
)
906906
return self.request(r, reason=reason)
907907

908-
def pins_from(self, channel_id: Snowflake) -> Response[list[message.Message]]:
908+
def pins_from(
909+
self,
910+
channel_id: Snowflake,
911+
limit: int | None = None,
912+
before: str | None = None,
913+
) -> Response[message.MessagePinPagination]:
914+
r = Route("GET", "/channels/{channel_id}/messages/pins", channel_id=channel_id)
915+
params = {}
916+
if limit:
917+
params["limit"] = limit
918+
if before:
919+
params["before"] = before
920+
921+
return self.request(r, params=params)
922+
923+
def legacy_pins_from(
924+
self, channel_id: Snowflake
925+
) -> Response[list[message.Message]]:
909926
return self.request(
910927
Route("GET", "/channels/{channel_id}/pins", channel_id=channel_id)
911928
)

0 commit comments

Comments
 (0)