mirror of
				https://github.com/Rapptz/discord.py.git
				synced 2025-11-04 07:22:50 +00:00 
			
		
		
		
	Add application command permissions to audit log
This commit is contained in:
		@@ -39,6 +39,7 @@ __all__ = (
 | 
			
		||||
    'AppCommandThread',
 | 
			
		||||
    'Argument',
 | 
			
		||||
    'Choice',
 | 
			
		||||
    'AllChannels',
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
ChoiceT = TypeVar('ChoiceT', str, int, float, Union[str, int, float])
 | 
			
		||||
@@ -70,6 +71,32 @@ if TYPE_CHECKING:
 | 
			
		||||
    ApplicationCommandParent = Union['AppCommand', 'AppCommandGroup']
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AllChannels:
 | 
			
		||||
    """Represents all channels for application command permissions.
 | 
			
		||||
 | 
			
		||||
    .. versionadded:: 2.0
 | 
			
		||||
 | 
			
		||||
    Attributes
 | 
			
		||||
    -----------
 | 
			
		||||
    id: :class:`int`
 | 
			
		||||
        The guilds id - 1.
 | 
			
		||||
    guild: :class:`~discord.Guild`
 | 
			
		||||
        The guild the application command permission is for.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    __slots__ = (
 | 
			
		||||
        'id',
 | 
			
		||||
        'guild',
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    def __init__(self, guild: Guild):
 | 
			
		||||
        self.id = guild.id - 1
 | 
			
		||||
        self.guild = guild
 | 
			
		||||
 | 
			
		||||
    def __repr__(self):
 | 
			
		||||
        return f'<All Channels guild={self.guild}>'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AppCommand(Hashable):
 | 
			
		||||
    """Represents a application command.
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -61,10 +61,13 @@ if TYPE_CHECKING:
 | 
			
		||||
    from .types.invite import Invite as InvitePayload
 | 
			
		||||
    from .types.role import Role as RolePayload
 | 
			
		||||
    from .types.snowflake import Snowflake
 | 
			
		||||
    from .types.command import ApplicationCommandPermissions
 | 
			
		||||
    from .user import User
 | 
			
		||||
    from .stage_instance import StageInstance
 | 
			
		||||
    from .sticker import GuildSticker
 | 
			
		||||
    from .threads import Thread
 | 
			
		||||
    from .integrations import PartialIntegration
 | 
			
		||||
    from .app_commands import AppCommand
 | 
			
		||||
 | 
			
		||||
    TargetType = Union[
 | 
			
		||||
        Guild, abc.GuildChannel, Member, User, Role, Invite, Emoji, StageInstance, GuildSticker, Thread, Object, None
 | 
			
		||||
@@ -253,6 +256,24 @@ class AuditLogChanges:
 | 
			
		||||
        self.before: AuditLogDiff = AuditLogDiff()
 | 
			
		||||
        self.after: AuditLogDiff = AuditLogDiff()
 | 
			
		||||
 | 
			
		||||
        if entry.action is enums.AuditLogAction.app_command_permission_update:
 | 
			
		||||
            # special case entire process since each
 | 
			
		||||
            # element in data is a different target
 | 
			
		||||
            self.before.app_command_permissions = []
 | 
			
		||||
            self.after.app_command_permissions = []
 | 
			
		||||
 | 
			
		||||
            for d in data:
 | 
			
		||||
 | 
			
		||||
                self._handle_app_command_permissions(
 | 
			
		||||
                    self.before,
 | 
			
		||||
                    self.after,
 | 
			
		||||
                    entry,
 | 
			
		||||
                    int(d['key']),
 | 
			
		||||
                    d.get('old_value'),  # type: ignore # old value will be an ApplicationCommandPermissions if present
 | 
			
		||||
                    d.get('new_value'),  # type: ignore # new value will be an ApplicationCommandPermissions if present
 | 
			
		||||
                )
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        for elem in data:
 | 
			
		||||
            attr = elem['key']
 | 
			
		||||
 | 
			
		||||
@@ -324,6 +345,52 @@ class AuditLogChanges:
 | 
			
		||||
 | 
			
		||||
        setattr(second, 'roles', data)
 | 
			
		||||
 | 
			
		||||
    def _handle_app_command_permissions(
 | 
			
		||||
        self,
 | 
			
		||||
        before: AuditLogDiff,
 | 
			
		||||
        after: AuditLogDiff,
 | 
			
		||||
        entry: AuditLogEntry,
 | 
			
		||||
        target_id: int,
 | 
			
		||||
        old_value: Optional[ApplicationCommandPermissions],
 | 
			
		||||
        new_value: Optional[ApplicationCommandPermissions],
 | 
			
		||||
    ):
 | 
			
		||||
        guild = entry.guild
 | 
			
		||||
 | 
			
		||||
        old_permission = new_permission = target = None
 | 
			
		||||
 | 
			
		||||
        if target_id == (guild.id - 1):
 | 
			
		||||
            # avoid circular import
 | 
			
		||||
            from .app_commands import AllChannels
 | 
			
		||||
 | 
			
		||||
            # all channels
 | 
			
		||||
            target = AllChannels(guild)
 | 
			
		||||
        else:
 | 
			
		||||
            # get type and determine role, user or channel
 | 
			
		||||
            _value = old_value or new_value
 | 
			
		||||
            if _value is None:
 | 
			
		||||
                return
 | 
			
		||||
            permission_type = _value['type']
 | 
			
		||||
            if permission_type == 1:
 | 
			
		||||
                # role
 | 
			
		||||
                target = guild.get_role(target_id)
 | 
			
		||||
            elif permission_type == 2:
 | 
			
		||||
                # user
 | 
			
		||||
                target = entry._get_member(target_id)
 | 
			
		||||
            elif permission_type == 3:
 | 
			
		||||
                # channel
 | 
			
		||||
                target = guild.get_channel(target_id)
 | 
			
		||||
 | 
			
		||||
        if target is None:
 | 
			
		||||
            target = Object(target_id)
 | 
			
		||||
 | 
			
		||||
        if old_value is not None:
 | 
			
		||||
            old_permission = old_value['permission']
 | 
			
		||||
            before.app_command_permissions.append((target, old_permission))
 | 
			
		||||
 | 
			
		||||
        if new_value is not None:
 | 
			
		||||
            new_permission = new_value['permission']
 | 
			
		||||
            after.app_command_permissions.append((target, new_permission))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class _AuditLogProxy:
 | 
			
		||||
    def __init__(self, **kwargs: Any) -> None:
 | 
			
		||||
@@ -397,10 +464,20 @@ class AuditLogEntry(Hashable):
 | 
			
		||||
        which actions have this field filled out.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self, *, users: Dict[int, User], data: AuditLogEntryPayload, guild: Guild):
 | 
			
		||||
    def __init__(
 | 
			
		||||
        self,
 | 
			
		||||
        *,
 | 
			
		||||
        users: Dict[int, User],
 | 
			
		||||
        integrations: Dict[int, PartialIntegration],
 | 
			
		||||
        app_commands: Dict[int, AppCommand],
 | 
			
		||||
        data: AuditLogEntryPayload,
 | 
			
		||||
        guild: Guild,
 | 
			
		||||
    ):
 | 
			
		||||
        self._state: ConnectionState = guild._state
 | 
			
		||||
        self.guild: Guild = guild
 | 
			
		||||
        self._users: Dict[int, User] = users
 | 
			
		||||
        self._integrations: Dict[int, PartialIntegration] = integrations
 | 
			
		||||
        self._app_commands: Dict[int, AppCommand] = app_commands
 | 
			
		||||
        self._from_data(data)
 | 
			
		||||
 | 
			
		||||
    def _from_data(self, data: AuditLogEntryPayload) -> None:
 | 
			
		||||
@@ -418,7 +495,7 @@ class AuditLogEntry(Hashable):
 | 
			
		||||
            _AuditLogProxyMemberDisconnect,
 | 
			
		||||
            _AuditLogProxyPinAction,
 | 
			
		||||
            _AuditLogProxyStageInstanceAction,
 | 
			
		||||
            Member, User, None,
 | 
			
		||||
            Member, User, None, PartialIntegration,
 | 
			
		||||
            Role, Object
 | 
			
		||||
        ] = None
 | 
			
		||||
        # fmt: on
 | 
			
		||||
