Implement channel and member aggregation (#117)
This commit is contained in:
parent
d710487fc2
commit
8e88aaec2f
@ -84,9 +84,9 @@ class MemberCache(Cache["Member"]):
|
|||||||
|
|
||||||
def _should_cache(self, member: Member) -> bool:
|
def _should_cache(self, member: Member) -> bool:
|
||||||
"""Determines if a member should be cached based on the flags."""
|
"""Determines if a member should be cached based on the flags."""
|
||||||
if self.flags.all:
|
if self.flags.all_enabled:
|
||||||
return True
|
return True
|
||||||
if self.flags.none:
|
if self.flags.no_flags:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if self.flags.online and member.status != "offline":
|
if self.flags.online and member.status != "offline":
|
||||||
|
@ -74,6 +74,14 @@ class MemberCacheFlags:
|
|||||||
for name in self.VALID_FLAGS:
|
for name in self.VALID_FLAGS:
|
||||||
yield name, getattr(self, name)
|
yield name, getattr(self, name)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def all_enabled(self) -> bool:
|
||||||
|
return self.value == self.ALL_FLAGS
|
||||||
|
|
||||||
|
@property
|
||||||
|
def no_flags(self) -> bool:
|
||||||
|
return self.value == 0
|
||||||
|
|
||||||
def __int__(self) -> int:
|
def __int__(self) -> int:
|
||||||
return self.value
|
return self.value
|
||||||
|
|
||||||
|
@ -1448,10 +1448,30 @@ class Client:
|
|||||||
|
|
||||||
return self._channels.get(channel_id)
|
return self._channels.get(channel_id)
|
||||||
|
|
||||||
def get_message(self, message_id: Snowflake) -> Optional["Message"]:
|
def get_message(self, message_id: Snowflake) -> Optional["Message"]:
|
||||||
"""Returns a message from the internal cache."""
|
"""Returns a message from the internal cache."""
|
||||||
|
|
||||||
return self._messages.get(message_id)
|
return self._messages.get(message_id)
|
||||||
|
|
||||||
|
def get_all_channels(self) -> List["Channel"]:
|
||||||
|
"""Return all channels cached in every guild."""
|
||||||
|
|
||||||
|
channels: List["Channel"] = []
|
||||||
|
for guild in self._guilds.values():
|
||||||
|
channels.extend(guild._channels.values())
|
||||||
|
return channels
|
||||||
|
|
||||||
|
def get_all_members(self) -> List["Member"]:
|
||||||
|
"""Return all cached members across all guilds.
|
||||||
|
|
||||||
|
When member caching is disabled via :class:`MemberCacheFlags.none`, this
|
||||||
|
list will always be empty.
|
||||||
|
"""
|
||||||
|
|
||||||
|
members: List["Member"] = []
|
||||||
|
for guild in self._guilds.values():
|
||||||
|
members.extend(guild._members.values())
|
||||||
|
return members
|
||||||
|
|
||||||
async def fetch_guild(self, guild_id: Snowflake) -> Optional["Guild"]:
|
async def fetch_guild(self, guild_id: Snowflake) -> Optional["Guild"]:
|
||||||
"""Fetches a guild by ID from Discord and caches it."""
|
"""Fetches a guild by ID from Discord and caches it."""
|
||||||
|
@ -656,21 +656,21 @@ class HTTPClient:
|
|||||||
|
|
||||||
await self.request("PUT", f"/channels/{channel_id}/pins/{message_id}")
|
await self.request("PUT", f"/channels/{channel_id}/pins/{message_id}")
|
||||||
|
|
||||||
async def unpin_message(
|
async def unpin_message(
|
||||||
self, channel_id: "Snowflake", message_id: "Snowflake"
|
self, channel_id: "Snowflake", message_id: "Snowflake"
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Unpins a message from a channel."""
|
"""Unpins a message from a channel."""
|
||||||
|
|
||||||
await self.request("DELETE", f"/channels/{channel_id}/pins/{message_id}")
|
await self.request("DELETE", f"/channels/{channel_id}/pins/{message_id}")
|
||||||
|
|
||||||
async def crosspost_message(
|
async def crosspost_message(
|
||||||
self, channel_id: "Snowflake", message_id: "Snowflake"
|
self, channel_id: "Snowflake", message_id: "Snowflake"
|
||||||
) -> Dict[str, Any]:
|
) -> Dict[str, Any]:
|
||||||
"""Crossposts a message to any following channels."""
|
"""Crossposts a message to any following channels."""
|
||||||
|
|
||||||
return await self.request(
|
return await self.request(
|
||||||
"POST", f"/channels/{channel_id}/messages/{message_id}/crosspost"
|
"POST", f"/channels/{channel_id}/messages/{message_id}/crosspost"
|
||||||
)
|
)
|
||||||
|
|
||||||
async def delete_channel(
|
async def delete_channel(
|
||||||
self, channel_id: str, reason: Optional[str] = None
|
self, channel_id: str, reason: Optional[str] = None
|
||||||
@ -734,63 +734,68 @@ class HTTPClient:
|
|||||||
|
|
||||||
return await self.request("GET", f"/channels/{channel_id}/invites")
|
return await self.request("GET", f"/channels/{channel_id}/invites")
|
||||||
|
|
||||||
async def create_invite(
|
async def create_invite(
|
||||||
self, channel_id: "Snowflake", payload: Dict[str, Any]
|
self, channel_id: "Snowflake", payload: Dict[str, Any]
|
||||||
) -> "Invite":
|
) -> "Invite":
|
||||||
"""Creates an invite for a channel."""
|
"""Creates an invite for a channel."""
|
||||||
|
|
||||||
data = await self.request(
|
data = await self.request(
|
||||||
"POST", f"/channels/{channel_id}/invites", payload=payload
|
"POST", f"/channels/{channel_id}/invites", payload=payload
|
||||||
)
|
)
|
||||||
from .models import Invite
|
from .models import Invite
|
||||||
|
|
||||||
return Invite.from_dict(data)
|
|
||||||
|
|
||||||
async def create_channel_invite(
|
|
||||||
self,
|
|
||||||
channel_id: "Snowflake",
|
|
||||||
payload: Dict[str, Any],
|
|
||||||
*,
|
|
||||||
reason: Optional[str] = None,
|
|
||||||
) -> "Invite":
|
|
||||||
"""Creates an invite for a channel with an optional audit log reason."""
|
|
||||||
|
|
||||||
headers = {"X-Audit-Log-Reason": reason} if reason else None
|
|
||||||
data = await self.request(
|
|
||||||
"POST",
|
|
||||||
f"/channels/{channel_id}/invites",
|
|
||||||
payload=payload,
|
|
||||||
custom_headers=headers,
|
|
||||||
)
|
|
||||||
from .models import Invite
|
|
||||||
|
|
||||||
return Invite.from_dict(data)
|
|
||||||
|
|
||||||
async def delete_invite(self, code: str) -> None:
|
return Invite.from_dict(data)
|
||||||
"""Deletes an invite by code."""
|
|
||||||
|
|
||||||
await self.request("DELETE", f"/invites/{code}")
|
|
||||||
|
|
||||||
async def get_invite(self, code: "Snowflake") -> Dict[str, Any]:
|
|
||||||
"""Fetches a single invite by its code."""
|
|
||||||
|
|
||||||
return await self.request("GET", f"/invites/{code}")
|
|
||||||
|
|
||||||
async def create_webhook(
|
async def create_channel_invite(
|
||||||
self, channel_id: "Snowflake", payload: Dict[str, Any]
|
self,
|
||||||
) -> "Webhook":
|
channel_id: "Snowflake",
|
||||||
"""Creates a webhook in the specified channel."""
|
payload: Dict[str, Any],
|
||||||
|
*,
|
||||||
|
reason: Optional[str] = None,
|
||||||
|
) -> "Invite":
|
||||||
|
"""Creates an invite for a channel with an optional audit log reason."""
|
||||||
|
|
||||||
|
headers = {"X-Audit-Log-Reason": reason} if reason else None
|
||||||
|
data = await self.request(
|
||||||
|
"POST",
|
||||||
|
f"/channels/{channel_id}/invites",
|
||||||
|
payload=payload,
|
||||||
|
custom_headers=headers,
|
||||||
|
)
|
||||||
|
from .models import Invite
|
||||||
|
|
||||||
|
return Invite.from_dict(data)
|
||||||
|
|
||||||
|
async def delete_invite(self, code: str) -> None:
|
||||||
|
"""Deletes an invite by code."""
|
||||||
|
|
||||||
|
await self.request("DELETE", f"/invites/{code}")
|
||||||
|
|
||||||
|
async def get_invite(self, code: "Snowflake") -> Dict[str, Any]:
|
||||||
|
"""Fetches a single invite by its code."""
|
||||||
|
|
||||||
|
return await self.request("GET", f"/invites/{code}")
|
||||||
|
|
||||||
|
async def create_webhook(
|
||||||
|
self, channel_id: "Snowflake", payload: Dict[str, Any]
|
||||||
|
) -> "Webhook":
|
||||||
|
"""Creates a webhook in the specified channel."""
|
||||||
|
|
||||||
data = await self.request(
|
data = await self.request(
|
||||||
"POST", f"/channels/{channel_id}/webhooks", payload=payload
|
"POST", f"/channels/{channel_id}/webhooks", payload=payload
|
||||||
)
|
)
|
||||||
from .models import Webhook
|
from .models import Webhook
|
||||||
|
|
||||||
return Webhook(data)
|
return Webhook(data)
|
||||||
|
|
||||||
async def edit_webhook(
|
async def get_webhook(self, webhook_id: "Snowflake") -> Dict[str, Any]:
|
||||||
self, webhook_id: "Snowflake", payload: Dict[str, Any]
|
"""Fetches a webhook by ID and returns the raw payload."""
|
||||||
) -> "Webhook":
|
|
||||||
|
return await self.request("GET", f"/webhooks/{webhook_id}")
|
||||||
|
|
||||||
|
async def edit_webhook(
|
||||||
|
self, webhook_id: "Snowflake", payload: Dict[str, Any]
|
||||||
|
) -> "Webhook":
|
||||||
"""Edits an existing webhook."""
|
"""Edits an existing webhook."""
|
||||||
|
|
||||||
data = await self.request("PATCH", f"/webhooks/{webhook_id}", payload=payload)
|
data = await self.request("PATCH", f"/webhooks/{webhook_id}", payload=payload)
|
||||||
@ -798,28 +803,28 @@ class HTTPClient:
|
|||||||
|
|
||||||
return Webhook(data)
|
return Webhook(data)
|
||||||
|
|
||||||
async def delete_webhook(self, webhook_id: "Snowflake") -> None:
|
async def delete_webhook(self, webhook_id: "Snowflake") -> None:
|
||||||
"""Deletes a webhook."""
|
"""Deletes a webhook."""
|
||||||
|
|
||||||
await self.request("DELETE", f"/webhooks/{webhook_id}")
|
await self.request("DELETE", f"/webhooks/{webhook_id}")
|
||||||
|
|
||||||
async def get_webhook(
|
async def get_webhook_with_token(
|
||||||
self, webhook_id: "Snowflake", token: Optional[str] = None
|
self, webhook_id: "Snowflake", token: Optional[str] = None
|
||||||
) -> "Webhook":
|
) -> "Webhook":
|
||||||
"""Fetches a webhook by ID, optionally using its token."""
|
"""Fetches a webhook by ID, optionally using its token."""
|
||||||
|
|
||||||
endpoint = f"/webhooks/{webhook_id}"
|
endpoint = f"/webhooks/{webhook_id}"
|
||||||
use_auth = True
|
use_auth = True
|
||||||
if token is not None:
|
if token is not None:
|
||||||
endpoint += f"/{token}"
|
endpoint += f"/{token}"
|
||||||
use_auth = False
|
use_auth = False
|
||||||
if use_auth:
|
if use_auth:
|
||||||
data = await self.request("GET", endpoint)
|
data = await self.request("GET", endpoint)
|
||||||
else:
|
else:
|
||||||
data = await self.request("GET", endpoint, use_auth_header=False)
|
data = await self.request("GET", endpoint, use_auth_header=False)
|
||||||
from .models import Webhook
|
from .models import Webhook
|
||||||
|
|
||||||
return Webhook(data)
|
return Webhook(data)
|
||||||
|
|
||||||
async def execute_webhook(
|
async def execute_webhook(
|
||||||
self,
|
self,
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
"""
|
"""
|
||||||
Data models for Discord objects.
|
Data models for Discord objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import datetime
|
import datetime
|
||||||
@ -49,14 +49,14 @@ from .enums import ( # These enums will need to be defined in disagreement/enum
|
|||||||
from .permissions import Permissions
|
from .permissions import Permissions
|
||||||
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .client import Client # For type hinting to avoid circular imports
|
from .client import Client # For type hinting to avoid circular imports
|
||||||
from .enums import OverwriteType # For PermissionOverwrite model
|
from .enums import OverwriteType # For PermissionOverwrite model
|
||||||
from .ui.view import View
|
from .ui.view import View
|
||||||
from .interactions import Snowflake
|
from .interactions import Snowflake
|
||||||
from .typing import Typing
|
from .typing import Typing
|
||||||
from .shard_manager import Shard
|
from .shard_manager import Shard
|
||||||
from .asset import Asset
|
from .asset import Asset
|
||||||
|
|
||||||
# Forward reference Message if it were used in type hints before its definition
|
# Forward reference Message if it were used in type hints before its definition
|
||||||
# from .models import Message # Not needed as Message is defined before its use in TextChannel.send etc.
|
# from .models import Message # Not needed as Message is defined before its use in TextChannel.send etc.
|
||||||
@ -104,23 +104,23 @@ class User(HashableById):
|
|||||||
return f"<User id='{self.id}' username='{username}' discriminator='{disc}'>"
|
return f"<User id='{self.id}' username='{username}' discriminator='{disc}'>"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def avatar(self) -> Optional["Asset"]:
|
def avatar(self) -> Optional["Asset"]:
|
||||||
"""Return the user's avatar as an :class:`Asset`."""
|
"""Return the user's avatar as an :class:`Asset`."""
|
||||||
|
|
||||||
if self._avatar:
|
if self._avatar:
|
||||||
from .asset import Asset
|
from .asset import Asset
|
||||||
|
|
||||||
return Asset(self._avatar, self._client)
|
return Asset(self._avatar, self._client)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@avatar.setter
|
@avatar.setter
|
||||||
def avatar(self, value: Optional[Union[str, "Asset"]]) -> None:
|
def avatar(self, value: Optional[Union[str, "Asset"]]) -> None:
|
||||||
if isinstance(value, str):
|
if isinstance(value, str):
|
||||||
self._avatar = value
|
self._avatar = value
|
||||||
elif value is None:
|
elif value is None:
|
||||||
self._avatar = None
|
self._avatar = None
|
||||||
else:
|
else:
|
||||||
self._avatar = value.url
|
self._avatar = value.url
|
||||||
|
|
||||||
async def send(
|
async def send(
|
||||||
self,
|
self,
|
||||||
@ -843,21 +843,21 @@ class Role:
|
|||||||
return f"<Role id='{self.id}' name='{self.name}'>"
|
return f"<Role id='{self.id}' name='{self.name}'>"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def icon(self) -> Optional["Asset"]:
|
def icon(self) -> Optional["Asset"]:
|
||||||
if self._icon:
|
if self._icon:
|
||||||
from .asset import Asset
|
from .asset import Asset
|
||||||
|
|
||||||
return Asset(self._icon, None)
|
return Asset(self._icon, None)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@icon.setter
|
@icon.setter
|
||||||
def icon(self, value: Optional[Union[str, "Asset"]]) -> None:
|
def icon(self, value: Optional[Union[str, "Asset"]]) -> None:
|
||||||
if isinstance(value, str):
|
if isinstance(value, str):
|
||||||
self._icon = value
|
self._icon = value
|
||||||
elif value is None:
|
elif value is None:
|
||||||
self._icon = None
|
self._icon = None
|
||||||
else:
|
else:
|
||||||
self._icon = value.url
|
self._icon = value.url
|
||||||
|
|
||||||
|
|
||||||
class Member(User): # Member inherits from User
|
class Member(User): # Member inherits from User
|
||||||
@ -924,23 +924,23 @@ class Member(User): # Member inherits from User
|
|||||||
return f"<Member id='{self.id}' username='{self.username}' nick='{self.nick}'>"
|
return f"<Member id='{self.id}' username='{self.username}' nick='{self.nick}'>"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def avatar(self) -> Optional["Asset"]:
|
def avatar(self) -> Optional["Asset"]:
|
||||||
"""Return the member's avatar as an :class:`Asset`."""
|
"""Return the member's avatar as an :class:`Asset`."""
|
||||||
|
|
||||||
if self._avatar:
|
if self._avatar:
|
||||||
from .asset import Asset
|
from .asset import Asset
|
||||||
|
|
||||||
return Asset(self._avatar, self._client)
|
return Asset(self._avatar, self._client)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@avatar.setter
|
@avatar.setter
|
||||||
def avatar(self, value: Optional[Union[str, "Asset"]]) -> None:
|
def avatar(self, value: Optional[Union[str, "Asset"]]) -> None:
|
||||||
if isinstance(value, str):
|
if isinstance(value, str):
|
||||||
self._avatar = value
|
self._avatar = value
|
||||||
elif value is None:
|
elif value is None:
|
||||||
self._avatar = None
|
self._avatar = None
|
||||||
else:
|
else:
|
||||||
self._avatar = value.url
|
self._avatar = value.url
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def display_name(self) -> str:
|
def display_name(self) -> str:
|
||||||
@ -1034,10 +1034,10 @@ class Member(User): # Member inherits from User
|
|||||||
return Permissions(~0)
|
return Permissions(~0)
|
||||||
|
|
||||||
return base
|
return base
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def voice(self) -> Optional["VoiceState"]:
|
def voice(self) -> Optional["VoiceState"]:
|
||||||
"""Return the member's cached voice state as a :class:`VoiceState`."""
|
"""Return the member's cached voice state as a :class:`VoiceState`."""
|
||||||
|
|
||||||
if self.voice_state is None:
|
if self.voice_state is None:
|
||||||
return None
|
return None
|
||||||
@ -1466,72 +1466,72 @@ class Guild(HashableById):
|
|||||||
return f"<Guild id='{self.id}' name='{self.name}'>"
|
return f"<Guild id='{self.id}' name='{self.name}'>"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def icon(self) -> Optional["Asset"]:
|
def icon(self) -> Optional["Asset"]:
|
||||||
if self._icon:
|
if self._icon:
|
||||||
from .asset import Asset
|
from .asset import Asset
|
||||||
|
|
||||||
return Asset(self._icon, self._client)
|
return Asset(self._icon, self._client)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@icon.setter
|
@icon.setter
|
||||||
def icon(self, value: Optional[Union[str, "Asset"]]) -> None:
|
def icon(self, value: Optional[Union[str, "Asset"]]) -> None:
|
||||||
if isinstance(value, str):
|
if isinstance(value, str):
|
||||||
self._icon = value
|
self._icon = value
|
||||||
elif value is None:
|
elif value is None:
|
||||||
self._icon = None
|
self._icon = None
|
||||||
else:
|
else:
|
||||||
self._icon = value.url
|
self._icon = value.url
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def splash(self) -> Optional["Asset"]:
|
def splash(self) -> Optional["Asset"]:
|
||||||
if self._splash:
|
if self._splash:
|
||||||
from .asset import Asset
|
from .asset import Asset
|
||||||
|
|
||||||
return Asset(self._splash, self._client)
|
return Asset(self._splash, self._client)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@splash.setter
|
@splash.setter
|
||||||
def splash(self, value: Optional[Union[str, "Asset"]]) -> None:
|
def splash(self, value: Optional[Union[str, "Asset"]]) -> None:
|
||||||
if isinstance(value, str):
|
if isinstance(value, str):
|
||||||
self._splash = value
|
self._splash = value
|
||||||
elif value is None:
|
elif value is None:
|
||||||
self._splash = None
|
self._splash = None
|
||||||
else:
|
else:
|
||||||
self._splash = value.url
|
self._splash = value.url
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def discovery_splash(self) -> Optional["Asset"]:
|
def discovery_splash(self) -> Optional["Asset"]:
|
||||||
if self._discovery_splash:
|
if self._discovery_splash:
|
||||||
from .asset import Asset
|
from .asset import Asset
|
||||||
|
|
||||||
return Asset(self._discovery_splash, self._client)
|
return Asset(self._discovery_splash, self._client)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@discovery_splash.setter
|
@discovery_splash.setter
|
||||||
def discovery_splash(self, value: Optional[Union[str, "Asset"]]) -> None:
|
def discovery_splash(self, value: Optional[Union[str, "Asset"]]) -> None:
|
||||||
if isinstance(value, str):
|
if isinstance(value, str):
|
||||||
self._discovery_splash = value
|
self._discovery_splash = value
|
||||||
elif value is None:
|
elif value is None:
|
||||||
self._discovery_splash = None
|
self._discovery_splash = None
|
||||||
else:
|
else:
|
||||||
self._discovery_splash = value.url
|
self._discovery_splash = value.url
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def banner(self) -> Optional["Asset"]:
|
def banner(self) -> Optional["Asset"]:
|
||||||
if self._banner:
|
if self._banner:
|
||||||
from .asset import Asset
|
from .asset import Asset
|
||||||
|
|
||||||
return Asset(self._banner, self._client)
|
return Asset(self._banner, self._client)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@banner.setter
|
@banner.setter
|
||||||
def banner(self, value: Optional[Union[str, "Asset"]]) -> None:
|
def banner(self, value: Optional[Union[str, "Asset"]]) -> None:
|
||||||
if isinstance(value, str):
|
if isinstance(value, str):
|
||||||
self._banner = value
|
self._banner = value
|
||||||
elif value is None:
|
elif value is None:
|
||||||
self._banner = None
|
self._banner = None
|
||||||
else:
|
else:
|
||||||
self._banner = value.url
|
self._banner = value.url
|
||||||
|
|
||||||
async def fetch_widget(self) -> Dict[str, Any]:
|
async def fetch_widget(self) -> Dict[str, Any]:
|
||||||
"""|coro| Fetch this guild's widget settings."""
|
"""|coro| Fetch this guild's widget settings."""
|
||||||
@ -2280,23 +2280,23 @@ class Webhook:
|
|||||||
return f"<Webhook id='{self.id}' name='{self.name}'>"
|
return f"<Webhook id='{self.id}' name='{self.name}'>"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def avatar(self) -> Optional["Asset"]:
|
def avatar(self) -> Optional["Asset"]:
|
||||||
"""Return the webhook's avatar as an :class:`Asset`."""
|
"""Return the webhook's avatar as an :class:`Asset`."""
|
||||||
|
|
||||||
if self._avatar:
|
if self._avatar:
|
||||||
from .asset import Asset
|
from .asset import Asset
|
||||||
|
|
||||||
return Asset(self._avatar, self._client)
|
return Asset(self._avatar, self._client)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@avatar.setter
|
@avatar.setter
|
||||||
def avatar(self, value: Optional[Union[str, "Asset"]]) -> None:
|
def avatar(self, value: Optional[Union[str, "Asset"]]) -> None:
|
||||||
if isinstance(value, str):
|
if isinstance(value, str):
|
||||||
self._avatar = value
|
self._avatar = value
|
||||||
elif value is None:
|
elif value is None:
|
||||||
self._avatar = None
|
self._avatar = None
|
||||||
else:
|
else:
|
||||||
self._avatar = value.url
|
self._avatar = value.url
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_url(
|
def from_url(
|
||||||
|
@ -1,6 +1,60 @@
|
|||||||
import time
|
import time
|
||||||
|
|
||||||
from disagreement.cache import Cache
|
from disagreement.cache import Cache
|
||||||
|
from disagreement.client import Client
|
||||||
|
from disagreement.caching import MemberCacheFlags
|
||||||
|
from disagreement.enums import (
|
||||||
|
ChannelType,
|
||||||
|
ExplicitContentFilterLevel,
|
||||||
|
GuildNSFWLevel,
|
||||||
|
MFALevel,
|
||||||
|
MessageNotificationLevel,
|
||||||
|
PremiumTier,
|
||||||
|
VerificationLevel,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _guild_payload(gid: str, channel_count: int, member_count: int) -> dict:
|
||||||
|
base = {
|
||||||
|
"id": gid,
|
||||||
|
"name": f"g{gid}",
|
||||||
|
"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,
|
||||||
|
"channels": [],
|
||||||
|
"members": [],
|
||||||
|
}
|
||||||
|
for i in range(channel_count):
|
||||||
|
base["channels"].append(
|
||||||
|
{
|
||||||
|
"id": f"{gid}-c{i}",
|
||||||
|
"type": ChannelType.GUILD_TEXT.value,
|
||||||
|
"guild_id": gid,
|
||||||
|
"permission_overwrites": [],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
for i in range(member_count):
|
||||||
|
base["members"].append(
|
||||||
|
{
|
||||||
|
"user": {
|
||||||
|
"id": f"{gid}-m{i}",
|
||||||
|
"username": f"u{i}",
|
||||||
|
"discriminator": "0001",
|
||||||
|
},
|
||||||
|
"joined_at": "t",
|
||||||
|
"roles": [],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return base
|
||||||
|
|
||||||
|
|
||||||
def test_cache_store_and_get():
|
def test_cache_store_and_get():
|
||||||
@ -65,3 +119,22 @@ def test_get_or_fetch_fetches_expired_item():
|
|||||||
|
|
||||||
assert cache.get_or_fetch("c", fetch) == 3
|
assert cache.get_or_fetch("c", fetch) == 3
|
||||||
assert called
|
assert called
|
||||||
|
|
||||||
|
|
||||||
|
def test_client_get_all_channels_and_members():
|
||||||
|
client = Client(token="t")
|
||||||
|
client.parse_guild(_guild_payload("1", 2, 2))
|
||||||
|
client.parse_guild(_guild_payload("2", 1, 1))
|
||||||
|
|
||||||
|
channels = {c.id for c in client.get_all_channels()}
|
||||||
|
members = {m.id for m in client.get_all_members()}
|
||||||
|
|
||||||
|
assert channels == {"1-c0", "1-c1", "2-c0"}
|
||||||
|
assert members == {"1-m0", "1-m1", "2-m0"}
|
||||||
|
|
||||||
|
|
||||||
|
def test_client_get_all_members_disabled_cache():
|
||||||
|
client = Client(token="t", member_cache_flags=MemberCacheFlags.none())
|
||||||
|
client.parse_guild(_guild_payload("1", 1, 2))
|
||||||
|
|
||||||
|
assert client.get_all_members() == []
|
||||||
|
Loading…
x
Reference in New Issue
Block a user