예제 #1
0
def get_role_changes(member: Member, role: Role, roleset_name):
    roleset = conf.get_object(member.guild, 'rolesets', roleset_name)
    changes = {
        'member': member,
        OperationType.DELETE: [],
        OperationType.CREATE: [],
        OperationType.RETAIN: []
    }
    if roleset['type'] == 'toggle':
        if member.get_role(role.id) is not None:
            changes[OperationType.DELETE].append(role)
        else:
            changes[OperationType.CREATE].append(role)
    else:
        changes[OperationType.CREATE].append(role)
        if roleset['roles'][
                role.name] and 'secondaryRoles' in roleset['roles'][role.name]:
            changes[OperationType.CREATE].extend([
                find(lambda r: r.name.lower() == role_name.lower(),
                     member.guild.roles)
                for role_name in roleset['roles'][role.name]['secondaryRoles']
            ])
        remove_on_update = []
        if 'removeOnUpdate' in roleset:
            remove_on_update = roleset['removeOnUpdate']
        for current_role in member.roles:
            if current_role.name in roleset['roles'].keys(
            ) or current_role.name in remove_on_update:
                changes[OperationType.DELETE].append(current_role)
    return sanitize_changes(changes)
예제 #2
0
    async def restore_roles(self, ctx, member: discord.Member):
        """Restores the roles a user had before leaving, suggesting they left less than an hour ago.
        The user running this command must have Manage Server permissions.
        Useful for... accidential leaves? Troll leaves? Yeah, not much, but Despair's Horizon wanted it.
        Requires Manage Server permissions or higher."""

        guild_entry = self.bot.role_rolebacks.get(ctx.guild.id)
        if not guild_entry:
            raise commands.BadArgument("That member did not leave in the last hour!")

        member_entry = guild_entry.get(member.id)
        if member_entry is None:
            raise commands.BadArgument("That member did not leave in the last hour!")

        now = discord.utils.utcnow()
        hour_prior = now - datetime.timedelta(hours=1)

        if member_entry["time"] < hour_prior:
            del self.bot.role_rolebacks[ctx.guild.id][member_entry["id"]]
            raise commands.BadArgument("That member did not leave in the last hour!")

        top_role = ctx.guild.me.top_role
        unadded_roles = []
        added_roles = []

        for role in member_entry["roles"]:
            if role.is_default():
                continue
            elif role > top_role or role not in ctx.guild.roles or role.managed:
                unadded_roles.append(role)
            elif member.get_role(role.id):
                continue
            else:
                added_roles.append(role)

        if not added_roles:
            raise commands.BadArgument("There were no roles to restore for this user!")

        try:
            await member.add_roles(
                *added_roles,
                reason=f"Restoring old roles: done by {ctx.author}.",
                atomic=False,
            )

        except discord.HTTPException as error:
            raise utils.CustomCheckFailure(
                (
                    (
                        (
                            "Something happened while trying to restore the roles this"
                            " user had.\n"
                            + "This shouldn't be happening, and this should have been"
                            " caught earlier "
                        )
                        + "by the bot. Try contacting the bot owner about it.\n\n"
                    )
                    + f"Error: `{error}`"
                )
            )

        del self.bot.role_rolebacks[ctx.guild.id][member_entry["id"]]

        final_msg = [f"Roles restored: `{', '.join([r.name for r in added_roles])}`."]
        if unadded_roles:
            final_msg.append(
                f"Roles not restored: `{', '.join([r.name for r in unadded_roles])}`.\n"
                + "This was most likely because these roles are higher than the bot's"
                " own role, the roles no longer exist, "
                + "or the role is managed by Discord and so the bot cannot add it."
            )
        final_msg.append(
            "Please wait a bit for the roles to appear; sometimes Discord is a bit"
            " slow."
        )

        final_msg_str = "\n\n".join(final_msg)
        await ctx.reply(final_msg_str, allowed_mentions=utils.deny_mentions(ctx.author))