@@ -463,6 +540,9 @@ class AuditLogEntry(Hashable):
 | 
			
		||||
                self.extra = _AuditLogProxyStageInstanceAction(
 | 
			
		||||
                    channel=self.guild.get_channel(channel_id) or Object(id=channel_id)
 | 
			
		||||
                )
 | 
			
		||||
            elif self.action.name.startswith('app_command'):
 | 
			
		||||
                application_id = int(extra['application_id'])
 | 
			
		||||
                self.extra = self._get_integration_by_app_id(application_id) or Object(application_id)
 | 
			
		||||
 | 
			
		||||
        # this key is not present when the above is present, typically.
 | 
			
		||||
        # It's a list of { new_value: a, old_value: b, key: c }
 | 
			
		||||
@@ -481,6 +561,25 @@ class AuditLogEntry(Hashable):
 | 
			
		||||
 | 
			
		||||
        return self.guild.get_member(user_id) or self._users.get(user_id)
 | 
			
		||||
 | 
			
		||||
    def _get_integration(self, integration_id: Optional[int]) -> Optional[PartialIntegration]:
 | 
			
		||||
        if integration_id is None:
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
        return self._integrations.get(integration_id)
 | 
			
		||||
 | 
			
		||||
    def _get_integration_by_app_id(self, application_id: Optional[int]) -> Optional[PartialIntegration]:
 | 
			
		||||
        if application_id is None:
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
        # get PartialIntegration by application id
 | 
			
		||||
        return utils.get(self._integrations.values(), application_id=application_id)
 | 
			
		||||
 | 
			
		||||
    def _get_app_command(self, app_command_id: Optional[int]) -> Optional[AppCommand]:
 | 
			
		||||
        if app_command_id is None:
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
        return self._app_commands.get(app_command_id)
 | 
			
		||||
 | 
			
		||||
    def __repr__(self) -> str:
 | 
			
		||||
        return f'<AuditLogEntry id={self.id} action={self.action} user={self.user!r}>'
 | 
			
		||||
 | 
			
		||||
