Exemplo n.º 1
0
    async def reactionrole_add(self, ctx: Context, msg: Message,
                               emoji: EmojiConverter, role: Role,
                               reverse: bool, auto_remove: bool):
        emoji: PartialEmoji

        if await ReactionRole.get(msg.channel.id, msg.id, str(emoji)):
            raise CommandError(t.rr_link_already_exists)
        if not msg.channel.permissions_for(msg.guild.me).add_reactions:
            raise CommandError(t.rr_link_not_created_no_permissions)

        check_role_assignable(role)

        try:
            await msg.add_reaction(emoji)
        except Forbidden:
            raise CommandError(t.could_not_add_reactions)
        await ReactionRole.create(msg.channel.id, msg.id, str(emoji), role.id,
                                  reverse, auto_remove)
        embed = Embed(title=t.reactionrole,
                      colour=Colors.ReactionRole,
                      description=t.rr_link_created)
        await reply(ctx, embed=embed)
        await send_to_changelog(
            ctx.guild,
            t.log_rr_link_created(emoji, role.id, msg.jump_url,
                                  msg.channel.mention))
Exemplo n.º 2
0
    async def verification_add(self,
                               ctx: Context,
                               role: Role,
                               reverse: bool = False):
        """
        add verification role
        if `reverse` is set to `true`, the role is not added but removed during verification.
        the `verify` command will fail if the user does not have the role.
        """

        check_role_assignable(role)

        if await db.get(VerificationRole, role_id=role.id) is not None:
            raise CommandError(t.verification_role_already_set)

        await VerificationRole.create(role.id, reverse)
        embed = Embed(title=t.verification,
                      description=t.verification_role_added,
                      colour=Colors.Verification)
        await reply(ctx, embed=embed)
        if reverse:
            await send_to_changelog(
                ctx.guild,
                t.log_verification_role_added_reverse(role.name, role.id))
        else:
            await send_to_changelog(
                ctx.guild, t.log_verification_role_added(role.name, role.id))
Exemplo n.º 3
0
    async def unmute(self, ctx: Context, user: UserMemberConverter, *,
                     reason: str):
        """
        unmute a user
        """

        user: Union[Member, User]

        if len(reason) > 900:
            raise CommandError(t.reason_too_long)

        mute_role: Role = await get_mute_role(ctx.guild)

        was_muted = False
        if isinstance(user, Member) and mute_role in user.roles:
            was_muted = True
            check_role_assignable(mute_role)
            await user.remove_roles(mute_role)

        async for mute in await db.stream(
                filter_by(Mute, active=True, member=user.id)):
            await Mute.deactivate(mute.id, ctx.author.id, reason)
            was_muted = True
        if not was_muted:
            raise UserCommandError(user, t.not_muted)

        server_embed = Embed(title=t.unmute,
                             description=t.unmuted_response,
                             colour=Colors.ModTools)
        server_embed.set_author(name=str(user),
                                icon_url=user.display_avatar.url)
        await reply(ctx, embed=server_embed)
        await send_to_changelog_mod(ctx.guild, ctx.message, Colors.unmute,
                                    t.log_unmuted, user, reason)
Exemplo n.º 4
0
    async def roles_add(self, ctx: Context, member: Member, *, role: Role):
        if role in member.roles:
            raise CommandError(t.role_already_assigned)

        if not await is_authorized(ctx.author, role, perma=False):
            raise CommandError(t.role_not_authorized)

        check_role_assignable(role)

        await member.add_roles(role)
        await ctx.message.add_reaction(name_to_emoji["white_check_mark"])
Exemplo n.º 5
0
    async def roles_perma_remove(self, ctx: Context,
                                 member: UserMemberConverter, *, role: Role):
        member: Union[User, Member]

        if not await is_authorized(ctx.author, role, perma=True):
            raise CommandError(t.role_not_authorized)

        check_role_assignable(role)

        if not (row := await db.get(
                PermaRole, member_id=member.id, role_id=role.id)):
            raise CommandError(t.role_not_assigned)
Exemplo n.º 6
0
async def configure_role(ctx: Context,
                         role_name: str,
                         role: Role,
                         check_assignable: bool = False):
    if check_assignable:
        check_role_assignable(role)

    await RoleSettings.set(role_name, role.id)
    await reply(ctx, t.role_set)
    await send_to_changelog(
        ctx.guild,
        t.log_role_set(Config.ROLES[role_name][0], role.name, role.id))
