예제 #1
0
    async def snapshot_role(ctx, role: discord.Role, group: RoleGroup = None):
        """Adds role to the internal database"""
        if role.is_bot_managed() or role.is_integration() or role.is_premium_subscriber():
            logger.info(f"Skipping role '{role}' as it's system role")
            raise commands.BadArgument(f"Role '{role}' is a system role")

        if not utils.can_manage_role(ctx.guild.me, role):
            logger.info(f"Skipping role '{role}' as bot cannot manage it")
            raise commands.BadArgument(f"Bot cannot manage role '{role}'")

        if await Role.exists(name=role.name):
            logger.info(f"Skipping role '{role}' as it already exists")
            raise commands.BadArgument(f"Role '{role}' already exists in DB")

        group = group or (await RoleGroup.get_or_create(name=utils.snapshot_role_group))[0]
        number = await db_utils.get_max_number(Role)
        await db_utils.reshuffle(Role, number)
        db_role = Role(name=role.name,
                       color=role.color.value,
                       number=number,
                       archived=False,
                       assignable=False,
                       mentionable=role.mentionable,
                       group=group)
        await db_role.save()
예제 #2
0
    async def update_guilds_roles(self):
        to_update = await Role.exclude(archived=True)
        to_remove = await Role.filter(archived=True).values_list("name", flat=True)

        for guild in self.bot.guilds:
            me = guild.me
            if not me.guild_permissions.manage_roles:
                logger.warning(f"Don't have 'manage roles' permissions in '{guild}'")
                continue

            position = me.top_role.position
            for db_role in to_update:
                role = discord.utils.get(guild.roles, name=db_role.name)
                if role is not None and not utils.can_manage_role(me, role):
                    logger.warning(f"Can't manage role '{db_role.name}' at '{guild}'")
                    continue

                position = max(position - 1, 1)
                await self._setup_role(guild, role, db_role, position)

            for name in to_remove:
                role = discord.utils.get(guild.roles, name=name)
                if role is not None:
                    try:
                        await role.delete()
                    except (discord.errors.Forbidden, discord.errors.HTTPException):
                        logger.warning(f"Failed delete role {name} at {guild}")
예제 #3
0
    async def role_assign(self, ctx: SlashContext, role: discord.Role, member: discord.Member = None):
        """Assign specified role to you or specified member"""
        if member and not isinstance(member, discord.Member):
            raise commands.BadArgument(f"Failed to get member '{member}' info!")
        if not isinstance(role, discord.Role):
            raise commands.BadArgument(f"Failed to get role '{role}' info!")

        await ctx.defer(hidden=True)
        member = member or ctx.author
        logger.info(f"{self.format_caller(ctx)} trying to assign '{role}' to {member}")

        if role in member.roles:
            await ctx.send(f"Looks like {self.member_mention(ctx, member).lower()} already have {role.mention} role ;)",
                           allowed_mentions=discord.AllowedMentions.none(),
                           hidden=True)
            return

        try:
            db_role = await Role.get(name=role.name)
        except exceptions.DoesNotExist:
            logger.warning(f"Role with name '{role}'' not found in database")
            raise commands.BadArgument(f"Role {role.mention} is not in bots database! "
                                       f"You probably shouldn't use that role")

        if (member != ctx.author or db_role.name == utils.bot_manager_role or not db_role.assignable) \
                and not await has_server_perms_from_ctx(ctx):
            # MissingPermissions expects an array of permissions
            logger.info(f"{self.format_caller(ctx)} don't have permissions to assign '{role}' to {member}")
            raise commands.MissingPermissions([utils.bot_manager_role])

        if not utils.can_manage_role(ctx.guild.me, role):
            await ctx.send(f"Sorry, I cannot manage role {role.mention}",
                           allowed_mentions=discord.AllowedMentions.none(),
                           hidden=True)
            return

        group = await db_role.group
        if group.exclusive:
            logger.info(f"Removing roles, conflicting with {role} (if any)")
            await self.remove_conflicting_roles(ctx, member, group)

        await member.add_roles(role)
        logger.info(f"Assigned role '{role}' to {member}")
        await ctx.send(f"Assigned role {role.mention} to {member.mention}",
                       allowed_mentions=discord.AllowedMentions.none(),
                       hidden=True
                       )
