Browse Source

Add support for member flags

pull/10109/head
Soheab_ 2 years ago
committed by dolfies
parent
commit
dbd8c213cb
  1. 75
      discord/flags.py
  2. 57
      discord/member.py
  3. 2
      discord/scheduled_event.py
  4. 1
      discord/types/gateway.py
  5. 1
      discord/types/member.py
  6. 2
      discord/utils.py
  7. 6
      docs/api.rst

75
discord/flags.py

@ -56,6 +56,7 @@ __all__ = (
'HubProgressFlags',
'OnboardingProgressFlags',
'AutoModPresets',
'MemberFlags',
)
BF = TypeVar('BF', bound='BaseFlags')
@ -2274,3 +2275,77 @@ class AutoModPresets(ArrayFlags):
def slurs(self):
""":class:`bool`: Whether to use the preset slurs filter."""
return 1 << 2
@fill_with_flags()
class MemberFlags(BaseFlags):
r"""Wraps up the Discord Guild Member flags
.. versionadded:: 2.0
.. container:: operations
.. describe:: x == y
Checks if two MemberFlags are equal.
.. describe:: x != y
Checks if two MemberFlags are not equal.
.. describe:: x | y, x |= y
Returns a MemberFlags instance with all enabled flags from
both x and y.
.. describe:: x & y, x &= y
Returns a MemberFlags instance with only flags enabled on
both x and y.
.. describe:: x ^ y, x ^= y
Returns a MemberFlags instance with only flags enabled on
only one of x or y, not on both.
.. describe:: ~x
Returns a MemberFlags instance with all flags inverted from x.
.. describe:: hash(x)
Return the flag's hash.
.. describe:: iter(x)
Returns an iterator of ``(name, value)`` pairs. This allows it
to be, for example, constructed as a dict or a list of pairs.
Note that aliases are not shown.
Attributes
-----------
value: :class:`int`
The raw value. You should query flags via the properties
rather than using this raw value.
"""
@flag_value
def did_rejoin(self):
""":class:`bool`: Returns ``True`` if the member left and rejoined the :attr:`~discord.Member.guild`."""
return 1 << 0
@flag_value
def completed_onboarding(self):
""":class:`bool`: Returns ``True`` if the member has completed onboarding."""
return 1 << 1
@flag_value
def bypasses_verification(self):
""":class:`bool`: Returns ``True`` if the member can bypass the guild verification requirements."""
return 1 << 2
@flag_value
def started_onboarding(self):
""":class:`bool`: Returns ``True`` if the member has started onboarding."""
return 1 << 3

57
discord/member.py

