Add guild prune support (#108)

This commit is contained in:
Slipstream 2025-06-15 18:49:41 -06:00 committed by GitHub
parent cc17d11509
commit 3f7c286322
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 126 additions and 19 deletions

View File

@ -917,6 +917,29 @@ class HTTPClient:
custom_headers=headers,
)
async def get_guild_prune_count(self, guild_id: "Snowflake", *, days: int) -> int:
"""Returns the number of members that would be pruned."""
data = await self.request(
"GET",
f"/guilds/{guild_id}/prune",
params={"days": days},
)
return int(data.get("pruned", 0))
async def begin_guild_prune(
self, guild_id: "Snowflake", *, days: int, compute_count: bool = True
) -> int:
"""Begins a prune operation for the guild and returns the count."""
payload = {"days": days, "compute_prune_count": compute_count}
data = await self.request(
"POST",
f"/guilds/{guild_id}/prune",
payload=payload,
)
return int(data.get("pruned", 0))
async def get_guild_roles(self, guild_id: "Snowflake") -> List[Dict[str, Any]]:
"""Returns a list of role objects for the guild."""
return await self.request("GET", f"/guilds/{guild_id}/roles")

View File

@ -1349,6 +1349,26 @@ class Guild:
del self._client._gateway._member_chunk_requests[nonce]
raise
async def prune_members(self, days: int, *, compute_count: bool = True) -> int:
"""|coro| Remove inactive members from the guild.
Parameters
----------
days: int
Number of days of inactivity required to be pruned.
compute_count: bool
Whether to return the number of members pruned.
Returns
-------
int
The number of members pruned.
"""
return await self._client._http.begin_guild_prune(
self.id, days=days, compute_count=compute_count
)
class Channel:
"""Base class for Discord channels."""

64
tests/test_guild_prune.py Normal file
View File

@ -0,0 +1,64 @@
import pytest
from types import SimpleNamespace
from unittest.mock import AsyncMock
from disagreement.http import HTTPClient
from disagreement.client import Client
from disagreement.enums import (
VerificationLevel,
MessageNotificationLevel,
ExplicitContentFilterLevel,
MFALevel,
GuildNSFWLevel,
PremiumTier,
)
from disagreement.models import Guild
@pytest.mark.asyncio
async def test_http_get_guild_prune_count_calls_request():
http = HTTPClient(token="t")
http.request = AsyncMock(return_value={"pruned": 3})
count = await http.get_guild_prune_count("1", days=7)
http.request.assert_called_once_with("GET", f"/guilds/1/prune", params={"days": 7})
assert count == 3
@pytest.mark.asyncio
async def test_http_begin_guild_prune_calls_request():
http = HTTPClient(token="t")
http.request = AsyncMock(return_value={"pruned": 2})
count = await http.begin_guild_prune("1", days=1, compute_count=True)
http.request.assert_called_once_with(
"POST",
f"/guilds/1/prune",
payload={"days": 1, "compute_prune_count": True},
)
assert count == 2
@pytest.mark.asyncio
async def test_guild_prune_members_calls_http():
http = SimpleNamespace(begin_guild_prune=AsyncMock(return_value=1))
client = Client(token="t")
client._http = http
guild_data = {
"id": "1",
"name": "g",
"owner_id": "1",
"afk_timeout": 60,
"verification_level": VerificationLevel.NONE.value,
"default_message_notifications": MessageNotificationLevel.ALL_MESSAGES.value,
"explicit_content_filter": ExplicitContentFilterLevel.DISABLED.value,
"roles": [],
"emojis": [],
"features": [],
"mfa_level": MFALevel.NONE.value,
"system_channel_flags": 0,
"premium_tier": PremiumTier.NONE.value,
"nsfw_level": GuildNSFWLevel.DEFAULT.value,
}
guild = Guild(guild_data, client_instance=client)
count = await guild.prune_members(2)
http.begin_guild_prune.assert_awaited_once_with("1", days=2, compute_count=True)
assert count == 1