@@ -575,3 +674,12 @@ class AuditLogEntry(Hashable):
 | 
			
		||||
 | 
			
		||||
    def _convert_target_guild_scheduled_event(self, target_id: int) -> Union[ScheduledEvent, Object]:
 | 
			
		||||
        return self.guild.get_scheduled_event(target_id) or Object(id=target_id)
 | 
			
		||||
 | 
			
		||||
    def _convert_target_integration(self, target_id: int) -> Union[PartialIntegration, Object]:
 | 
			
		||||
        return self._get_integration(target_id) or Object(target_id)
 | 
			
		||||
 | 
			
		||||
    def _convert_target_app_command(self, target_id: int) -> Union[AppCommand, Object]:
 | 
			
		||||
        return self._get_app_command(target_id) or Object(target_id)
 | 
			
		||||
 | 
			
		||||
    def _convert_target_integration_or_app_command(self, target_id: int) -> Union[PartialIntegration, AppCommand, Object]:
 | 
			
		||||
        return self._get_integration_by_app_id(target_id) or self._get_app_command(target_id) or Object(target_id)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										192
									
								
								discord/enums.py
									
									
									
									
									
								
							
							
						
						
									
										192
									
								
								discord/enums.py
									
									
									
									
									
								
							@@ -298,106 +298,108 @@ class AuditLogActionCategory(Enum):
 | 
			
		||||
 | 
			
		||||