@ -41,6 +41,7 @@ from .enums import RelationshipAction, Status, try_enum
from .errors import ClientException
from .colour import Colour
from .object import Object
from .flags import MemberFlags
__all__ = (
'VoiceState',
@ -275,7 +276,7 @@ class Member(discord.abc.Messageable, discord.abc.Connectable, _UserTag):
'_user',
'_state',
'_avatar',
'_communication_disabled_until',
'_flags',
)
if TYPE_CHECKING:
@ -306,6 +307,7 @@ class Member(discord.abc.Messageable, discord.abc.Connectable, _UserTag):
self.nick: Optional[str] = data.get('nick', None)
self.pending: bool = data.get('pending', False)
self._avatar: Optional[str] = data.get('avatar')
self._flags: int = data.get('flags', 0)
self.timed_out_until: Optional[datetime.datetime] = utils.parse_time(data.get('communication_disabled_until'))
def __str__(self) -> str:
@ -339,6 +341,7 @@ class Member(discord.abc.Messageable, discord.abc.Connectable, _UserTag):
self.nick = data.get('nick', None)
self.pending = data.get('pending', False)
self.timed_out_until = utils.parse_time(data.get('communication_disabled_until'))
self._flags = data.get('flags', 0)
@classmethod
def _try_upgrade(cls, *, data: UserWithMemberPayload, guild: Guild, state: ConnectionState) -> Union[User, Self]:
@ -363,6 +366,7 @@ class Member(discord.abc.Messageable, discord.abc.Connectable, _UserTag):
self.nick = member.nick
self.pending = member.pending
self.timed_out_until = member.timed_out_until
self._flags = member._flags
self._state = member._state
self._avatar = member._avatar
@ -390,6 +394,7 @@ class Member(discord.abc.Messageable, discord.abc.Connectable, _UserTag):
self.timed_out_until = utils.parse_time(data.get('communication_disabled_until'))
self._roles = utils.SnowflakeList(map(int, data['roles']))
self._avatar = data.get('avatar')
self._flags = data.get('flags', 0)
attrs = {'joined_at', 'premium_since', '_roles', '_avatar', 'timed_out_until', 'nick', 'pending'}
@ -649,6 +654,14 @@ class Member(discord.abc.Messageable, discord.abc.Connectable, _UserTag):
"""Optional[:class:`VoiceState`]: Returns the member's current voice state."""
return self.guild._voice_state_for(self._user.id)
@property
def flags(self) -> MemberFlags:
""":class:`MemberFlags`: Returns the member's flags.
.. versionadded:: 2.0
"""
return MemberFlags._from_value(self._flags)
async def ban(
self,
*,
@ -694,6 +707,7 @@ class Member(discord.abc.Messageable, discord.abc.Connectable, _UserTag):
avatar: Optional[bytes] = MISSING,
banner: Optional[bytes] = MISSING,
bio: Optional[str] = MISSING,
bypass_verification: bool = MISSING,
reason: Optional[str] = None,
) -> Optional[Member]:
"""|coro|
@ -702,21 +716,23 @@ class Member(discord.abc.Messageable, discord.abc.Connectable, _UserTag):
Depending on the parameter passed, this requires different permissions listed below:
+-----------------+--------------------------------------+
| Parameter | Permission |
+-----------------+--------------------------------------+
| nick | :attr:`Permissions.manage_nicknames` |
+-----------------+--------------------------------------+
| mute | :attr:`Permissions.mute_members` |
+-----------------+--------------------------------------+
| deafen | :attr:`Permissions.deafen_members` |
+-----------------+--------------------------------------+
| roles | :attr:`Permissions.manage_roles` |
+-----------------+--------------------------------------+
| voice_channel | :attr:`Permissions.move_members` |
+-----------------+--------------------------------------+
| timed_out_until | :attr:`Permissions.moderate_members` |
+-----------------+--------------------------------------+
+---------------------+--------------------------------------+
| Parameter | Permission |
+---------------------+--------------------------------------+
| nick | :attr:`Permissions.manage_nicknames` |
+---------------------+--------------------------------------+
| mute | :attr:`Permissions.mute_members` |
+---------------------+--------------------------------------+
| deafen | :attr:`Permissions.deafen_members` |
+---------------------+--------------------------------------+
| roles | :attr:`Permissions.manage_roles` |
+---------------------+--------------------------------------+
| voice_channel | :attr:`Permissions.move_members` |
+---------------------+--------------------------------------+
| timed_out_until | :attr:`Permissions.moderate_members` |
+---------------------+--------------------------------------+
| bypass_verification | :attr:`Permissions.manage_guild` |
+---------------------+--------------------------------------+
All parameters are optional.
@ -769,6 +785,10 @@ class Member(discord.abc.Messageable, discord.abc.Connectable, _UserTag):
The member's new guild "about me". Pass ``None`` to remove the bio.
You can only change your own guild bio.
.. versionadded:: 2.0
bypass_verification: :class:`bool`
Indicates if the member should be allowed to bypass the guild verification requirements.
.. versionadded:: 2.0
reason: Optional[:class:`str`]
The reason for editing this member. Shows up on the audit log.
@ -850,6 +870,11 @@ class Member(discord.abc.Messageable, discord.abc.Connectable, _UserTag):
)
payload['communication_disabled_until'] = timed_out_until.isoformat()
if bypass_verification is not MISSING:
flags = MemberFlags._from_value(self._flags)
flags.bypasses_verification = bypass_verification
payload['flags'] = flags.value
if payload:
data = await http.edit_member(guild_id, self.id, reason=reason, **payload)

2
discord/scheduled_event.py

@ -101,7 +101,7 @@ class ScheduledEvent(Hashable):
creator_id: Optional[:class:`int`]
The ID of the user that created the scheduled event.
.. versionadded:: 2.2
.. versionadded:: 2.0
location: Optional[:class:`str`]
The location of the scheduled event.
"""

1
discord/types/gateway.py

@ -278,6 +278,7 @@ class GuildMemberUpdateEvent(TypedDict):
user: PartialUser
avatar: Optional[str]
joined_at: Optional[str]
flags: int
nick: NotRequired[str]
premium_since: NotRequired[Optional[str]]
deaf: NotRequired[bool]

1
discord/types/member.py

@ -36,6 +36,7 @@ class PartialMember(TypedDict):
joined_at: str
deaf: bool
mute: bool
flags: int
class Member(PartialMember, total=False):

2
discord/utils.py

@ -750,7 +750,7 @@ async def maybe_coroutine(f: MaybeAwaitableFunc[P, T], *args: P.args, **kwargs:
This is useful for functions that may or may not be coroutines.
.. versionadded:: 2.2
.. versionadded:: 2.0
Parameters
-----------

6
docs/api.rst

@ -916,6 +916,7 @@ Members
- pending
- timeout
- guild avatar
- flags
Due to a Discord limitation, this event is not dispatched when a member's timeout expires.
@ -7416,6 +7417,11 @@ Flags
.. autoclass:: HubProgressFlags()
:members:
.. attributetable:: MemberFlags
.. autoclass:: MemberFlags()
:members:
.. attributetable:: MessageFlags
.. autoclass:: MessageFlags()

Loading…
Cancel
Save