Skip to content

Commit

Permalink
feat: implement MemberFlags (#2489)
Browse files Browse the repository at this point in the history
  • Loading branch information
NeloBlivion committed Jun 30, 2024
1 parent 267a644 commit de117fe
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 0 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ These changes are available on the `master` branch, but have not yet been releas
([#2438](https://github.com/Pycord-Development/pycord/pull/2438))
- Added `Attachment.title`.
([#2486](https://github.com/Pycord-Development/pycord/pull/2486))
- Added `MemberFlags`. ([#2489](https://github.com/Pycord-Development/pycord/pull/2489))
- Added `bypass_verification` parameter to `Member.edit`.
([#2489](https://github.com/Pycord-Development/pycord/pull/2489))

### Fixed

Expand Down
74 changes: 74 additions & 0 deletions discord/flags.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"ApplicationFlags",
"ChannelFlags",
"SKUFlags",
"MemberFlags",
)

FV = TypeVar("FV", bound="flag_value")
Expand Down Expand Up @@ -1684,3 +1685,76 @@ def guild_subscription(self):
def user_subscription(self):
""":class:`bool`: Returns ``True`` if the SKU is a user subscription."""
return 1 << 8


@fill_with_flags()
class MemberFlags(BaseFlags):
r"""Wraps up the Discord Member flags.
.. container:: operations
.. describe:: x == y
Checks if two MemberFlags are equal.
.. describe:: x != y
Checks if two MemberFlags are not equal.
.. describe:: x + y
Adds two flags together. Equivalent to ``x | y``.
.. describe:: x - y
Subtracts two flags from each other.
.. describe:: x | y
Returns the union of two flags. Equivalent to ``x + y``.
.. describe:: x & y
Returns the intersection of two flags.
.. describe:: ~x
Returns the inverse of a flag.
.. 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.
.. versionadded:: 2.6
Attributes
-----------
value: :class:`int`
The raw value. You should query flags via the properties
rather than using this raw value.
"""

__slots__ = ()

@flag_value
def did_rejoin(self):
""":class:`bool`: Returns ``True`` if the member left and rejoined the 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 is exempt from verification requirements.
.. note::
This can be edited through :func:`~discord.Member.edit`.
"""
return 1 << 2

@flag_value
def started_onboarding(self):
""":class:`bool`: Returns ``True`` if the member has started onboarding."""
return 1 << 3
31 changes: 31 additions & 0 deletions discord/member.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
from .asset import Asset
from .colour import Colour
from .enums import Status, try_enum
from .flags import MemberFlags
from .object import Object
from .permissions import Permissions
from .user import BaseUser, User, _UserTag
Expand Down Expand Up @@ -269,6 +270,10 @@ class Member(discord.abc.Messageable, _UserTag):
An aware datetime object that specifies the date and time in UTC when the member will be removed from timeout.
.. versionadded:: 2.0
flags: :class:`MemberFlags`
Extra attributes of the member.
.. versionadded:: 2.6
"""

__slots__ = (
Expand All @@ -284,6 +289,7 @@ class Member(discord.abc.Messageable, _UserTag):
"_state",
"_avatar",
"communication_disabled_until",
"flags",
)

if TYPE_CHECKING:
Expand Down Expand Up @@ -325,6 +331,7 @@ def __init__(
self.communication_disabled_until: datetime.datetime | None = utils.parse_time(
data.get("communication_disabled_until")
)
self.flags: MemberFlags = MemberFlags._from_value(data.get("flags", 0))

def __str__(self) -> str:
return str(self._user)
Expand Down Expand Up @@ -400,6 +407,7 @@ def _copy(cls: type[M], member: M) -> M:
self._state = member._state
self._avatar = member._avatar
self.communication_disabled_until = member.communication_disabled_until
self.flags = member.flags

# Reference will not be copied unless necessary by PRESENCE_UPDATE
# See below
Expand Down Expand Up @@ -429,6 +437,7 @@ def _update(self, data: MemberPayload) -> None:
self.communication_disabled_until = utils.parse_time(
data.get("communication_disabled_until")
)
self.flags = MemberFlags._from_value(data.get("flags", 0))

def _presence_update(
self, data: PartialPresenceUpdate, user: UserPayload
Expand Down Expand Up @@ -729,6 +738,7 @@ async def edit(
voice_channel: VocalGuildChannel | None = MISSING,
reason: str | None = None,
communication_disabled_until: datetime.datetime | None = MISSING,
bypass_verification: bool | None = MISSING,
) -> Member | None:
"""|coro|
Expand All @@ -751,6 +761,18 @@ async def edit(
+------------------------------+--------------------------------------+
| communication_disabled_until | :attr:`Permissions.moderate_members` |
+------------------------------+--------------------------------------+
| bypass_verification | See note below |
+------------------------------+--------------------------------------+
.. note::
`bypass_verification` may be edited under three scenarios:
- Client has :attr:`Permissions.manage_guild`
- Client has :attr:`Permissions.manage_roles`
- Client has ALL THREE of :attr:`Permissions.moderate_members`, :attr:`Permissions.kick_members`, and :attr:`Permissions.ban_members`
All parameters are optional.
Expand Down Expand Up @@ -785,6 +807,10 @@ async def edit(
from timeout.
.. versionadded:: 2.0
bypass_verification: Optional[:class:`bool`]
Indicates if the member should bypass the guild's verification requirements.
.. versionadded:: 2.6
Returns
-------
Expand Down Expand Up @@ -849,6 +875,11 @@ async def edit(
else:
payload["communication_disabled_until"] = communication_disabled_until

if bypass_verification is not MISSING:
flags = MemberFlags._from_value(self.flags.value)
flags.bypasses_verification = bypass_verification
payload["flags"] = flags.value

if payload:
data = await http.edit_member(guild_id, self.id, reason=reason, **payload)
return Member(data=data, guild=self.guild, state=self._state)
Expand Down
1 change: 1 addition & 0 deletions discord/types/member.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class Member(PartialMember, total=False):
pending: bool
permissions: str
communication_disabled_until: str
flags: int


class _OptionalMemberWithUser(PartialMember, total=False):
Expand Down
5 changes: 5 additions & 0 deletions docs/api/data_classes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,11 @@ Flags
.. autoclass:: SKUFlags()
:members:

.. attributetable:: MemberFlags

.. autoclass:: MemberFlags()
:members:

Colour
------

Expand Down

0 comments on commit de117fe

Please sign in to comment.