mirror of
https://github.com/Rapptz/discord.py.git
synced 2025-07-11 12:28:03 +00:00
Support ban endpoint pagination
This commit is contained in:
parent
6ef2043b10
commit
9acf1db076
101
discord/guild.py
101
discord/guild.py
@ -2023,29 +2023,112 @@ class Guild(Hashable):
|
|||||||
channel: GuildChannel = factory(guild=self, state=self._state, data=data) # type: ignore # channel won't be a private channel
|
channel: GuildChannel = factory(guild=self, state=self._state, data=data) # type: ignore # channel won't be a private channel
|
||||||
return channel
|
return channel
|
||||||
|
|
||||||
async def bans(self) -> List[BanEntry]:
|
async def bans(
|
||||||
"""|coro|
|
self,
|
||||||
|
*,
|
||||||
Retrieves all the users that are banned from the guild as a :class:`list` of :class:`BanEntry`.
|
limit: Optional[int] = 1000,
|
||||||
|
before: Snowflake = MISSING,
|
||||||
|
after: Snowflake = MISSING,
|
||||||
|
) -> AsyncIterator[BanEntry]:
|
||||||
|
"""Retrieves an :term:`asynchronous iterator` of the users that are banned from the guild as a :class:`BanEntry`.
|
||||||
|
|
||||||
You must have the :attr:`~Permissions.ban_members` permission
|
You must have the :attr:`~Permissions.ban_members` permission
|
||||||
to get this information.
|
to get this information.
|
||||||
|
|
||||||
|
.. versionchanged:: 2.0
|
||||||
|
Due to a breaking change in Discord's API, this now returns a paginated iterator instead of a list.
|
||||||
|
|
||||||
|
Examples
|
||||||
|
---------
|
||||||
|
|
||||||
|
Usage ::
|
||||||
|
|
||||||
|
async for entry in guild.bans(limit=150):
|
||||||
|
print(entry.user, entry.reason)
|
||||||
|
|
||||||
|
Flattening into a list ::
|
||||||
|
|
||||||
|
bans = [entry async for entry in guild.bans(limit=2000)]
|
||||||
|
# bans is now a list of BanEntry...
|
||||||
|
|
||||||
|
All parameters are optional.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
-----------
|
||||||
|
limit: Optional[:class:`int`]
|
||||||
|
The number of bans to retrieve.
|
||||||
|
If ``None``, it retrieves every guild you have access to. Note, however,
|
||||||
|
that this would make it a slow operation.
|
||||||
|
Defaults to ``1000``.
|
||||||
|
before: :class:`.abc.Snowflake`
|
||||||
|
Retrieves bans before this user.
|
||||||
|
after: :class:`.abc.Snowflake`
|
||||||
|
Retrieve bans after this user.
|
||||||
|
|
||||||
Raises
|
Raises
|
||||||
-------
|
-------
|
||||||
Forbidden
|
Forbidden
|
||||||
You do not have proper permissions to get the information.
|
You do not have proper permissions to get the information.
|
||||||
HTTPException
|
HTTPException
|
||||||
An error occurred while fetching the information.
|
An error occurred while fetching the information.
|
||||||
|
TypeError
|
||||||
|
Both ``after`` and ``before`` were provided, as Discord does not
|
||||||
|
support this type of pagination.
|
||||||
|
|
||||||
Returns
|
Yields
|
||||||
--------
|
--------
|
||||||
List[:class:`BanEntry`]
|
:class:`BanEntry`
|
||||||
A list of :class:`BanEntry` objects.
|
The ban entry of the banned user.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
data: List[BanPayload] = await self._state.http.get_bans(self.id)
|
if before is not MISSING and after is not MISSING:
|
||||||
return [BanEntry(user=User(state=self._state, data=e['user']), reason=e['reason']) for e in data]
|
raise TypeError('bans pagination does not support both before and after')
|
||||||
|
|
||||||
|
# This endpoint paginates in ascending order.
|
||||||
|
endpoint = self._state.http.get_bans
|
||||||
|
|
||||||
|
async def _before_strategy(retrieve, before, limit):
|
||||||
|
before_id = before.id if before else None
|
||||||
|
data = await endpoint(self.id, limit=retrieve, before=before_id)
|
||||||
|
|
||||||
|
if data:
|
||||||
|
if limit is not None:
|
||||||
|
limit -= len(data)
|
||||||
|
|
||||||
|
before = Object(id=int(data[0]['user']['id']))
|
||||||
|
|
||||||
|
return data, before, limit
|
||||||
|
|
||||||
|
async def _after_strategy(retrieve, after, limit):
|
||||||
|
after_id = after.id if after else None
|
||||||
|
data = await endpoint(self.id, limit=retrieve, after=after_id)
|
||||||
|
|
||||||
|
if data:
|
||||||
|
if limit is not None:
|
||||||
|
limit -= len(data)
|
||||||
|
|
||||||
|
after = Object(id=int(data[-1]['user']['id']))
|
||||||
|
|
||||||
|
return data, after, limit
|
||||||
|
|
||||||
|
if before:
|
||||||
|
strategy, state = _before_strategy, before
|
||||||
|
else:
|
||||||
|
strategy, state = _after_strategy, after
|
||||||
|
|
||||||
|
while True:
|
||||||
|
retrieve = min(1000 if limit is None else limit, 1000)
|
||||||
|
if retrieve < 1:
|
||||||
|
return
|
||||||
|
|
||||||
|
data, state, limit = await strategy(retrieve, state, limit)
|
||||||
|
|
||||||
|
# Terminate loop on next iteration; there's no data left after this
|
||||||
|
if len(data) < 1000:
|
||||||
|
limit = 0
|
||||||
|
|
||||||
|
for e in data:
|
||||||
|
yield BanEntry(user=User(state=self._state, data=e['user']), reason=e['reason'])
|
||||||
|
|
||||||
async def prune_members(
|
async def prune_members(
|
||||||
self,
|
self,
|
||||||
|
@ -1175,8 +1175,22 @@ class HTTPClient:
|
|||||||
payload['icon'] = icon
|
payload['icon'] = icon
|
||||||
return self.request(Route('POST', '/guilds/templates/{code}', code=code), json=payload)
|
return self.request(Route('POST', '/guilds/templates/{code}', code=code), json=payload)
|
||||||
|
|
||||||
def get_bans(self, guild_id: Snowflake) -> Response[List[guild.Ban]]:
|
def get_bans(
|
||||||
return self.request(Route('GET', '/guilds/{guild_id}/bans', guild_id=guild_id))
|
self,
|
||||||
|
guild_id: Snowflake,
|
||||||
|
limit: int,
|
||||||
|
before: Optional[Snowflake] = None,
|
||||||
|
after: Optional[Snowflake] = None,
|
||||||
|
) -> Response[List[guild.Ban]]:
|
||||||
|
params: Dict[str, Any] = {
|
||||||
|
'limit': limit,
|
||||||
|
}
|
||||||
|
if before is not None:
|
||||||
|
params['before'] = before
|
||||||
|
if after is not None:
|
||||||
|
params['after'] = after
|
||||||
|
|
||||||
|
return self.request(Route('GET', '/guilds/{guild_id}/bans', guild_id=guild_id), params=params)
|
||||||
|
|
||||||
def get_ban(self, user_id: Snowflake, guild_id: Snowflake) -> Response[guild.Ban]:
|
def get_ban(self, user_id: Snowflake, guild_id: Snowflake) -> Response[guild.Ban]:
|
||||||
return self.request(Route('GET', '/guilds/{guild_id}/bans/{user_id}', guild_id=guild_id, user_id=user_id))
|
return self.request(Route('GET', '/guilds/{guild_id}/bans/{user_id}', guild_id=guild_id, user_id=user_id))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user