Skip to content

Commit 14ec7c0

Browse files
authored
Merge branch 'Pycord-Development:master' into master
2 parents 824a5c6 + 4dedcf2 commit 14ec7c0

File tree

3 files changed

+90
-17
lines changed

3 files changed

+90
-17
lines changed

discord/member.py

Lines changed: 86 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,10 @@ class Member(discord.abc.Messageable, _UserTag):
252252
premium_since: Optional[:class:`datetime.datetime`]
253253
An aware datetime object that specifies the date and time in UTC when the member used their
254254
"Nitro boost" on the guild, if available. This could be ``None``.
255+
communication_disabled_until: Optional[:class:`datetime.datetime`]
256+
An aware datetime object that specifies the date and time in UTC when the member will be removed from timeout.
257+
258+
.. versionadded:: 2.0
255259
"""
256260

257261
__slots__ = (
@@ -266,6 +270,7 @@ class Member(discord.abc.Messageable, _UserTag):
266270
'_user',
267271
'_state',
268272
'_avatar',
273+
'communication_disabled_until',
269274
)
270275

271276
if TYPE_CHECKING:
@@ -284,6 +289,7 @@ class Member(discord.abc.Messageable, _UserTag):
284289
banner: Optional[Asset]
285290
accent_color: Optional[Colour]
286291
accent_colour: Optional[Colour]
292+
communication_disabled_until: Optional[datetime.datetime]
287293

288294
def __init__(self, *, data: MemberWithUserPayload, guild: Guild, state: ConnectionState):
289295
self._state: ConnectionState = state
@@ -297,6 +303,7 @@ def __init__(self, *, data: MemberWithUserPayload, guild: Guild, state: Connecti
297303
self.nick: Optional[str] = data.get('nick', None)
298304
self.pending: bool = data.get('pending', False)
299305
self._avatar: Optional[str] = data.get('avatar')
306+
self.communication_disabled_until: Optional[datetime.datetime] = utils.parse_time(data.get('communication_disabled_until'))
300307

301308
def __str__(self) -> str:
302309
return str(self._user)
@@ -354,6 +361,7 @@ def _copy(cls: Type[M], member: M) -> M:
354361
self.activities = member.activities
355362
self._state = member._state
356363
self._avatar = member._avatar
364+
self.communication_disabled_until = member.communication_disabled_until
357365

358366
# Reference will not be copied unless necessary by PRESENCE_UPDATE
359367
# See below
@@ -380,6 +388,7 @@ def _update(self, data: MemberPayload) -> None:
380388
self.premium_since = utils.parse_time(data.get('premium_since'))
381389
self._roles = utils.SnowflakeList(map(int, data['roles']))
382390
self._avatar = data.get('avatar')
391+
self.communication_disabled_until = utils.parse_time(data.get('communication_disabled_until'))
383392

384393
def _presence_update(self, data: PartialPresenceUpdate, user: UserPayload) -> Optional[Tuple[User, User]]:
385394
self.activities = tuple(map(create_activity, data['activities']))
@@ -405,7 +414,9 @@ def _update_inner_user(self, user: UserPayload) -> Optional[Tuple[User, User]]:
405414

406415
@property
407416
def status(self) -> Status:
408-
""":class:`Status`: The member's overall status. If the value is unknown, then it will be a :class:`str` instead."""
417+
""":class:`Status`: The member's overall status.
418+
If the value is unknown, then it will be a :class:`str` instead.
419+
"""
409420
return try_enum(Status, self._client_status[None])
410421