Exemplo n.º 7
0
    async def autorole_add(self, ctx: Context, *, role: Role):
        """
        add a role
        """

        if await AutoRole.exists(role.id):
            raise CommandError(t.ar_already_set)

        check_role_assignable(role)

        await AutoRole.add(role.id)
        await ctx.message.add_reaction(name_to_emoji["white_check_mark"])
        await send_to_changelog(ctx.guild, t.log_ar_added(role))
Exemplo n.º 8
0
    async def roles_auth_add(self, ctx: Context, source: Union[Member, Role],
                             target: Role, allow_perma: bool):
        if await RoleAuth.check(source.id, target.id):
            raise CommandError(t.role_auth_already_exists)
        if isinstance(source, Member) and source.bot:
            raise CommandError(t.no_auth_for_bots)

        check_role_assignable(target)

        await RoleAuth.add(source.id, target.id, allow_perma)
        await reply(ctx, t.role_auth_created)
        await send_to_changelog(ctx.guild,
                                t.log_role_auth_created(source, target))
Exemplo n.º 9
0
    async def mod_loop(self):
        guild: Guild = self.bot.guilds[0]

        async for ban in await db.stream(filter_by(Ban, active=True)):
            if ban.days != -1 and utcnow() >= ban.timestamp + timedelta(
                    days=ban.days):
                await Ban.deactivate(ban.id)

                try:
                    user = await self.bot.fetch_user(ban.member)
                except NotFound:
                    user = ban.member, ban.member_name

                if isinstance(user, User):
                    try:
                        await guild.unban(user)
                    except Forbidden:
                        await send_alert(
                            guild,
                            t.cannot_unban_user_permissions(
                                user.mention, user.id))

                await send_to_changelog_mod(guild, None, Colors.unban,
                                            t.log_unbanned, user,
                                            t.log_unbanned_expired)

        mute_role: Optional[Role] = guild.get_role(await
                                                   RoleSettings.get("mute"))
        if mute_role is None:
            return

        try:
            check_role_assignable(mute_role)
        except CommandError:
            await send_alert(
                guild, t.cannot_assign_mute_role(mute_role, mute_role.id))
            return

        async for mute in await db.stream(filter_by(Mute, active=True)):
            if mute.days != -1 and utcnow() >= mute.timestamp + timedelta(
                    days=mute.days):
                if member := guild.get_member(mute.member):
                    await member.remove_roles(mute_role)
                else:
                    member = mute.member, mute.member_name

                await send_to_changelog_mod(guild, None, Colors.unmute,
                                            t.log_unmuted, member,
                                            t.log_unmuted_expired)
                await Mute.deactivate(mute.id)
Exemplo n.º 10
0
    async def roles_remove(self, ctx: Context, member: Member, *, role: Role):
        if role not in member.roles:
            raise CommandError(t.role_not_assigned)

        if not await is_authorized(ctx.author, role, perma=False):
            raise CommandError(t.role_not_authorized)

        check_role_assignable(role)

        if await db.exists(
                filter_by(PermaRole, member_id=member.id, role_id=role.id)):
            raise CommandError(t.cannot_remove_perma(await get_prefix()))

        await member.remove_roles(role)
        await ctx.message.add_reaction(name_to_emoji["white_check_mark"])
Exemplo n.º 11
0
    async def register_topics(self, ctx: Context, *, topics: str):
        """
        register one or more new topics
        """

        guild: Guild = ctx.guild
        names = split_topics(topics)
        if not names:
            raise UserInputError

        valid_chars = set(string.ascii_letters + string.digits +
                          " !#$%&'()+-./:<=>?[\\]^_{|}~")
        to_be_created: List[str] = []
        roles: List[Role] = []
        for topic in names:
            if len(topic) > 100:
                raise CommandError(t.topic_too_long(topic))
            if any(c not in valid_chars for c in topic):
                raise CommandError(t.topic_invalid_chars(topic))

            for role in guild.roles:
                if role.name.lower() == topic.lower():
                    break
            else:
                to_be_created.append(topic)
                continue

            if await db.exists(select(BTPRole).filter_by(role_id=role.id)):
                raise CommandError(t.topic_already_registered(topic))

            check_role_assignable(role)

            roles.append(role)

        for name in to_be_created:
            roles.append(await guild.create_role(name=name, mentionable=True))

        for role in roles:
            await BTPRole.create(role.id)

        embed = Embed(title=t.betheprofessional,
                      colour=Colors.BeTheProfessional)
        embed.description = t.topics_registered(cnt=len(roles))
        await send_to_changelog(
            ctx.guild,
            t.log_topics_registered(cnt=len(roles),
                                    topics=", ".join(f"`{r}`" for r in roles)))
        await reply(ctx, embed=embed)
