Skip to content

Commit

Permalink
feat(member): implement member banners (#1204)
Browse files Browse the repository at this point in the history
Signed-off-by: Snipy7374 <[email protected]>
  • Loading branch information
Snipy7374 authored Nov 16, 2024
1 parent aedc1d1 commit ac5a936
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 0 deletions.
1 change: 1 addition & 0 deletions changelog/1203.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Implement new :attr:`.Member.guild_banner` property.
13 changes: 13 additions & 0 deletions disnake/asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,19 @@ def _from_guild_avatar(
animated=animated,
)

@classmethod
def _from_guild_banner(
cls, state: AnyState, guild_id: int, member_id: int, banner: str
) -> Self:
animated = banner.startswith("a_")
format = "gif" if animated else "png"
return cls(
state,
url=f"{cls.BASE}/guilds/{guild_id}/users/{member_id}/banners/{banner}.{format}?size=1024",
key=banner,
animated=animated,
)

@classmethod
def _from_icon(cls, state: AnyState, object_id: int, icon_hash: str, path: str) -> Self:
return cls(
Expand Down
19 changes: 19 additions & 0 deletions disnake/member.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ class Member(disnake.abc.Messageable, _UserTag):
"_user",
"_state",
"_avatar",
"_banner",
"_communication_disabled_until",
"_flags",
"_avatar_decoration_data",
Expand Down Expand Up @@ -340,6 +341,7 @@ def __init__(
self.nick: Optional[str] = data.get("nick")
self.pending: bool = data.get("pending", False)
self._avatar: Optional[str] = data.get("avatar")
self._banner: Optional[str] = data.get("banner")
timeout_datetime = utils.parse_time(data.get("communication_disabled_until"))
self._communication_disabled_until: Optional[datetime.datetime] = timeout_datetime
self._flags: int = data.get("flags", 0)
Expand Down Expand Up @@ -409,6 +411,7 @@ def _copy(cls, member: Member) -> Self:
self.activities = member.activities
self._state = member._state
self._avatar = member._avatar
self._banner = member._banner
self._communication_disabled_until = member.current_timeout
self._flags = member._flags

Expand Down Expand Up @@ -437,6 +440,7 @@ def _update(self, data: GuildMemberUpdateEvent) -> None:
self.premium_since = utils.parse_time(data.get("premium_since"))
self._roles = utils.SnowflakeList(map(int, data["roles"]))
self._avatar = data.get("avatar")
self._banner = data.get("banner")
timeout_datetime = utils.parse_time(data.get("communication_disabled_until"))
self._communication_disabled_until = timeout_datetime
self._flags = data.get("flags", 0)
Expand Down Expand Up @@ -619,6 +623,21 @@ def guild_avatar(self) -> Optional[Asset]:
return None
return Asset._from_guild_avatar(self._state, self.guild.id, self.id, self._avatar)

# TODO
# implement a `display_banner` property
# for more info on why this wasn't implemented read this discussion
# https://github.com/DisnakeDev/disnake/pull/1204#discussion_r1685773429
@property
def guild_banner(self) -> Optional[Asset]:
"""Optional[:class:`Asset`]: Returns an :class:`Asset` for the guild banner
the member has. If unavailable, ``None`` is returned.
.. versionadded:: 2.10
"""
if self._banner is None:
return None
return Asset._from_guild_banner(self._state, self.guild.id, self.id, self._banner)

@property
def activity(self) -> Optional[ActivityTypes]:
"""Optional[Union[:class:`BaseActivity`, :class:`Spotify`]]: Returns the primary
Expand Down
1 change: 1 addition & 0 deletions disnake/types/gateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,7 @@ class GuildMemberUpdateEvent(TypedDict):
user: User
nick: NotRequired[Optional[str]]
avatar: Optional[str]
banner: Optional[str]
joined_at: Optional[str]
premium_since: NotRequired[Optional[str]]
deaf: NotRequired[bool]
Expand Down

0 comments on commit ac5a936

Please sign in to comment.