411422
@property
@@ -645,26 +656,29 @@ async def edit(
645656
roles: List[discord.abc.Snowflake] = MISSING,
646657
voice_channel: Optional[VocalGuildChannel] = MISSING,
647658
reason: Optional[str] = None,
659+
communication_disabled_until: Optional[datetime.datetime] = MISSING,
648660
) -> Optional[Member]:
649661
"""|coro|
650662
651663
Edits the member's data.
652664
653665
Depending on the parameter passed, this requires different permissions listed below:
654666
655-
+---------------+--------------------------------------+
656-
| Parameter | Permission |
657-
+---------------+--------------------------------------+
658-
| nick | :attr:`Permissions.manage_nicknames` |
659-
+---------------+--------------------------------------+
660-
| mute | :attr:`Permissions.mute_members` |
661-
+---------------+--------------------------------------+
662-
| deafen | :attr:`Permissions.deafen_members` |
663-
+---------------+--------------------------------------+
664-
| roles | :attr:`Permissions.manage_roles` |
665-
+---------------+--------------------------------------+
666-
| voice_channel | :attr:`Permissions.move_members` |
667-
+---------------+--------------------------------------+
667+
+------------------------------+--------------------------------------+
668+
| Parameter | Permission |
669+
+------------------------------+--------------------------------------+
670+
| nick | :attr:`Permissions.manage_nicknames` |
671+
+------------------------------+--------------------------------------+
672+
| mute | :attr:`Permissions.mute_members` |
673+
+------------------------------+--------------------------------------+
674+
| deafen | :attr:`Permissions.deafen_members` |
675+
+------------------------------+--------------------------------------+
676+
| roles | :attr:`Permissions.manage_roles` |
677+
+------------------------------+--------------------------------------+
678+
| voice_channel | :attr:`Permissions.move_members` |
679+
+------------------------------+--------------------------------------+
680+
| communication_disabled_until | :attr:`Permissions.moderate_members` |
681+
+------------------------------+--------------------------------------+
668682
669683
All parameters are optional.
670684
@@ -694,7 +708,11 @@ async def edit(
694708
Pass ``None`` to kick them from voice.
695709
reason: Optional[:class:`str`]
696710
The reason for editing this member. Shows up on the audit log.
711+
communication_disabled_until: Optional[:class:`datetime.datetime`]
712+
Temporarily puts the member in timeout until this time. If the value is ``None``, then the user is removed
713+
from timeout.
697714
715+
.. versionadded:: 2.0
698716
Raises
699717
-------
700718
Forbidden
@@ -748,10 +766,64 @@ async def edit(
748766
if roles is not MISSING:
749767
payload['roles'] = tuple(r.id for r in roles)
750768

769+
if communication_disabled_until is not MISSING:
770+
if communication_disabled_until is not None:
771+
payload['communication_disabled_until'] = communication_disabled_until.isoformat()
772+
else:
773+
payload['communication_disabled_until'] = communication_disabled_until
774+
751775
if payload:
752776
data = await http.edit_member(guild_id, self.id, reason=reason, **payload)
753777
return Member(data=data, guild=self.guild, state=self._state)
754778

779+
async def timeout(self, until: Optional[datetime.datetime], reason: str = None) -> None:
780+
"""|coro|
781+
782+
Timeouts a member from the guild for the set duration.
783+
784+
You must have the :attr:`~Permissions.moderate_members` permission to
785+
timeout a member.
786+
787+
Parameters
788+
-----------
789+
until: :class:`datetime.datetime`
790+
The date and time to timeout the member for. If this is ``None`` then the member is removed from timeout.
791+
reason: Optional[:class:`str`]
792+
The reason for doing this action. Shows up on the audit log.
793+
794+
Raises
795+
-------
796+
Forbidden
797+
You do not have permissions to timeout members.
798+
HTTPException
799+
An error occurred doing the request.
800+
"""
801+
await self.edit(communication_disabled_until=until, reason=reason)
802+
803+
async def remove_timeout(self, reason: str = None) -> None:
804+
"""|coro|
805+
806+
Removes the timeout from a member.
807+
808+
You must have the :attr:`~Permissions.moderate_members` permission to
809+
remove the timeout.
810+
811+
This is equivalent to calling :meth:`~.timeout` and passing ``None`` to :param:`~.timeout.until`.
812+
813+
Parameters
814+
-----------
815+
reason: Optional[:class:`str`]
816+
The reason for doing this action. Shows up on the audit log.
817+
818+
Raises
819+
-------
820+
Forbidden
821+
You do not have permissions to remove the timeout.
822+
HTTPException
823+
An error occurred doing the request.
824+
"""
825+
await self.edit(communication_disabled_until=None, reason=reason)
826+
755827
async def request_to_speak(self) -> None:
756828
"""|coro|
757829

discord/permissions.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -561,8 +561,8 @@ def start_embedded_activities(self) -> int:
561561
return 1 << 39
562562

563563
@flag_value
564-
def manage_members(self) -> int:
565-
""":class:`bool`: Returns ``True`` if a user can manage members (timeout).
564+
def moderate_members(self) -> int:
565+
""":class:`bool`: Returns ``True`` if a user can moderate members (timeout).
566566
567567
.. versionadded:: 2.0
568568
"""
@@ -682,7 +682,7 @@ class PermissionOverwrite:
682682
external_stickers: Optional[bool]
683683
use_external_stickers: Optional[bool]
684684
start_embedded_activities: Optional[bool]
685-
manage_members: Optional[bool]
685+
moderate_members: Optional[bool]
686686

687687
def __init__(self, **kwargs: Optional[bool]):
688688
self._values: Dict[str, Optional[bool]] = {}

discord/types/member.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class Member(PartialMember, total=False):
4646
premium_since: str
4747
pending: bool
4848
permissions: str
49+
communication_disabled_until: str
4950

5051

5152
class _OptionalMemberWithUser(PartialMember, total=False):

0 commit comments

Comments
 (0)