Exemplo n.º 12
0
    async def aoc_role_set(self, ctx: Context, *, role: Role):
        """
        configure aoc role
        """

        check_role_assignable(role)

        old_role: Optional[Role] = ctx.guild.get_role(
            await AdventOfCodeSettings.role.get())

        await AdventOfCodeSettings.role.set(role.id)

        if old_role:
            for member in old_role.members:
                await member.remove_roles(old_role)
        await self.update_roles(await
                                AOCConfig.get_leaderboard(disable_hook=True))

        await reply(ctx, t.role_set)
        await send_to_changelog(ctx.guild, t.log_role_set(role.name, role.id))
Exemplo n.º 13
0
    async def roles_perma_add(self, ctx: Context, member: UserMemberConverter,
                              *, role: Role):
        member: Union[User, Member]

        if not await is_authorized(ctx.author, role, perma=True):
            raise CommandError(t.role_not_authorized)

        check_role_assignable(role)

        if await db.exists(
                filter_by(PermaRole, member_id=member.id, role_id=role.id)):
            raise CommandError(t.role_already_assigned)

        self.removed_perma_roles.discard((member.id, role.id))
        await PermaRole.add(member.id, role.id)
        if isinstance(member, Member):
            await member.add_roles(role)
        await send_to_changelog(
            ctx.guild, t.added_perma_role(role.mention, member.mention,
                                          member))
        await ctx.message.add_reaction(name_to_emoji["white_check_mark"])
Exemplo n.º 14
0
    async def unassign_topics(self, ctx: Context, *, topics: str):
        """
        remove one or more topics (use * to remove all topics)
        """

        member: Member = ctx.author
        if topics.strip() == "*":
            roles: List[Role] = await list_topics(ctx.guild)
        else:
            roles: List[Role] = await parse_topics(ctx.guild, topics,
                                                   ctx.author)
        roles = [r for r in roles if r in member.roles]

        for role in roles:
            check_role_assignable(role)

        await member.remove_roles(*roles, atomic=False)

        embed = Embed(title=t.betheprofessional,
                      colour=Colors.BeTheProfessional)
        embed.description = t.topics_removed(cnt=len(roles))
        await reply(ctx, embed=embed)
Exemplo n.º 15
0
    async def assign_topics(self, ctx: Context, *, topics: str):
        """
        add one or more topics (comma separated) you are interested in
        """

        member: Member = ctx.author
        roles: List[Role] = [
            r for r in await parse_topics(ctx.guild, topics, ctx.author)
            if r not in member.roles
        ]

        for role in roles:
            check_role_assignable(role)

        await member.add_roles(*roles, atomic=False)

        embed = Embed(title=t.betheprofessional,
                      colour=Colors.BeTheProfessional)
        embed.description = t.topics_added(cnt=len(roles))
        if not roles:
            embed.colour = Colors.error

        await reply(ctx, embed=embed)
Exemplo n.º 16
0
    async def on_member_join(self, member: Member):
        roles: list[Role] = []
        invalid: list[Role] = []

        role: Role
        for role in map(member.guild.get_role, await AutoRole.all()):
            if not role:
                continue

            try:
                check_role_assignable(role)
            except CommandError:
                invalid.append(role)
            else:
                roles.append(role)

        await member.add_roles(*roles)

        if invalid:
            raise PermissionError(
                member.guild,
                t.cannot_assign(cnt=len(invalid), member=member, roles=", ".join(role.mention for role in invalid)),
            )
Exemplo n.º 17
0
    for topic in names:
        for role in guild.roles:
            if role.name.lower() == topic.lower():
                break
        else:
            raise CommandError(t.topic_not_registered(topic))
        if (btp_role := await db.first(
                select(BTPRole).filter_by(role_id=role.id))) is None:
            raise CommandError(t.topic_not_registered(topic))

        roles.append(role)
        btp_roles.append(btp_role)

    for role, btp_role in zip(roles, btp_roles):
        if delete_roles:
            check_role_assignable(role)
            await role.delete()
        await db.delete(btp_role)

    embed = Embed(title=t.betheprofessional, colour=Colors.BeTheProfessional)
    embed.description = t.topics_unregistered(cnt=len(roles))
    await send_to_changelog(
        ctx.guild,
        t.log_topics_unregistered(cnt=len(roles),
                                  topics=", ".join(f"`{r}`" for r in roles)))
    await send_long_embed(ctx, embed)


