Browse Source

Add support member specific get and edit

pull/10285/head
Soheab_ 2 weeks ago
parent
commit
e023c48bb2
  1. 80
      discord/member.py
  2. 5
      discord/types/member.py

80
discord/member.py

@ -36,12 +36,13 @@ from .asset import Asset
from .utils import MISSING from .utils import MISSING
from .user import BaseUser, ClientUser, User, _UserTag from .user import BaseUser, ClientUser, User, _UserTag
from .permissions import Permissions from .permissions import Permissions
from .enums import Status from .enums import DisplayNameEffect, DisplayNameFont, Status
from .errors import ClientException from .errors import ClientException
from .colour import Colour from .colour import Colour
from .object import Object from .object import Object
from .flags import MemberFlags from .flags import MemberFlags
from .presences import ClientStatus from .presences import ClientStatus
from .user import DisplayNameStyle
__all__ = ( __all__ = (
'VoiceState', 'VoiceState',
@ -64,7 +65,7 @@ if TYPE_CHECKING:
UserWithMember as UserWithMemberPayload, UserWithMember as UserWithMemberPayload,
) )
from .types.gateway import GuildMemberUpdateEvent from .types.gateway import GuildMemberUpdateEvent
from .types.user import User as UserPayload, AvatarDecorationData from .types.user import User as UserPayload, AvatarDecorationData, DisplayNameStyle as DisplayNameStylePayload
from .abc import Snowflake from .abc import Snowflake
from .state import ConnectionState from .state import ConnectionState
from .message import Message from .message import Message
@ -75,7 +76,6 @@ if TYPE_CHECKING:
) )
from .primary_guild import PrimaryGuild from .primary_guild import PrimaryGuild
from .collectible import Collectible from .collectible import Collectible
from .user import DisplayNameStyle
VocalGuildChannel = Union[VoiceChannel, StageChannel] VocalGuildChannel = Union[VoiceChannel, StageChannel]
@ -290,6 +290,7 @@ class Member(discord.abc.Messageable, _UserTag):
'_banner', '_banner',
'_flags', '_flags',
'_avatar_decoration_data', '_avatar_decoration_data',
'_display_name_style',
) )
if TYPE_CHECKING: if TYPE_CHECKING:
@ -313,7 +314,6 @@ class Member(discord.abc.Messageable, _UserTag):
avatar_decoration_sku_id: Optional[int] avatar_decoration_sku_id: Optional[int]
primary_guild: PrimaryGuild primary_guild: PrimaryGuild
collectibles: List[Collectible] collectibles: List[Collectible]
display_name_style: DisplayNameStyle
def __init__(self, *, data: MemberWithUserPayload, guild: Guild, state: ConnectionState): def __init__(self, *, data: MemberWithUserPayload, guild: Guild, state: ConnectionState):
self._state: ConnectionState = state self._state: ConnectionState = state
@ -331,6 +331,7 @@ class Member(discord.abc.Messageable, _UserTag):
self._permissions: Optional[int] self._permissions: Optional[int]
self._flags: int = data['flags'] self._flags: int = data['flags']
self._avatar_decoration_data: Optional[AvatarDecorationData] = data.get('avatar_decoration_data') self._avatar_decoration_data: Optional[AvatarDecorationData] = data.get('avatar_decoration_data')
self._display_name_style: Optional[DisplayNameStylePayload] = data.get('display_name_style')
try: try:
self._permissions = int(data['permissions']) # pyright: ignore[reportTypedDictNotRequiredAccess] self._permissions = int(data['permissions']) # pyright: ignore[reportTypedDictNotRequiredAccess]
except KeyError: except KeyError:
@ -410,6 +411,7 @@ class Member(discord.abc.Messageable, _UserTag):
self._avatar = member._avatar self._avatar = member._avatar
self._banner = member._banner self._banner = member._banner
self._avatar_decoration_data = member._avatar_decoration_data self._avatar_decoration_data = member._avatar_decoration_data
self._display_name_style = member._display_name_style
# Reference will not be copied unless necessary by PRESENCE_UPDATE # Reference will not be copied unless necessary by PRESENCE_UPDATE
# See below # See below
@ -440,6 +442,7 @@ class Member(discord.abc.Messageable, _UserTag):
self._banner = data.get('banner') self._banner = data.get('banner')
self._flags = data.get('flags', 0) self._flags = data.get('flags', 0)
self._avatar_decoration_data = data.get('avatar_decoration_data') self._avatar_decoration_data = data.get('avatar_decoration_data')
self._display_name_style = data.get('display_name_style')
def _presence_update(self, raw: RawPresenceUpdateEvent, user: UserPayload) -> Optional[Tuple[User, User]]: def _presence_update(self, raw: RawPresenceUpdateEvent, user: UserPayload) -> Optional[Tuple[User, User]]:
self.activities = raw.activities self.activities = raw.activities
@ -458,10 +461,12 @@ class Member(discord.abc.Messageable, _UserTag):
u._public_flags, u._public_flags,
u._avatar_decoration_data['sku_id'] if u._avatar_decoration_data is not None else None, u._avatar_decoration_data['sku_id'] if u._avatar_decoration_data is not None else None,
u._primary_guild, u._primary_guild,
u._display_name_style,
) )
decoration_payload = user.get('avatar_decoration_data') decoration_payload = user.get('avatar_decoration_data')
primary_guild_payload = user.get('primary_guild', None) primary_guild_payload = user.get('primary_guild', None)
display_name_style_payload = user.get('display_name_style', None)
# These keys seem to always be available # These keys seem to always be available
modified = ( modified = (
user['username'], user['username'],
@ -471,6 +476,7 @@ class Member(discord.abc.Messageable, _UserTag):
user.get('public_flags', 0), user.get('public_flags', 0),
decoration_payload['sku_id'] if decoration_payload is not None else None, decoration_payload['sku_id'] if decoration_payload is not None else None,
primary_guild_payload, primary_guild_payload,
display_name_style_payload,
) )
if original != modified: if original != modified:
to_return = User._copy(self._user) to_return = User._copy(self._user)
@ -482,6 +488,7 @@ class Member(discord.abc.Messageable, _UserTag):
u._public_flags, u._public_flags,
u._avatar_decoration_data, u._avatar_decoration_data,
u._primary_guild, u._primary_guild,
u._display_name_style,
) = ( ) = (
user['username'], user['username'],
user['discriminator'], user['discriminator'],
@ -490,6 +497,7 @@ class Member(discord.abc.Messageable, _UserTag):
user.get('public_flags', 0), user.get('public_flags', 0),
decoration_payload, decoration_payload,
primary_guild_payload, primary_guild_payload,
display_name_style_payload,
) )
# Signal to dispatch on_user_update # Signal to dispatch on_user_update
return to_return, u return to_return, u
@ -660,6 +668,35 @@ class Member(discord.abc.Messageable, _UserTag):
if self._banner is None: if self._banner is None:
return None return None
return Asset._from_guild_banner(self._state, self.guild.id, self.id, self._banner) return Asset._from_guild_banner(self._state, self.guild.id, self.id, self._banner)
@property
def display_name_style(self) -> Optional[DisplayNameStyle]:
"""Optional[:class:`DisplayNameStyle`]: Returns the member's guild display name style if they have one,
otherwise their global display name style if they have one, otherwise ``None``.
.. versionadded:: 2.8
"""
return self.guild_display_name_style or self.global_display_name_style
@property
def guild_display_name_style(self) -> Optional[DisplayNameStyle]:
"""Optional[:class:`DisplayNameStyle`]: Returns the member's guild specific display name style.
if the member has no guild display name style set then ``None`` is returned.
.. versionadded:: 2.8
"""
if self._display_name_style is None:
return None
return DisplayNameStyle(data=self._display_name_style)
@property
def global_display_name_style(self) -> Optional[DisplayNameStyle]:
"""Optional[:class:`DisplayNameStyle`]: Returns the user's global display name style.
if the user has no global display name style set then ``None`` is returned.
.. versionadded:: 2.8
"""
return self._user.display_name_style
@property @property
def activity(self) -> Optional[ActivityTypes]: def activity(self) -> Optional[ActivityTypes]:
@ -819,6 +856,9 @@ class Member(discord.abc.Messageable, _UserTag):
avatar: Optional[bytes] = MISSING, avatar: Optional[bytes] = MISSING,
banner: Optional[bytes] = MISSING, banner: Optional[bytes] = MISSING,
bio: Optional[str] = MISSING, bio: Optional[str] = MISSING,
display_name_font: Optional[DisplayNameFont] = MISSING,
display_name_effect: Optional[DisplayNameEffect] = MISSING,
display_name_colors: Optional[List[Union[Colour, int]]] = MISSING,
reason: Optional[str] = None, reason: Optional[str] = None,
) -> Optional[Member]: ) -> Optional[Member]:
"""|coro| """|coro|
@ -904,7 +944,22 @@ class Member(discord.abc.Messageable, _UserTag):
This can only be set when editing the bot's own member. This can only be set when editing the bot's own member.
.. versionadded:: 2.7 .. versionadded:: 2.7
display_name_font: Optional[:class:`DisplayNameFont`]
The new display name font for the member. Use ``None`` to remove the display name font.
This can only be set when editing the bot's own member.
.. versionadded:: 2.8
display_name_effect: Optional[:class:`DisplayNameEffect`]
The new display name effect for the member. Use ``None`` to remove the display name effect.
This can only be set when editing the bot's own member.
.. versionadded:: 2.8
display_name_colors: Optional[List[Union[:class:`Colour`, :class:`int`]]]
A list of up to 2 colors that will be used for the member's display name
gradient. This can only be set when editing the bot's own member.
Use ``None`` to remove the display name colors.
.. versionadded:: 2.8
reason: Optional[:class:`str`] reason: Optional[:class:`str`]
The reason for editing this member. Shows up on the audit log. The reason for editing this member. Shows up on the audit log.
@ -954,8 +1009,23 @@ class Member(discord.abc.Messageable, _UserTag):
if bio is not MISSING: if bio is not MISSING:
self_payload['bio'] = bio or '' self_payload['bio'] = bio or ''
if display_name_font is not MISSING:
self_payload['display_name_font_id'] = display_name_font.value if display_name_font else None
if display_name_effect is not MISSING:
self_payload['display_name_effect_id'] = display_name_effect.value if display_name_effect else None
if display_name_colors is not MISSING:
self_payload['display_name_colors'] = [
c.value if isinstance(c, Colour) else c for c in display_name_colors or []
]
if not me and self_payload: if not me and self_payload:
raise ValueError("Editing the bio, avatar or banner is only for the bot's own member.") only_fields = {'avatar', 'banner', 'bio', 'display_name_font', 'display_name_effect', 'display_name_colors'}
current_fields = utils._human_join(list(only_fields.intersection(set(self_payload.keys()))), final="and")
raise ValueError(
f'Editing {current_fields} can only happen when editing the bot\'s own member.'
)
if deafen is not MISSING: if deafen is not MISSING:
payload['deaf'] = deafen payload['deaf'] = deafen