class AuditLogAction(Enum):
 | 
			
		||||
    # fmt: off
 | 
			
		||||
    guild_update             = 1
 | 
			
		||||
    channel_create           = 10
 | 
			
		||||
    channel_update           = 11
 | 
			
		||||
    channel_delete           = 12
 | 
			
		||||
    overwrite_create         = 13
 | 
			
		||||
    overwrite_update         = 14
 | 
			
		||||
    overwrite_delete         = 15
 | 
			
		||||
    kick                     = 20
 | 
			
		||||
    member_prune             = 21
 | 
			
		||||
    ban                      = 22
 | 
			
		||||
    unban                    = 23
 | 
			
		||||
    member_update            = 24
 | 
			
		||||
    member_role_update       = 25
 | 
			
		||||
    member_move              = 26
 | 
			
		||||
    member_disconnect        = 27
 | 
			
		||||
    bot_add                  = 28
 | 
			
		||||
    role_create              = 30
 | 
			
		||||
    role_update              = 31
 | 
			
		||||
    role_delete              = 32
 | 
			
		||||
    invite_create            = 40
 | 
			
		||||
    invite_update            = 41
 | 
			
		||||
    invite_delete            = 42
 | 
			
		||||
    webhook_create           = 50
 | 
			
		||||
    webhook_update           = 51
 | 
			
		||||
    webhook_delete           = 52
 | 
			
		||||
    emoji_create             = 60
 | 
			
		||||
    emoji_update             = 61
 | 
			
		||||
    emoji_delete             = 62
 | 
			
		||||
    message_delete           = 72
 | 
			
		||||
    message_bulk_delete      = 73
 | 
			
		||||
    message_pin              = 74
 | 
			
		||||
    message_unpin            = 75
 | 
			
		||||
    integration_create       = 80
 | 
			
		||||
    integration_update       = 81
 | 
			
		||||
    integration_delete       = 82
 | 
			
		||||
    stage_instance_create    = 83
 | 
			
		||||
    stage_instance_update    = 84
 | 
			
		||||
    stage_instance_delete    = 85
 | 
			
		||||
    sticker_create           = 90
 | 
			
		||||
    sticker_update           = 91
 | 
			
		||||
    sticker_delete           = 92
 | 
			
		||||
    scheduled_event_create   = 100
 | 
			
		||||
    scheduled_event_update   = 101
 | 
			
		||||
    scheduled_event_delete   = 102
 | 
			
		||||
    thread_create            = 110
 | 
			
		||||
    thread_update            = 111
 | 
			
		||||
    thread_delete            = 112
 | 
			
		||||
    guild_update                  = 1
 | 
			
		||||
    channel_create                = 10
 | 
			
		||||
    channel_update                = 11
 | 
			
		||||
    channel_delete                = 12
 | 
			
		||||
    overwrite_create              = 13
 | 
			
		||||
    overwrite_update              = 14
 | 
			
		||||
    overwrite_delete              = 15
 | 
			
		||||
    kick                          = 20
 | 
			
		||||
    member_prune                  = 21
 | 
			
		||||
    ban                           = 22
 | 
			
		||||
    unban                         = 23
 | 
			
		||||
    member_update                 = 24
 | 
			
		||||
    member_role_update            = 25
 | 
			
		||||
    member_move                   = 26
 | 
			
		||||
    member_disconnect             = 27
 | 
			
		||||
    bot_add                       = 28
 | 
			
		||||
    role_create                   = 30
 | 
			
		||||
    role_update                   = 31
 | 
			
		||||
    role_delete                   = 32
 | 
			
		||||
    invite_create                 = 40
 | 
			
		||||
    invite_update                 = 41
 | 
			
		||||
    invite_delete                 = 42
 | 
			
		||||
    webhook_create                = 50
 | 
			
		||||
    webhook_update                = 51
 | 
			
		||||
    webhook_delete                = 52
 | 
			
		||||
    emoji_create                  = 60
 | 
			
		||||
    emoji_update                  = 61
 | 
			
		||||
    emoji_delete                  = 62
 | 
			
		||||
    message_delete                = 72
 | 
			
		||||
    message_bulk_delete           = 73
 | 
			
		||||
    message_pin                   = 74
 | 
			
		||||
    message_unpin                 = 75
 | 
			
		||||
    integration_create            = 80
 | 
			
		||||
    integration_update            = 81
 | 
			
		||||
    integration_delete            = 82
 | 
			
		||||
    stage_instance_create         = 83
 | 
			
		||||
    stage_instance_update         = 84
 | 
			
		||||
    stage_instance_delete         = 85
 | 
			
		||||
    sticker_create                = 90
 | 
			
		||||
    sticker_update                = 91
 | 
			
		||||
    sticker_delete                = 92
 | 
			
		||||
    scheduled_event_create        = 100
 | 
			
		||||
    scheduled_event_update        = 101
 | 
			
		||||
    scheduled_event_delete        = 102
 | 
			
		||||
    thread_create                 = 110
 | 
			
		||||
    thread_update                 = 111
 | 
			
		||||
    thread_delete                 = 112
 | 
			
		||||
    app_command_permission_update = 121
 | 
			
		||||
    # fmt: on
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def category(self) -> Optional[AuditLogActionCategory]:
 | 
			
		||||
        # fmt: off
 | 
			
		||||
        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,
 | 
			
		||||
            AuditLogAction.sticker_create:         AuditLogActionCategory.create,
 | 
			
		||||
            AuditLogAction.sticker_update:         AuditLogActionCategory.update,
 | 
			
		||||
            AuditLogAction.sticker_delete:         AuditLogActionCategory.delete,
 | 
			
		||||
            AuditLogAction.scheduled_event_create: AuditLogActionCategory.create,
 | 
			
		||||
            AuditLogAction.scheduled_event_update: AuditLogActionCategory.update,
 | 
			
		||||
            AuditLogAction.scheduled_event_delete: AuditLogActionCategory.delete,
 | 
			
		||||
            AuditLogAction.thread_create:          AuditLogActionCategory.create,
 | 
			
		||||
            AuditLogAction.thread_update:          AuditLogActionCategory.update,
 | 
			
		||||
            AuditLogAction.thread_delete:          AuditLogActionCategory.delete,
 | 
			
		||||
            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,
 | 
			
		||||
            AuditLogAction.sticker_create:                AuditLogActionCategory.create,
 | 
			
		||||
            AuditLogAction.sticker_update:                AuditLogActionCategory.update,
 | 
			
		||||
            AuditLogAction.sticker_delete:                AuditLogActionCategory.delete,
 | 
			
		||||
            AuditLogAction.scheduled_event_create:        AuditLogActionCategory.create,
 | 
			
		||||
            AuditLogAction.scheduled_event_update:        AuditLogActionCategory.update,
 | 
			
		||||
            AuditLogAction.scheduled_event_delete:        AuditLogActionCategory.delete,
 | 
			
		||||
            AuditLogAction.thread_create:                 AuditLogActionCategory.create,
 | 
			
		||||
            AuditLogAction.thread_delete:                 AuditLogActionCategory.delete,
 | 
			
		||||
            AuditLogAction.thread_update:                 AuditLogActionCategory.update,
 | 
			
		||||
            AuditLogAction.app_command_permission_update: AuditLogActionCategory.update,
 | 
			
		||||
        }
 | 
			
		||||
        # fmt: on
 | 
			
		||||
        return lookup[self]
 | 
			
		||||
