From 91652e3b6017ac68f5a183ce6541e055b4b53ec7 Mon Sep 17 00:00:00 2001 From: JustAnyone Date: Sun, 22 Aug 2021 13:49:42 +0300 Subject: [PATCH] Add per-guild member avatar support Fix #7054 --- discord/asset.py | 11 +++++++++++ discord/member.py | 26 ++++++++++++++++++++++++++ discord/user.py | 12 ++++++++++++ 3 files changed, 49 insertions(+) diff --git a/discord/asset.py b/discord/asset.py index 8aa439144f39..c58cfd3643ef 100644 --- a/discord/asset.py +++ b/discord/asset.py @@ -177,6 +177,17 @@ def _from_avatar(cls, state, user_id: int, avatar: str) -> Asset: animated=animated, ) + @classmethod + def _from_guild_avatar(cls, state, guild_id: int, member_id: int, avatar: str) -> Asset: + animated = avatar.startswith('a_') + format = 'gif' if animated else 'png' + return cls( + state, + url=f"{cls.BASE}/guilds/{guild_id}/users/{member_id}/avatars/{avatar}.{format}?size=1024", + key=avatar, + animated=animated, + ) + @classmethod def _from_icon(cls, state, object_id: int, icon_hash: str, path: str) -> Asset: return cls( diff --git a/discord/member.py b/discord/member.py index 6a5afa425219..fa4df1c7a9fc 100644 --- a/discord/member.py +++ b/discord/member.py @@ -34,6 +34,7 @@ import discord.abc from . import utils +from .asset import Asset from .utils import MISSING from .user import BaseUser, User, _UserTag from .activity import create_activity, ActivityTypes @@ -263,6 +264,7 @@ class Member(discord.abc.Messageable, _UserTag): '_client_status', '_user', '_state', + '_avatar', ) if TYPE_CHECKING: @@ -293,6 +295,7 @@ def __init__(self, *, data: GatewayMemberPayload, guild: Guild, state: Connectio self.activities: Tuple[ActivityTypes, ...] = tuple() self.nick: Optional[str] = data.get('nick', None) self.pending: bool = data.get('pending', False) + self._avatar: Optional[str] = data.get("avatar", None) def __str__(self) -> str: return str(self._user) @@ -498,6 +501,29 @@ def display_name(self) -> str: """ return self.nick or self.name + @property + def display_avatar(self) -> Asset: + """:class:`Asset`: Returns the member's display avatar. + + For regular members this is just their avatar, but + if they have a guild specific avatar then that + is returned instead. + + .. versionadded:: 2.0 + """ + return self.guild_avatar or self.avatar + + @property + def guild_avatar(self) -> Optional[Asset]: + """Optional[:class:`Asset`:] Returns an :class:`Asset` for the guild avatar + the member has if available. + + .. versionadded:: 2.0 + """ + if self._avatar is None: + return None + return Asset._from_guild_avatar(self._state, self.guild.id, self.id, self._avatar) + @property def activity(self) -> Optional[ActivityTypes]: """Optional[Union[:class:`BaseActivity`, :class:`Spotify`]]: Returns the primary diff --git a/discord/user.py b/discord/user.py index 03a81fc957e7..83fb8fd4c4bc 100644 --- a/discord/user.py +++ b/discord/user.py @@ -238,6 +238,18 @@ def display_name(self) -> str: """ return self.name + @property + def display_avatar(self) -> Asset: + """:class:`Asset`: Returns the user's display avatar. + + For regular users this is just their avatar, but + if they have a guild specific avatar then that + is returned instead. + + .. versionadded:: 2.0 + """ + return self.avatar + def mentioned_in(self, message: Message) -> bool: """Checks if the user is mentioned in the specified message.