diff --git a/discord/audit_logs.py b/discord/audit_logs.py index a56f08fdb..f1bba6ef4 100644 --- a/discord/audit_logs.py +++ b/discord/audit_logs.py @@ -24,7 +24,7 @@ DEALINGS IN THE SOFTWARE. from __future__ import annotations -from typing import TYPE_CHECKING, Any, Callable, ClassVar, Dict, Generator, List, Optional, Tuple, Union +from typing import TYPE_CHECKING, Any, Callable, ClassVar, Dict, Generator, List, Optional, Tuple, Type, TypeVar, Union from . import enums, utils from .asset import Asset @@ -57,18 +57,6 @@ if TYPE_CHECKING: from .user import User -def _transform_verification_level(entry: AuditLogEntry, data: int) -> enums.VerificationLevel: - return enums.try_enum(enums.VerificationLevel, data) - - -def _transform_default_notifications(entry: AuditLogEntry, data: int) -> enums.NotificationLevel: - return enums.try_enum(enums.NotificationLevel, data) - - -def _transform_explicit_content_filter(entry: AuditLogEntry, data: int) -> enums.ContentFilter: - return enums.try_enum(enums.ContentFilter, data) - - def _transform_permissions(entry: AuditLogEntry, data: str) -> Permissions: return Permissions(int(data)) @@ -124,18 +112,6 @@ def _transform_overwrites( return overwrites -def _transform_channeltype(entry: AuditLogEntry, data: int) -> enums.ChannelType: - return enums.try_enum(enums.ChannelType, data) - - -def _transform_voiceregion(entry: AuditLogEntry, data: int) -> enums.VoiceRegion: - return enums.try_enum(enums.VoiceRegion, data) - - -def _transform_video_quality_mode(entry: AuditLogEntry, data: int) -> enums.VideoQualityMode: - return enums.try_enum(enums.VideoQualityMode, data) - - def _transform_icon(entry: AuditLogEntry, data: Optional[str]) -> Optional[Asset]: if data is None: return None @@ -145,10 +121,10 @@ def _transform_icon(entry: AuditLogEntry, data: Optional[str]) -> Optional[Asset def _transform_avatar(entry: AuditLogEntry, data: Optional[str]) -> Optional[Asset]: if data is None: return None - return Asset._from_avatar(entry._state, entry._target_id, data) + return Asset._from_avatar(entry._state, entry._target_id, data) # type: ignore -def _guild_hash_transformer(path: str) -> Callable[['AuditLogEntry', Optional[str]], Optional[Asset]]: +def _guild_hash_transformer(path: str) -> Callable[[AuditLogEntry, Optional[str]], Optional[Asset]]: def _transform(entry: AuditLogEntry, data: Optional[str]) -> Optional[Asset]: if data is None: return None @@ -157,6 +133,16 @@ def _guild_hash_transformer(path: str) -> Callable[['AuditLogEntry', Optional[st return _transform +T = TypeVar('T', bound=enums.Enum) + + +def _enum_transformer(enum: Type[T]) -> Callable[[AuditLogEntry, int], T]: + def _transform(entry: AuditLogEntry, data: int) -> T: + return enums.try_enum(enum, data) + + return _transform + + class AuditLogDiff: def __len__(self) -> int: return len(self.__dict__) @@ -183,8 +169,8 @@ Transformer = Callable[["AuditLogEntry", Any], Any] class AuditLogChanges: # fmt: off TRANSFORMERS: ClassVar[Dict[str, Tuple[Optional[str], Optional[Transformer]]]] = { - 'verification_level': (None, _transform_verification_level), - 'explicit_content_filter': (None, _transform_explicit_content_filter), + 'verification_level': (None, _enum_transformer(enums.VerificationLevel)), + 'explicit_content_filter': (None, _enum_transformer(enums.ContentFilter)), 'allow': (None, _transform_permissions), 'deny': (None, _transform_permissions), 'permissions': (None, _transform_permissions), @@ -205,11 +191,12 @@ class AuditLogChanges: 'icon_hash': ('icon', _transform_icon), 'avatar_hash': ('avatar', _transform_avatar), 'rate_limit_per_user': ('slowmode_delay', None), - 'default_message_notifications': ('default_notifications', _transform_default_notifications), - 'region': (None, _transform_voiceregion), - 'rtc_region': (None, _transform_voiceregion), - 'video_quality_mode': (None, _transform_video_quality_mode), - 'type': (None, _transform_channeltype), + 'default_message_notifications': ('default_notifications', _enum_transformer(enums.NotificationLevel)), + 'region': (None, _enum_transformer(enums.VoiceRegion)), + 'rtc_region': (None, _enum_transformer(enums.VoiceRegion)), + 'video_quality_mode': (None, _enum_transformer(enums.VideoQualityMode)), + 'privacy_level': (None, _enum_transformer(enums.StagePrivacyLevel)), + 'type': (None, _enum_transformer(enums.ChannelType)), } # fmt: on @@ -308,6 +295,10 @@ class _AuditLogProxyPinAction: message_id: int +class _AuditLogProxyStageInstanceAction: + channel: abc.GuildChannel + + class AuditLogEntry(Hashable): r"""Represents an Audit Log entry. @@ -404,6 +395,10 @@ class AuditLogEntry(Hashable): role = Object(id=instance_id) role.name = self.extra.get('role_name') # type: ignore self.extra: Role = role + elif self.action.name.startswith('stage_instance'): + channel_id = int(self.extra['channel_id']) + elems = {'channel': self.guild.get_channel(channel_id) or Object(id=channel_id)} + self.extra: _AuditLogProxyStageInstanceAction = type('_AuditLogProxy', (), elems)() # fmt: off self.extra: Union[ @@ -411,6 +406,7 @@ class AuditLogEntry(Hashable): _AuditLogProxyMemberMoveOrMessageDelete, _AuditLogProxyMemberDisconnect, _AuditLogProxyPinAction, + _AuditLogProxyStageInstanceAction, Member, User, None, Role, ] diff --git a/discord/enums.py b/discord/enums.py index 98b5a1092..57d43e53a 100644 --- a/discord/enums.py +++ b/discord/enums.py @@ -24,7 +24,7 @@ DEALINGS IN THE SOFTWARE. import types from collections import namedtuple -from typing import Any, TYPE_CHECKING, Type, TypeVar +from typing import Any, Dict, Optional, TYPE_CHECKING, Type, TypeVar __all__ = ( 'Enum', @@ -320,50 +320,56 @@ class AuditLogAction(Enum): integration_create = 80 integration_update = 81 integration_delete = 82 + stage_instance_create = 83 + stage_instance_update = 84 + stage_instance_delete = 85 @property - def category(self): - lookup = { - AuditLogAction.guild_update: AuditLogActionCategory.update, - AuditLogAction.channel_create: AuditLogActionCategory.create, - AuditLogAction.channel_update: AuditLogActionCategory.update, - AuditLogAction.channel_delete: AuditLogActionCategory.delete, - AuditLogAction.overwrite_create: AuditLogActionCategory.create, - AuditLogAction.overwrite_update: AuditLogActionCategory.update, - AuditLogAction.overwrite_delete: AuditLogActionCategory.delete, - AuditLogAction.kick: None, - AuditLogAction.member_prune: None, - AuditLogAction.ban: None, - AuditLogAction.unban: None, - AuditLogAction.member_update: AuditLogActionCategory.update, - AuditLogAction.member_role_update: AuditLogActionCategory.update, - AuditLogAction.member_move: None, - AuditLogAction.member_disconnect: None, - AuditLogAction.bot_add: None, - AuditLogAction.role_create: AuditLogActionCategory.create, - AuditLogAction.role_update: AuditLogActionCategory.update, - AuditLogAction.role_delete: AuditLogActionCategory.delete, - AuditLogAction.invite_create: AuditLogActionCategory.create, - AuditLogAction.invite_update: AuditLogActionCategory.update, - AuditLogAction.invite_delete: AuditLogActionCategory.delete, - AuditLogAction.webhook_create: AuditLogActionCategory.create, - AuditLogAction.webhook_update: AuditLogActionCategory.update, - AuditLogAction.webhook_delete: AuditLogActionCategory.delete, - AuditLogAction.emoji_create: AuditLogActionCategory.create, - AuditLogAction.emoji_update: AuditLogActionCategory.update, - AuditLogAction.emoji_delete: AuditLogActionCategory.delete, - AuditLogAction.message_delete: AuditLogActionCategory.delete, - AuditLogAction.message_bulk_delete: AuditLogActionCategory.delete, - AuditLogAction.message_pin: None, - AuditLogAction.message_unpin: None, - AuditLogAction.integration_create: AuditLogActionCategory.create, - AuditLogAction.integration_update: AuditLogActionCategory.update, - AuditLogAction.integration_delete: AuditLogActionCategory.delete, + def category(self) -> Optional[AuditLogActionCategory]: + lookup: Dict[AuditLogAction, Optional[AuditLogActionCategory]] = { + AuditLogAction.guild_update: AuditLogActionCategory.update, + AuditLogAction.channel_create: AuditLogActionCategory.create, + AuditLogAction.channel_update: AuditLogActionCategory.update, + AuditLogAction.channel_delete: AuditLogActionCategory.delete, + AuditLogAction.overwrite_create: AuditLogActionCategory.create, + AuditLogAction.overwrite_update: AuditLogActionCategory.update, + AuditLogAction.overwrite_delete: AuditLogActionCategory.delete, + AuditLogAction.kick: None, + AuditLogAction.member_prune: None, + AuditLogAction.ban: None, + AuditLogAction.unban: None, + AuditLogAction.member_update: AuditLogActionCategory.update, + AuditLogAction.member_role_update: AuditLogActionCategory.update, + AuditLogAction.member_move: None, + AuditLogAction.member_disconnect: None, + AuditLogAction.bot_add: None, + AuditLogAction.role_create: AuditLogActionCategory.create, + AuditLogAction.role_update: AuditLogActionCategory.update, + AuditLogAction.role_delete: AuditLogActionCategory.delete, + AuditLogAction.invite_create: AuditLogActionCategory.create, + AuditLogAction.invite_update: AuditLogActionCategory.update, + AuditLogAction.invite_delete: AuditLogActionCategory.delete, + AuditLogAction.webhook_create: AuditLogActionCategory.create, + AuditLogAction.webhook_update: AuditLogActionCategory.update, + AuditLogAction.webhook_delete: AuditLogActionCategory.delete, + AuditLogAction.emoji_create: AuditLogActionCategory.create, + AuditLogAction.emoji_update: AuditLogActionCategory.update, + AuditLogAction.emoji_delete: AuditLogActionCategory.delete, + AuditLogAction.message_delete: AuditLogActionCategory.delete, + AuditLogAction.message_bulk_delete: AuditLogActionCategory.delete, + AuditLogAction.message_pin: None, + AuditLogAction.message_unpin: None, + AuditLogAction.integration_create: AuditLogActionCategory.create, + AuditLogAction.integration_update: AuditLogActionCategory.update, + AuditLogAction.integration_delete: AuditLogActionCategory.delete, + AuditLogAction.stage_instance_create: AuditLogActionCategory.create, + AuditLogAction.stage_instance_update: AuditLogActionCategory.update, + AuditLogAction.stage_instance_delete: AuditLogActionCategory.delete, } return lookup[self] @property - def target_type(self): + def target_type(self) -> Optional[str]: v = self.value if v == -1: return 'all' @@ -385,8 +391,10 @@ class AuditLogAction(Enum): return 'channel' elif v < 80: return 'message' - elif v < 90: + elif v < 83: return 'integration' + elif v < 90: + return 'stage_instance' class UserFlags(Enum): staff = 1 diff --git a/docs/api.rst b/docs/api.rst index 0aeea2f7b..3231871d4 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -2134,6 +2134,42 @@ of :class:`enum.Enum`. .. versionadded:: 1.3 + .. attribute:: stage_instance_create + + A stage instance was started. + + When this is the action, the type of :attr:`~AuditLogEntry.target` is + either :class:`Object` with the stage instance ID of the stage instance + which was created. + + Possible attributes for :class:`AuditLogDiff`: + + - :attr:`~AuditLogDiff.topic` + - :attr:`~AuditLogDiff.privacy_level` + + .. versionadded:: 2.0 + + .. attribute:: stage_instance_update + + A stage instance was updated. + + When this is the action, the type of :attr:`~AuditLogEntry.target` is + either :class:`Object` with the stage instance ID of the stage instance + which was updated. + + Possible attributes for :class:`AuditLogDiff`: + + - :attr:`~AuditLogDiff.topic` + - :attr:`~AuditLogDiff.privacy_level` + + .. versionadded:: 2.0 + + .. attribute:: stage_instance_delete + + A stage instance was ended. + + .. versionadded:: 2.0 + .. class:: AuditLogActionCategory Represents the category that the :class:`AuditLogAction` belongs to. @@ -2282,7 +2318,7 @@ of :class:`enum.Enum`. Represents full camera video quality. -.. class:: PrivacyLevel +.. class:: StagePrivacyLevel Represents a stage instance's privacy level. @@ -2715,9 +2751,9 @@ AuditLogDiff .. attribute:: topic - The topic of a :class:`TextChannel`. + The topic of a :class:`TextChannel` or :class:`StageChannel`. - See also :attr:`TextChannel.topic`. + See also :attr:`TextChannel.topic` or :attr:`StageChannel.topic`. :type: :class:`str` @@ -2742,6 +2778,12 @@ AuditLogDiff :type: List[Tuple[target, :class:`PermissionOverwrite`]] + .. attribute:: privacy_level + + The privacy level of the stage instance. + + :type: :class:`StagePrivacyLevel` + .. attribute:: roles A list of roles being added or removed from a member.