@@ -435,6 +437,8 @@ class AuditLogAction(Enum):
 | 
			
		||||
            return 'guild_scheduled_event'
 | 
			
		||||
        elif v < 113:
 | 
			
		||||
            return 'thread'
 | 
			
		||||
        elif v < 122:
 | 
			
		||||
            return 'integration_or_app_command'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UserFlags(Enum):
 | 
			
		||||
 
 | 
			
		||||
@@ -78,7 +78,7 @@ from .invite import Invite
 | 
			
		||||
from .widget import Widget
 | 
			
		||||
from .asset import Asset
 | 
			
		||||
from .flags import SystemChannelFlags
 | 
			
		||||
from .integrations import Integration, _integration_factory
 | 
			
		||||
from .integrations import Integration, PartialIntegration, _integration_factory
 | 
			
		||||
from .scheduled_event import ScheduledEvent
 | 
			
		||||
from .stage_instance import StageInstance
 | 
			
		||||
from .threads import Thread, ThreadMember
 | 
			
		||||
@@ -3346,11 +3346,11 @@ class Guild(Hashable):
 | 
			
		||||
 | 
			
		||||
            if data and entries:
 | 
			
		||||
                if limit is not None:
 | 
			
		||||
                    limit -= len(data)
 | 
			
		||||
                    limit -= len(entries)
 | 
			
		||||
 | 
			
		||||
                before = Object(id=int(entries[-1]['id']))
 | 
			
		||||
 | 
			
		||||
            return data.get('users', []), entries, before, limit
 | 
			
		||||
            return data, entries, after, limit
 | 
			
		||||
 | 
			
		||||
        async def _after_strategy(retrieve, after, limit):
 | 
			
		||||
            after_id = after.id if after else None
 | 
			
		||||
@@ -3362,11 +3362,11 @@ class Guild(Hashable):
 | 
			
		||||
 | 
			
		||||
            if data and entries:
 | 
			
		||||
                if limit is not None:
 | 
			
		||||
                    limit -= len(data)
 | 
			
		||||
                    limit -= len(entries)
 | 
			
		||||
 | 
			
		||||
                after = Object(id=int(entries[0]['id']))
 | 
			
		||||
 | 
			
		||||
            return data.get('users', []), entries, after, limit
 | 
			
		||||
            return data, entries, after, limit
 | 
			
		||||
 | 
			
		||||
        if user is not MISSING:
 | 
			
		||||
            user_id = user.id
 | 
			
		||||
