Browse Source

Make it paginate instead using the after param

pull/10205/head
Soheab_ 4 weeks ago
parent
commit
e59658418c
  1. 110
      discord/abc.py
  2. 5
      discord/http.py

110
discord/abc.py

@ -1710,15 +1710,20 @@ class Messageable:
data = await self._state.http.get_message(channel.id, id)
return self._state.create_message(channel=channel, data=data)
async def pins(self, *, before: Optional[datetime] = None, limit: Optional[int] = None) -> List[Message]:
"""|coro|
Retrieves a maximum of 50 pinned messages from the destination.
async def pins(
self,
*,
limit: Optional[int] = None,
before: SnowflakeTime = MISSING,
after: SnowflakeTime = MISSING,
) -> AsyncIterator[Message]:
"""Retrieves an :term:`asynchronous iterator` of the pinned messages in the channel.
Requires the :attr:`~discord.Permissions.view_channel` permission.
You must have :attr:`~discord.Permissions.view_channel` and
:attr:`~discord.Permissions.read_message_history` to get these.
No pins will be returned if the user is missing the
:attr:`~discord.Permissions.read_message_history` permission.
.. versionchanged:: 2.6
Due to a change in Discord's API, this now returns a paginated iterator instead of a list.
.. note::
@ -1729,15 +1734,22 @@ class Messageable:
Parameters
-----------
before: Optional[:class:`datetime.datetime`]
Retrieve pinned messages before this time.
Retrieve pinned messages before this time or snowflake.
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.
.. versionadded:: 2.6
limit: Optional[int]
The maximum number of pinned messages to retrieve. Defaults to 50.
after: Optional[:class:`datetime.datetime`]
Retrieve pinned messages after this time or snowflake.
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.
This must be a number between 2 and 50.
.. versionadded:: 2.6
limit: Optional[int]
The number of pinned messages to retrieve. If ``None``, it retrieves
every pinned message in the channel. Note, however, that this would
make it a slow operation.
Defaults to ``50``.
.. versionadded:: 2.6
@ -1755,23 +1767,69 @@ class Messageable:
List[:class:`~discord.Message`]
The messages that are currently pinned.
"""
if before is not None:
if not isinstance(before, datetime):
raise TypeError(f'before must be a datetime object, not {before.__class__!r}')
if before.tzinfo is None:
raise TypeError(
'before must be an aware datetime. Consider using discord.utils.utcnow() or datetime.datetime.now().astimezone() for local time.'
)
if before is not MISSING and after is not MISSING:
raise TypeError('pins pagination does not support both before and after')
state = self._state
endpoint = self._state.http.pins_from
channel = await self._get_channel()
data = await state.http.pins_from(channel.id, before=before.isoformat() if before else None, limit=limit)
ret: List[Message] = []
for m in data["items"]:
message = state.create_message(channel=channel, data=m["message"])
message._pinned_at = utils.parse_time(m.get("pinned_at"))
ret.append(message)
return ret
state = self._state
async def _before_strategy(retrieve: int, before: Optional[SnowflakeTime], limit: Optional[int]):
before_time = (
before.isoformat()
if isinstance(before, datetime)
else utils.snowflake_time(before.id).isoformat()
if before
else None
)
data = await endpoint(channel.id, limit=retrieve, before=before_time)
if data and data['items']:
if limit is not None:
limit -= len(data)
before = utils.parse_time(data['items'][-1]['pinned_at'])
return data, before, limit
async def _after_strategy(retrieve: int, after: Optional[SnowflakeTime], limit: Optional[int]):
after_time = (
after.isoformat()
if isinstance(after, datetime)
else utils.snowflake_time(after.id).isoformat()
if after
else None
)
data = await endpoint(channel.id, limit=retrieve, after=after_time)
if data and data['items']:
if limit is not None:
limit -= len(data)
after = utils.parse_time(data['items'][-1]['pinned_at'])
return data, after, limit
if before:
strategy, time = _before_strategy, before
else:
strategy, time = _after_strategy, after
while True:
retrieve = 50 if limit is None else min(limit, 50)
if retrieve < 1:
return
data, time, limit = await strategy(retrieve, time, limit)
# Terminate loop on next iteration; there's no data left after this
if len(data) < 50:
limit = 0
for m in data["items"]:
message = state.create_message(channel=channel, data=m['message'])
message._pinned_at = utils.parse_time(m['pinned_at'])
yield message
async def history(
self,

5
discord/http.py

@ -1059,12 +1059,15 @@ class HTTPClient:
def pins_from(
self,
channel_id: Snowflake,
before: Optional[str] = None,
limit: Optional[int] = None,
before: Optional[str] = None,
after: Optional[str] = None,
) -> Response[message.ChannelPins]:
params = {}
if before is not None:
params['before'] = before
if after is not None:
params['after'] = after
if limit is not None:
params['limit'] = limit

Loading…
Cancel
Save