class BeTheProfessionalCog(Cog, name="BeTheProfessional"):
    CONTRIBUTORS = [
        Contributor.Defelo, Contributor.wolflu, Contributor.MaxiHuHe04,
Exemplo n.º 18
0
    async def mute(self, ctx: Context, user: UserMemberConverter,
                   days: DurationConverter, *, reason: str):
        """
        mute a user
        set days to `inf` for a permanent mute
        """

        user: Union[Member, User]

        days: Optional[int]

        if len(reason) > 900:
            raise CommandError(t.reason_too_long)

        mute_role: Role = await get_mute_role(ctx.guild)

        if user == self.bot.user or await is_teamler(user):
            raise UserCommandError(user, t.cannot_mute)

        if isinstance(user, Member):
            check_role_assignable(mute_role)
            await user.add_roles(mute_role)
            await user.move_to(None)

        active_mutes: List[Mute] = await db.all(
            filter_by(Mute, active=True, member=user.id))
        for mute in active_mutes:
            if mute.days == -1:
                raise UserCommandError(user, t.already_muted)

            ts = mute.timestamp + timedelta(days=mute.days)
            if days is not None and utcnow() + timedelta(days=days) <= ts:
                raise UserCommandError(user, t.already_muted)

        for mute in active_mutes:
            await Mute.upgrade(mute.id, ctx.author.id)

        user_embed = Embed(title=t.mute, colour=Colors.ModTools)
        server_embed = Embed(title=t.mute,
                             description=t.muted_response,
                             colour=Colors.ModTools)
        server_embed.set_author(name=str(user),
                                icon_url=user.display_avatar.url)

        if days is not None:
            await Mute.create(user.id, str(user), ctx.author.id, days, reason,
                              bool(active_mutes))
            user_embed.description = t.muted(ctx.author.mention,
                                             ctx.guild.name,
                                             reason,
                                             cnt=days)
            await send_to_changelog_mod(ctx.guild,
                                        ctx.message,
                                        Colors.mute,
                                        t.log_muted,
                                        user,
                                        reason,
                                        duration=t.log_field.days(cnt=days))
        else:
            await Mute.create(user.id, str(user), ctx.author.id, -1, reason,
                              bool(active_mutes))
            user_embed.description = t.muted_inf(ctx.author.mention,
                                                 ctx.guild.name, reason)
            await send_to_changelog_mod(ctx.guild,
                                        ctx.message,
                                        Colors.mute,
                                        t.log_muted,
                                        user,
                                        reason,
                                        duration=t.log_field.days_infinity)

        try:
            await user.send(embed=user_embed)
        except (Forbidden, HTTPException):
            server_embed.description = t.no_dm + "\n\n" + server_embed.description
            server_embed.colour = Colors.error

        await reply(ctx, embed=server_embed)
Exemplo n.º 19
0
    async def verify(self, ctx: Context, *, password: str):
        correct_password: str = await VerificationSettings.password.get()
        if correct_password is None:
            raise CommandError(t.verification_disabled)
        if not await db.exists(select(VerificationRole)):
            raise CommandError(t.verification_disabled)

        if password != correct_password:
            raise CommandError(t.password_incorrect)

        guild: Guild = self.bot.guilds[0]
        member: Member = guild.get_member(ctx.author.id)

        delay: int = await VerificationSettings.delay.get()
        if delay != -1 and (utcnow() -
                            member.joined_at).total_seconds() < delay:
            raise CommandError(t.too_soon)

        add: List[Role] = []
        remove: List[Role] = []
        fail = False
        async for vrole in await db.stream(select(VerificationRole)
                                           ):  # type: VerificationRole
            role: Optional[Role] = guild.get_role(vrole.role_id)
            if role is None:
                continue

            if vrole.reverse:
                if role in member.roles:
                    remove.append(role)
                else:
                    fail = True
            elif not vrole.reverse and role not in member.roles:
                add.append(role)
        if not add and not remove:
            raise CommandError(t.already_verified)
        if fail:
            raise CommandError(t.verification_failed)

        invalid = []
        for role in add + remove:
            try:
                check_role_assignable(role)
            except CommandError:
                invalid.append(role)

        if invalid:
            await send_alert(
                member.guild,
                t.cannot_assign(cnt=len(invalid),
                                member=member,
                                roles=", ".join(role.mention
                                                for role in invalid)),
            )
            raise CommandError(t.verification_failed)

        await member.add_roles(*add)
        await member.remove_roles(*remove)
        embed = Embed(title=t.verification,
                      description=t.verified,
                      colour=Colors.Verification)
        await reply(ctx, embed=embed)