@@ -3397,31 +3397,46 @@ class Guild(Hashable):
 | 
			
		||||
            if after and after != OLDEST_OBJECT:
 | 
			
		||||
                predicate = lambda m: int(m['id']) > after.id
 | 
			
		||||
 | 
			
		||||
        # avoid circular import
 | 
			
		||||
        from .app_commands import AppCommand
 | 
			
		||||
 | 
			
		||||
        while True:
 | 
			
		||||
            retrieve = min(100 if limit is None else limit, 100)
 | 
			
		||||
            if retrieve < 1:
 | 
			
		||||
                return
 | 
			
		||||
 | 
			
		||||
            raw_users, data, state, limit = await strategy(retrieve, state, limit)
 | 
			
		||||
            data, raw_entries, state, limit = await strategy(retrieve, state, limit)
 | 
			
		||||
 | 
			
		||||
            # Terminate loop on next iteration; there's no data left after this
 | 
			
		||||
            if len(data) < 100:
 | 
			
		||||
            if len(raw_entries) < 100:
 | 
			
		||||
                limit = 0
 | 
			
		||||
 | 
			
		||||
            if reverse:
 | 
			
		||||
                data = reversed(data)
 | 
			
		||||
                raw_entries = reversed(raw_entries)
 | 
			
		||||
            if predicate:
 | 
			
		||||
                data = filter(predicate, data)
 | 
			
		||||
                raw_entries = filter(predicate, raw_entries)
 | 
			
		||||
 | 
			
		||||
            users = (User(data=raw_user, state=self._state) for raw_user in raw_users)
 | 
			
		||||
            users = (User(data=raw_user, state=self._state) for raw_user in data.get('users', []))
 | 
			
		||||
            user_map = {user.id: user for user in users}
 | 
			
		||||
 | 
			
		||||
            for raw_entry in data:
 | 
			
		||||
            integrations = (PartialIntegration(data=raw_i, guild=self) for raw_i in data.get('integrations', []))
 | 
			
		||||
            integration_map = {integration.id: integration for integration in integrations}
 | 
			
		||||
 | 
			
		||||
            app_commands = (AppCommand(data=raw_cmd, state=self._state) for raw_cmd in data.get('application_commands', []))
 | 
			
		||||
            app_command_map = {app_command.id: app_command for app_command in app_commands}
 | 
			
		||||
 | 
			
		||||
            for raw_entry in raw_entries:
 | 
			
		||||
                # Weird Discord quirk
 | 
			
		||||
                if raw_entry['action_type'] is None:
 | 
			
		||||
                    continue
 | 
			
		||||
 | 
			
		||||
                yield AuditLogEntry(data=raw_entry, users=user_map, guild=self)
 | 
			
		||||
                yield AuditLogEntry(
 | 
			
		||||
                    data=raw_entry,
 | 
			
		||||
                    users=user_map,
 | 
			
		||||
                    integrations=integration_map,
 | 
			
		||||
                    app_commands=app_command_map,
 | 
			
		||||
                    guild=self,
 | 
			
		||||
                )
 | 
			
		||||
 | 
			
		||||
    async def widget(self) -> Widget:
 | 
			
		||||
        """|coro|
 | 
			
		||||
 
 | 
			
		||||
@@ -36,6 +36,7 @@ __all__ = (
 | 
			
		||||
    'Integration',
 | 
			
		||||
    'StreamIntegration',
 | 
			
		||||
    'BotIntegration',
 | 
			
		||||
    'PartialIntegration',
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
if TYPE_CHECKING:
 | 
			
		||||
@@ -49,6 +50,7 @@ if TYPE_CHECKING:
 | 
			
		||||
        BotIntegration as BotIntegrationPayload,
 | 
			
		||||
        IntegrationType,
 | 
			
		||||
        IntegrationApplication as IntegrationApplicationPayload,
 | 
			
		||||
        PartialIntegration as PartialIntegrationPayload,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -115,7 +117,7 @@ class Integration:
 | 
			
		||||
        self._from_data(data)
 | 
			
		||||
 | 
			
		||||
    def __repr__(self) -> str:
 | 
			
		||||
        return f"<{self.__class__.__name__} id={self.id} name={self.name!r}>"
 | 
			
		||||
        return f'<{self.__class__.__name__} id={self.id} name={self.name!r}>'
 | 
			
		||||
 | 
			
		||||
    def _from_data(self, data: IntegrationPayload) -> None:
 | 
			
		||||
        self.id: int = int(data['id'])
 | 
			
		||||
@@ -362,6 +364,53 @@ class BotIntegration(Integration):
 | 
			
		||||
        self.application: IntegrationApplication = IntegrationApplication(data=data['application'], state=self._state)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class PartialIntegration:
 | 
			
		||||
    """Represents a partial guild integration.
 | 
			
		||||
 | 
			
		||||
    .. versionadded:: 2.0
 | 
			
		||||
 | 
			
		||||
    Attributes
 | 
			
		||||
    -----------
 | 
			
		||||
    id: :class:`int`
 | 
			
		||||
        The integration ID.
 | 
			
		||||
    name: :class:`str`
 | 
			
		||||
        The integration name.
 | 
			
		||||
    guild: :class:`Guild`
 | 
			
		||||
        The guild of the integration.
 | 
			
		||||
    type: :class:`str`
 | 
			
		||||
        The integration type (i.e. Twitch).
 | 
			
		||||
    account: :class:`IntegrationAccount`
 | 
			
		||||
        The account linked to this integration.
 | 
			
		||||
    application_id: Optional[:class:`int`]
 | 
			
		||||
        The id of the application this integration belongs to.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    __slots__ = (
 | 
			
		||||
        'guild',
 | 
			
		||||
        '_state',
 | 
			
		||||
        'id',
 | 
			
		||||
        'type',
 | 
			
		||||
        'name',
 | 
			
		||||
        'account',
 | 
			
		||||
        'application_id',
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    def __init__(self, *, data: PartialIntegrationPayload, guild: Guild):
 | 
			
		||||
        self.guild: Guild = guild
 | 
			
		||||
        self._state: ConnectionState = guild._state
 | 
			
		||||
        self._from_data(data)
 | 
			
		||||
 | 
			
		||||
    def __repr__(self) -> str:
 | 
			
		||||
        return f'<{self.__class__.__name__} id={self.id} name={self.name!r}>'
 | 
			
		||||
 | 
			
		||||
    def _from_data(self, data: PartialIntegrationPayload) -> None:
 | 
			
		||||
        self.id: int = int(data['id'])
 | 
			
		||||
        self.type: IntegrationType = data['type']
 | 
			
		||||
        self.name: str = data['name']
 | 
			
		||||
        self.account: IntegrationAccount = IntegrationAccount(data['account'])
 | 
			
		||||
        self.application_id: Optional[int] = _get_as_snowflake(data, 'application_id')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def _integration_factory(value: str) -> Tuple[Type[Integration], str]:
 | 
			
		||||
    if value == 'discord':
 | 
			
		||||
        return BotIntegration, value
 | 
			
		||||
 
 | 
			
		||||
@@ -36,6 +36,7 @@ from .snowflake import Snowflake
 | 
			
		||||
from .role import Role
 | 
			
		||||
from .channel import ChannelType, PrivacyLevel, VideoQualityMode, PermissionOverwrite
 | 
			
		||||
from .threads import Thread
 | 
			
		||||
from .command import ApplicationCommand, ApplicationCommandPermissions
 | 
			
		||||
 | 
			
		||||
AuditLogEvent = Literal[
 | 
			
		||||
    1,
 | 
			
		||||
@@ -85,6 +86,7 @@ AuditLogEvent = Literal[
 | 
			
		||||
    110,
 | 
			
		||||
    111,
 | 
			
		||||
    112,
 | 
			
		||||
    121,
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -242,6 +244,12 @@ class _AuditLogChange_EntityType(TypedDict):
 | 
			
		||||
    old_value: EntityType
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class _AuditLogChange_AppCommandPermissions(TypedDict):
 | 
			
		||||
    key: str
 | 
			
		||||
    new_value: ApplicationCommandPermissions
 | 
			
		||||
    old_value: ApplicationCommandPermissions
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
AuditLogChange = Union[
 | 
			
		||||
    _AuditLogChange_Str,
 | 
			
		||||
    _AuditLogChange_AssetHash,
 | 
			
		||||
@@ -260,6 +268,7 @@ AuditLogChange = Union[
 | 
			
		||||
    _AuditLogChange_PrivacyLevel,
 | 
			
		||||
    _AuditLogChange_Status,
 | 
			
		||||
    _AuditLogChange_EntityType,
 | 
			
		||||
    _AuditLogChange_AppCommandPermissions,
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -272,6 +281,8 @@ class AuditEntryInfo(TypedDict):
 | 
			
		||||
    id: Snowflake
 | 
			
		||||
    type: Literal['0', '1']
 | 
			
		||||
    role_name: str
 | 
			
		||||
    application_id: Snowflake
 | 
			
		||||
    guild_id: Snowflake
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AuditLogEntry(TypedDict):
 | 
			
		||||
@@ -291,3 +302,4 @@ class AuditLog(TypedDict):
 | 
			
		||||
    integrations: List[PartialIntegration]
 | 
			
		||||
    threads: List[Thread]
 | 
			
		||||
    guild_scheduled_events: List[GuildScheduledEvent]
 | 
			
		||||
    application_commands: List[ApplicationCommand]
 | 
			
		||||
 
 | 
			
		||||
@@ -192,7 +192,7 @@ ApplicationCommand = Union[
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
ApplicationCommandPermissionType = Literal[1, 2]
 | 
			
		||||
ApplicationCommandPermissionType = Literal[1, 2, 3]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ApplicationCommandPermissions(TypedDict):
 | 
			
		||||
 
 | 
			
		||||
@@ -53,6 +53,7 @@ class PartialIntegration(TypedDict):
 | 
			
		||||
    name: str
 | 
			
		||||
    type: IntegrationType
 | 
			
		||||
    account: IntegrationAccount
 | 
			
		||||
    application_id: Snowflake
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
IntegrationType = Literal['twitch', 'youtube', 'discord']
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										43
									
								
								docs/api.rst
									
									
									
									
									
								
							
							
						
						
									
										43
									
								
								docs/api.rst
									
									
									
									
									
								
							@@ -2239,7 +2239,8 @@ of :class:`enum.Enum`.
 | 
			
		||||
        A guild integration was created.
 | 
			
		||||
 | 
			
		||||
        When this is the action, the type of :attr:`~AuditLogEntry.target` is
 | 
			
		||||
        the :class:`Object` with the integration ID of the integration which was created.
 | 
			
		||||
        a :class:`PartialIntegration` or :class:`Object` with the
 | 
			
		||||
        integration ID of the integration which was created.
 | 
			
		||||
 | 
			
		||||
        .. versionadded:: 1.3
 | 
			
		||||
 | 
			
		||||
@@ -2248,7 +2249,8 @@ of :class:`enum.Enum`.
 | 
			
		||||
        A guild integration was updated.
 | 
			
		||||
 | 
			
		||||
        When this is the action, the type of :attr:`~AuditLogEntry.target` is
 | 
			
		||||
        the :class:`Object` with the integration ID of the integration which was updated.
 | 
			
		||||
        a :class:`PartialIntegration` or :class:`Object` with the
 | 
			
		||||
        integration ID of the integration which was updated.
 | 
			
		||||
 | 
			
		||||
        .. versionadded:: 1.3
 | 
			
		||||
 | 
			
		||||
@@ -2257,7 +2259,8 @@ of :class:`enum.Enum`.
 | 
			
		||||
        A guild integration was deleted.
 | 
			
		||||
 | 
			
		||||
        When this is the action, the type of :attr:`~AuditLogEntry.target` is
 | 
			
		||||
        the :class:`Object` with the integration ID of the integration which was deleted.
 | 
			
		||||
        a :class:`PartialIntegration` or :class:`Object` with the
 | 
			
		||||
        integration ID of the integration which was deleted.
 | 
			
		||||
 | 
			
		||||
        .. versionadded:: 1.3
 | 
			
		||||
 | 
			
		||||
@@ -2465,6 +2468,27 @@ of :class:`enum.Enum`.
 | 
			
		||||
 | 
			
		||||
        .. versionadded:: 2.0
 | 
			
		||||
 | 
			
		||||
    .. attribute:: app_command_permission_update
 | 
			
		||||
 | 
			
		||||
        An application command or integrations application command permissions
 | 
			
		||||
        were updated.
 | 
			
		||||
 | 
			
		||||
        When this is the action, the type of :attr:`~AuditLogEntry.target` is
 | 
			
		||||
        a :class:`PartialIntegration` for an integrations general permissions,
 | 
			
		||||
        :class:`~discord.app_commands.AppCommand` for a specific commands permissions,
 | 
			
		||||
        or :class:`Object` with the ID of the command or integration which
 | 
			
		||||
        was updated.
 | 
			
		||||
 | 
			
		||||
        When this is the action, the type of :attr:`~AuditLogEntry.extra` is
 | 
			
		||||
        set to an :class:`PartialIntegration` or :class:`Object` with the ID of
 | 
			
		||||
        application that command or integration belongs to.
 | 
			
		||||
 | 
			
		||||
        Possible attributes for :class:`AuditLogDiff`:
 | 
			
		||||
 | 
			
		||||
        - :attr:`~AuditLogDiff.app_command_permissions`
 | 
			
		||||
 | 
			
		||||
        .. versionadded:: 2.0
 | 
			
		||||
 | 
			
		||||
.. class:: AuditLogActionCategory
 | 
			
		||||
 | 
			
		||||
    Represents the category that the :class:`AuditLogAction` belongs to.
 | 
			
		||||
@@ -3477,6 +3501,16 @@ AuditLogDiff
 | 
			
		||||
 | 
			
		||||
        :type: :class:`Asset`
 | 
			
		||||
 | 
			
		||||
    .. attribute:: app_command_permissions
 | 
			
		||||
 | 
			
		||||
        A list of application command permission tuples that represents a
 | 
			
		||||
        target and a :class:`bool` for said target.
 | 
			
		||||
 | 
			
		||||
        The first element is the object being targeted, which can either
 | 
			
		||||
        be a :class:`Member`, :class:`abc.GuildChannel`,
 | 
			
		||||
        :class:`~discord.app_commands.AllChannels`, or :class:`Role`.
 | 
			
		||||
        :type: List[Tuple[target, :class:`bool`]]
 | 
			
		||||
 | 
			
		||||
.. this is currently missing the following keys: reason and application_id
 | 
			
		||||
   I'm not sure how to about porting these
 | 
			
		||||
 | 
			
		||||
@@ -3727,6 +3761,9 @@ Integration
 | 
			
		||||
.. autoclass:: StreamIntegration()
 | 
			
		||||
    :members:
 | 
			
		||||
 | 
			
		||||
.. autoclass:: PartialIntegration()
 | 
			
		||||
    :members:
 | 
			
		||||
 | 
			
		||||
Member
 | 
			
		||||
~~~~~~
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -129,6 +129,14 @@ Argument
 | 
			
		||||
.. autoclass:: discord.app_commands.Argument()
 | 
			
		||||
    :members:
 | 
			
		||||
 | 
			
		||||
AllChannels
 | 
			
		||||
~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
.. attributetable:: discord.app_commands.AllChannels
 | 
			
		||||
 | 
			
		||||
.. autoclass:: discord.app_commands.AllChannels()
 | 
			
		||||
    :members:
 | 
			
		||||
 | 
			
		||||
Data Classes
 | 
			
		||||
--------------
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user