Пример #1
0
 def __get_member(self, action: proto.Action) -> discord.Member:
     assert action.HasField('user_id')
     # FIXME: This will not work once the bot is larger than a single process.
     guild = self.__get_guild(action)
     if guild is None:
         return None
     return utils.get_member_async(guild, action.user_id)
Пример #2
0
 async def _apply_ban(self, action: proto.Action) -> None:
     assert action.WhichOneof('details') == 'ban'
     guild = self.__get_guild(action)
     if guild is None:
         return
     assert action.HasField('user_id')
     user = fake.FakeSnowflake(id=action.user_id)
     if action.ban.type != proto.BanMember.UNBAN:
         await guild.ban(user,
                         reason=_get_reason(action),
                         delete_message_days=action.ban.delete_message_days)
     if action.ban.type != proto.BanMember.BAN:
         await guild.unban(user, reason=_get_reason(action))
Пример #3
0
def invert_action(action: proto.Action) -> proto.Action:
    new_action = proto.Action()
    new_action.CopyFrom(action)

    if action.HasField('reason'):
        new_action.reason = 'Undo: ' + action.reason
    new_action.ClearField('duration')

    try:
        INVERT_MAPPING[action.WhichOneof('details')](new_action)
    except KeyError:
        raise ValueError('Provided action cannot be inverted.')

    return new_action
Пример #4
0
    async def _apply_command(self, action: proto.Action) -> None:
        assert action.WhichOneof('details') == 'command'
        channel = self.bot.get_channel(action.command.channel_id)
        try:
            guild = channel.guild
        except AttributeError:
            guild = self.bot.get_guild(action.guild_id)

        if action.HasField('user_id'):
            user = (await self.__get_member(action)) if guild is not None \
                    else (await self.__get_user(action))
        else:
            user = (guild.me if guild is not None else self.bot.user)

        ctx = await self.bot.get_automated_context(
            content=action.command.command,
            author=user,
            channel=channel,
            guild=guild)
        async with ctx:
            await self.bot.invoke(ctx)
Пример #5
0
 async def execute(self, action: proto.Action) -> None:
     action_type = action.WhichOneof('details')
     try:
         await getattr(self, "_apply_" + action_type)(action)
         if not action.HasField('duration'):
             return
         # Schedule an undo
         duration = timedelta(seconds=action.duration)
         self.bot.action_manager.schedule(datetime.utcnow() + duration,
                                          invert_action(action))
     except AttributeError:
         raise ValueError(f'Action type not supported: {action_type}')
     except discord.NotFound:
         # If the guild or the target is not found, silence the error
         pass
     except discord.Forbidden:
         # TODO(james7132): Properly report missing permissions
         # If the guild or the target is not found, silence the error
         pass
         self.bot.logger.exception('Error while executing action:')
     except Exception:
         self.bot.logger.exception('Error while executing action:')
Пример #6
0
def _get_reason(action: proto.Action) -> str:
    if action.HasField('reason'):
        return action.reason
    return None
Пример #7
0
 def __get_user(self, action: proto.Action) -> discord.User:
     assert action.HasField('user_id')
     return utils.get_user_async(self.bot, action.user_id)
Пример #8
0
 def __get_guild(self, action: proto.Action) -> discord.Guild:
     assert action.HasField('guild_id')
     return self.bot.get_guild(action.guild_id)