5
discord/types/member.py

@ -24,7 +24,7 @@ DEALINGS IN THE SOFTWARE.
from typing import Optional, TypedDict from typing import Optional, TypedDict
from .snowflake import SnowflakeList from .snowflake import SnowflakeList
from .user import User, AvatarDecorationData from .user import User, AvatarDecorationData, DisplayNameStyle
from typing_extensions import NotRequired from typing_extensions import NotRequired
@ -50,6 +50,7 @@ class Member(PartialMember, total=False):
communication_disabled_until: str communication_disabled_until: str
banner: NotRequired[Optional[str]] banner: NotRequired[Optional[str]]
avatar_decoration_data: NotRequired[AvatarDecorationData] avatar_decoration_data: NotRequired[AvatarDecorationData]
display_name_style: NotRequired[DisplayNameStyle]
class _OptionalMemberWithUser(PartialMember, total=False): class _OptionalMemberWithUser(PartialMember, total=False):
@ -60,7 +61,7 @@ class _OptionalMemberWithUser(PartialMember, total=False):
permissions: str permissions: str
communication_disabled_until: str communication_disabled_until: str
avatar_decoration_data: NotRequired[AvatarDecorationData] avatar_decoration_data: NotRequired[AvatarDecorationData]
display_name_style: NotRequired[DisplayNameStyle]
class MemberWithUser(_OptionalMemberWithUser): class MemberWithUser(_OptionalMemberWithUser):
user: User user: User

Loading…
Cancel
Save