예제 #4
0
    async def crew_join(self, ctx: SlashContext, crew, join=True):  # todo all
        """Receive crew roles to get pings when LynxGriffin is streaming or updating comics!"""
        logger.info(f"{ctx.author} trying to {'join' if join else 'leave'} {crew}")

        if not self.has_crews:
            raise commands.CheckFailure(f"Sorry, but this command is unavailable as there is no crew roles in DB.")

        await ctx.defer(hidden=True)
        db_role = await Role.get(id=crew)

        role = discord.utils.get(ctx.guild.roles, name=db_role.name)
        if role is None:
            logger.warning(f"Role with name '{db_role.name}' in not a valid role for {ctx.guild}")
            raise commands.CheckFailure(
                f"Sorry, but this command is unavailable as there is no **{db_role.name}** role "
                f"on this server yet.")

        if not utils.can_manage_role(ctx.guild.me, role):
            await ctx.send(f"Sorry, I cannot manage role {role.mention}",
                           allowed_mentions=discord.AllowedMentions.none(),
                           hidden=True)
            return

        member = ctx.author
        if join:
            if role in member.roles:
                logger.info(f"{ctx.author} already in {db_role.name}")
                await ctx.send(f"Do you need **more** pings, {member.mention}? You're already in {role.mention}",
                               allowed_mentions=discord.AllowedMentions(users=True, roles=False),
                               hidden=True)
            else:
                await member.add_roles(role)
                logger.info(f"{ctx.author} joined {db_role.name}")
                await ctx.send(f"Welcome to the {role.mention}! Enjoy your pings ;)",
                               allowed_mentions=discord.AllowedMentions.none(),
                               hidden=True)
        else:
            if role not in member.roles:
                logger.info(f"{ctx.author} is not in {db_role.name}")
                await ctx.send(f"You're not in the {role.mention}? Never have been 🔫",
                               allowed_mentions=discord.AllowedMentions.none(),
                               hidden=True)
            else:
                await member.remove_roles(role)
                logger.info(f"{ctx.author} left {db_role.name}")
                await ctx.send("Goodbye o7", hidden=True)
예제 #5
0
    async def role_unassign(self, ctx: SlashContext, role: discord.Role, member: discord.Member = None):
        """Remove specified role from you or specified member"""
        if member and not isinstance(member, discord.Member):
            raise commands.BadArgument(f"Failed to get member '{member}' info!")
        if not isinstance(role, discord.Role):
            raise commands.BadArgument(f"Failed to get role '{role}' info!")

        await ctx.defer(hidden=True)
        member = member or ctx.author
        logger.info(f"{self.format_caller(ctx)} trying to remove role '{role}' from {member}")

        if role not in member.roles:
            await ctx.send(f"Looks like {self.member_mention(ctx, member).lower()} "
                           f"don't have {role.mention} role anyways ;)",
                           allowed_mentions=discord.AllowedMentions.none(),
                           hidden=True)
            return

        try:
            db_role = await Role.get(name=role.name)
        except exceptions.DoesNotExist:
            logger.warning(f"Role with name '{role.name}' not found in database")
            raise commands.BadArgument(f"Role {role.mention} is not in bots database!"
                                       f"You probably shouldn't touch that role")

        if (member != ctx.author or not db_role.assignable) and not await has_server_perms_from_ctx(ctx):
            logger.info(f"{self.format_caller(ctx)} don't have permissions to remove '{role}' from {member}")
            # MissingPermissions expects an array of permissions
            raise commands.MissingPermissions([utils.bot_manager_role])

        if not utils.can_manage_role(ctx.guild.me, role):
            await ctx.send(f"Sorry, I cannot manage role {role.mention}",
                           allowed_mentions=discord.AllowedMentions.none(),
                           hidden=True)
            return

        await member.remove_roles(role)
        logger.info(f"Removed role '{role}' from {member}")
        await ctx.send(f"Removed role {role.mention} from {member.mention}",
                       allowed_mentions=discord.AllowedMentions.none(),
                       hidden=True
                       )