From ff90e7e7470a8b0d4af55f8c9bc91d5814f83794 Mon Sep 17 00:00:00 2001 From: mniip Date: Tue, 22 Feb 2022 16:48:26 +0300 Subject: [PATCH] GUILD_UPDATE audit logs --- discord/audit_logs.py | 54 ++++++++++++++++++++---------------- discord/enums.py | 6 ++++ discord/guild.py | 12 ++++---- docs/api.rst | 64 +++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 103 insertions(+), 33 deletions(-) diff --git a/discord/audit_logs.py b/discord/audit_logs.py index 6e634fbd4..da9564881 100644 --- a/discord/audit_logs.py +++ b/discord/audit_logs.py @@ -26,7 +26,7 @@ from __future__ import annotations from typing import TYPE_CHECKING, Any, Callable, ClassVar, Dict, Generator, List, Optional, Tuple, Type, TypeVar, Union -from . import enums, utils +from . import enums, flags, utils from .asset import Asset from .colour import Colour from .invite import Invite @@ -74,10 +74,6 @@ def _transform_timestamp(entry: AuditLogEntry, data: Optional[str]) -> Optional[ return utils.parse_time(data) -def _transform_permissions(entry: AuditLogEntry, data: str) -> Permissions: - return Permissions(int(data)) - - def _transform_color(entry: AuditLogEntry, data: int) -> Colour: return Colour(data) @@ -153,16 +149,26 @@ def _guild_hash_transformer(path: str) -> Callable[[AuditLogEntry, Optional[str] return _transform -T = TypeVar('T', bound=enums.Enum) +E = TypeVar('E', bound=enums.Enum) -def _enum_transformer(enum: Type[T]) -> Callable[[AuditLogEntry, int], T]: - def _transform(entry: AuditLogEntry, data: int) -> T: +def _enum_transformer(enum: Type[E]) -> Callable[[AuditLogEntry, int], E]: + def _transform(entry: AuditLogEntry, data: int) -> E: return enums.try_enum(enum, data) return _transform +F = TypeVar('F', bound=flags.BaseFlags) + + +def _flag_transformer(cls: Type[F]) -> Callable[[AuditLogEntry, Union[int, str]], F]: + def _transform(entry: AuditLogEntry, data: Union[int, str]) -> F: + return cls._from_value(int(data)) + + return _transform + + def _transform_type(entry: AuditLogEntry, data: int) -> Union[enums.ChannelType, enums.StickerType]: if entry.action.name.startswith('sticker_'): return enums.try_enum(enums.StickerType, data) @@ -198,9 +204,9 @@ class AuditLogChanges: TRANSFORMERS: ClassVar[Dict[str, Tuple[Optional[str], Optional[Transformer]]]] = { '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), + 'allow': (None, _flag_transformer(Permissions)), + 'deny': (None, _flag_transformer(Permissions)), + 'permissions': (None, _flag_transformer(Permissions)), 'id': (None, _transform_snowflake), 'color': ('colour', _transform_color), 'owner_id': ('owner', _transform_member_id), @@ -208,6 +214,7 @@ class AuditLogChanges: 'channel_id': ('channel', _transform_channel), 'afk_channel_id': ('afk_channel', _transform_channel), 'system_channel_id': ('system_channel', _transform_channel), + 'system_channel_flags': (None, _flag_transformer(flags.SystemChannelFlags)), 'widget_channel_id': ('widget_channel', _transform_channel), 'rules_channel_id': ('rules_channel', _transform_channel), 'public_updates_channel_id': ('public_updates_channel', _transform_channel), @@ -229,6 +236,7 @@ class AuditLogChanges: 'type': (None, _transform_type), 'communication_disabled_until': ('timed_out_until', _transform_timestamp), 'expire_behavior': (None, _enum_transformer(enums.ExpireBehaviour)), + 'mfa_level': (None, _enum_transformer(enums.MFALevel)), } # fmt: on @@ -394,6 +402,18 @@ class AuditLogEntry(Hashable): self.reason = data.get('reason') extra = data.get('options') + # fmt: off + self.extra: Union[ + _AuditLogProxyMemberPrune, + _AuditLogProxyMemberMoveOrMessageDelete, + _AuditLogProxyMemberDisconnect, + _AuditLogProxyPinAction, + _AuditLogProxyStageInstanceAction, + Member, User, None, + Role, Object + ] = None + # fmt: on + if isinstance(self.action, enums.AuditLogAction) and extra: if self.action is enums.AuditLogAction.member_prune: # member prune has two keys with useful information @@ -435,18 +455,6 @@ class AuditLogEntry(Hashable): channel=self.guild.get_channel(channel_id) or Object(id=channel_id) ) - # fmt: off - self.extra: Union[ - _AuditLogProxyMemberPrune, - _AuditLogProxyMemberMoveOrMessageDelete, - _AuditLogProxyMemberDisconnect, - _AuditLogProxyPinAction, - _AuditLogProxyStageInstanceAction, - Member, User, None, - Role, Object - ] - # fmt: on - # this key is not present when the above is present, typically. # It's a list of { new_value: a, old_value: b, key: c } # where new_value and old_value are not guaranteed to be there depending diff --git a/discord/enums.py b/discord/enums.py index 5b5b46d96..82e9163c6 100644 --- a/discord/enums.py +++ b/discord/enums.py @@ -56,6 +56,7 @@ __all__ = ( 'InteractionType', 'InteractionResponseType', 'NSFWLevel', + 'MFALevel', ) @@ -609,6 +610,11 @@ class NSFWLevel(Enum, comparable=True): age_restricted = 3 +class MFALevel(Enum, comparable=True): + disabled = 0 + require_2fa = 1 + + E = TypeVar('E', bound='Enum') diff --git a/discord/guild.py b/discord/guild.py index 28f550d3a..87296bb87 100644 --- a/discord/guild.py +++ b/discord/guild.py @@ -66,6 +66,7 @@ from .enums import ( ContentFilter, NotificationLevel, NSFWLevel, + MFALevel, ) from .mixins import Hashable from .user import User @@ -96,7 +97,6 @@ if TYPE_CHECKING: Ban as BanPayload, Guild as GuildPayload, RolePositionUpdate as RolePositionUpdatePayload, - MFALevel, GuildFeature, ) from .types.threads import ( @@ -202,10 +202,6 @@ class Guild(Hashable): .. versionadded:: 1.4 description: Optional[:class:`str`] The guild's description. - mfa_level: :class:`int` - Indicates the guild's two factor authorisation level. If this value is 0 then - the guild does not require 2FA for their administrative members. If the value is - 1 then they do. verification_level: :class:`VerificationLevel` The guild's verification level. explicit_content_filter: :class:`ContentFilter` @@ -253,6 +249,8 @@ class Guild(Hashable): results to a specific language. nsfw_level: :class:`NSFWLevel` The guild's NSFW level. + mfa_level: :class:`MFALevel` + The guild's Multi-Factor Authentication requirement level. .. versionadded:: 2.0 """ @@ -265,7 +263,6 @@ class Guild(Hashable): 'unavailable', 'region', 'owner_id', - 'mfa_level', 'emojis', 'stickers', 'features', @@ -280,6 +277,7 @@ class Guild(Hashable): 'premium_subscription_count', 'preferred_locale', 'nsfw_level', + 'mfa_level', '_members', '_channels', '_icon', @@ -444,7 +442,6 @@ class Guild(Hashable): role = Role(guild=self, data=r, state=state) self._roles[role.id] = role - self.mfa_level: MFALevel = guild.get('mfa_level', 0) self.emojis: Tuple[Emoji, ...] = tuple(map(lambda d: state.store_emoji(self, d), guild.get('emojis', []))) self.stickers: Tuple[GuildSticker, ...] = tuple( map(lambda d: state.store_sticker(self, d), guild.get('stickers', [])) @@ -464,6 +461,7 @@ class Guild(Hashable): self._rules_channel_id: Optional[int] = utils._get_as_snowflake(guild, 'rules_channel_id') self._public_updates_channel_id: Optional[int] = utils._get_as_snowflake(guild, 'public_updates_channel_id') self.nsfw_level: NSFWLevel = try_enum(NSFWLevel, guild.get('nsfw_level', 0)) + self.mfa_level: MFALevel = try_enum(MFALevel, guild.get('mfa_level', 0)) self._stage_instances: Dict[int, StageInstance] = {} for s in guild.get('stage_instances', []): diff --git a/docs/api.rst b/docs/api.rst index 54106f7fa..56ceab3af 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -1802,6 +1802,15 @@ of :class:`enum.Enum`. - :attr:`~AuditLogDiff.icon` - :attr:`~AuditLogDiff.banner` - :attr:`~AuditLogDiff.vanity_url_code` + - :attr:`~AuditLogDiff.description` + - :attr:`~AuditLogDiff.preferred_locale` + - :attr:`~AuditLogDiff.prune_delete_days` + - :attr:`~AuditLogDiff.public_updates_channel` + - :attr:`~AuditLogDiff.region` + - :attr:`~AuditLogDiff.rules_channel` + - :attr:`~AuditLogDiff.verification_level` + - :attr:`~AuditLogDiff.widget_channel` + - :attr:`~AuditLogDiff.widget_enabled` .. attribute:: channel_create @@ -2642,6 +2651,41 @@ of :class:`enum.Enum`. The guild may contain NSFW content. +.. class:: MFALevel + + Represents the Multi-Factor Authentication requirement level of a guild. + + .. versionadded:: 2.0 + + .. container:: operations + + .. describe:: x == y + + Checks if two MFA levels are equal. + .. describe:: x != y + + Checks if two MFA levels are not equal. + .. describe:: x > y + + Checks if a MFA level is higher than another. + .. describe:: x < y + + Checks if a MFA level is lower than another. + .. describe:: x >= y + + Checks if a MFA level is higher or equal to another. + .. describe:: x <= y + + Checks if a MFA level is lower or equal to another. + + .. attribute:: disabled + + The guild has no MFA requirement. + + .. attribute:: require_2fa + + The guild requires 2 factor authentication. + .. _discord-api-audit-logs: Audit Log Data @@ -2831,7 +2875,7 @@ AuditLogDiff The guild's MFA level. See :attr:`Guild.mfa_level`. - :type: :class:`int` + :type: :class:`MFALevel` .. attribute:: widget_enabled @@ -3129,9 +3173,9 @@ AuditLogDiff .. attribute:: description - The description of a sticker being changed. + The description of a guild, or a sticker. - See also :attr:`GuildSticker.description` + See also :attr:`Guild.description`, or :attr:`GuildSticker.description`. :type: :class:`str` @@ -3206,6 +3250,20 @@ AuditLogDiff :type: :class:`int` + .. attribute:: preferred_locale + + The preferred locale for the guild changed. + + see also :attr:`Guild.preferred_locale` + + :type: :class:`str` + + .. attribute:: prune_delete_days + + The number of days after which inactive and role-unassigned members are kicked has been changed. + + :type: :class:`int` + .. this is currently missing the following keys: reason and application_id I'm not sure how to about porting these