コード例 #1
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)
コード例 #2
0
        async def count(cls):
            if cls is Report:
                active = await db.count(filter_by(cls, reporter=user_id))
            else:
                active = await db.count(filter_by(cls, mod=user_id))

            passive = await db.count(filter_by(cls, member=user_id))

            if cls is Kick:
                if auto_kicks := await db.count(
                        filter_by(cls, member=user_id, mod=None)):
                    return t.active_passive(
                        active, passive -
                        auto_kicks) + "\n" + t.autokicks(cnt=auto_kicks)
コード例 #3
0
ファイル: cog.py プロジェクト: PyDrocsid/cogs
        async def update(member):
            await Join.update(member.id, str(member), member.joined_at)

            relevant_join: Optional[Join] = await db.first(
                filter_by(Join, member=member.id).order_by(Join.timestamp.asc())
            )

            if not relevant_join:
                return

            timestamp = relevant_join.timestamp + timedelta(seconds=10)
            if await db.exists(filter_by(Verification, member=member.id, accepted=True, timestamp=timestamp)):
                return

            await db.add(Verification(member=member.id, member_name=str(member), accepted=True, timestamp=timestamp))
コード例 #4
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)
コード例 #5
0
    async def unban(self, ctx: Context, user: UserMemberConverter, *,
                    reason: str):
        """
        unban a user
        """

        user: Union[Member, User]

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

        if not ctx.guild.me.guild_permissions.ban_members:
            raise CommandError(t.cannot_unban_permissions)

        was_banned = True
        try:
            await ctx.guild.unban(user, reason=reason)
        except HTTPException:
            was_banned = False

        async for ban in await db.stream(
                filter_by(Ban, active=True, member=user.id)):
            was_banned = True
            await Ban.deactivate(ban.id, ctx.author.id, reason)
        if not was_banned:
            raise UserCommandError(user, t.not_banned)

        server_embed = Embed(title=t.unban,
                             description=t.unbanned_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.unban,
                                    t.log_unbanned, user, reason)
コード例 #6
0
    async def on_member_join(self, member: Member):
        mute_role: Optional[Role] = member.guild.get_role(
            await RoleSettings.get("mute"))
        if mute_role is None:
            return

        if await db.exists(filter_by(Mute, active=True, member=member.id)):
            await member.add_roles(mute_role)
コード例 #7
0
ファイル: cog.py プロジェクト: PyDrocsid/cogs
    async def handle_get_userlog_entries(self, user_id: int, _) -> list[tuple[datetime, str]]:
        out: list[tuple[datetime, str]] = []

        deletion: MediaOnlyDeletion
        async for deletion in await db.stream(filter_by(MediaOnlyDeletion, member=user_id)):
            out.append((deletion.timestamp, t.ulog_deletion(f"<#{deletion.channel}>")))

        return out
コード例 #8
0
    async def on_member_role_remove(self, member: Member, role: Role):
        if (member.id, role.id) in self.removed_perma_roles:
            self.removed_perma_roles.remove((member.id, role.id))
            return

        if not await db.exists(
                filter_by(PermaRole, member_id=member.id, role_id=role.id)):
            return

        await reassign(member, role)
コード例 #9
0
    async def on_member_join(self, member: Member):
        guild: Guild = member.guild

        perma_role: PermaRole
        async for perma_role in await db.stream(
                filter_by(PermaRole, member_id=member.id)):
            if not (role := guild.get_role(perma_role.role_id)):
                await db.delete(perma_role)
                continue

            await reassign(member, role)
コード例 #10
0
    async def handle_get_ulog_entries(self, user_id: int, _):
        out = []

        async for log in await db.stream(
                filter_by(InviteLog, applicant=user_id)):  # type: InviteLog
            if log.approved:
                out.append((log.timestamp,
                            t.ulog_invite_approved(f"<@{log.mod}>",
                                                   log.guild_name)))
            else:
                out.append((log.timestamp,
                            t.ulog_invite_removed(f"<@{log.mod}>",
                                                  log.guild_name)))

        post: IllegalInvitePost
        async for post in await db.stream(
                filter_by(IllegalInvitePost, member=user_id)):
            out.append((post.timestamp,
                        t.ulog_illegal_post(f"<#{post.channel}>", post.name)))

        return out
コード例 #11
0
ファイル: cog.py プロジェクト: PyDrocsid/cogs
    async def on_member_role_add(self, member: Member, role: Role):
        if role.id != await RoleSettings.get("verified"):
            return

        asyncio.create_task(self.update_verification_reaction(member, add=True))

        last_verification: Optional[Verification] = await db.first(
            filter_by(Verification, member=member.id).order_by(Verification.timestamp.desc())
        )
        if last_verification and last_verification.accepted:
            return

        await Verification.create(member.id, str(member), True)
コード例 #12
0
    async def on_ready(self):
        guild: Guild = self.bot.guilds[0]
        mute_role: Optional[Role] = guild.get_role(await
                                                   RoleSettings.get("mute"))
        if mute_role is not None:
            async for mute in await db.stream(filter_by(Mute, active=True)):
                member: Optional[Member] = guild.get_member(mute.member)
                if member is not None:
                    await member.add_roles(mute_role)

        try:
            self.mod_loop.start()
        except RuntimeError:
            self.mod_loop.restart()
コード例 #13
0
    async def handle_get_ulog_entries(self, user_id: int, _):
        out = []

        log: BadWordPost
        async for log in await db.stream(filter_by(BadWordPost,
                                                   member=user_id)):
            if log.deleted_message:
                out.append((log.timestamp,
                            t.ulog_message_deleted(log.content, log.channel)))
            else:
                out.append(
                    (log.timestamp, t.ulog_message(log.content, log.channel)))

        return out
コード例 #14
0
    async def add(self, ctx: Context, regex: RegexConverter, delete: bool, *,
                  description: str):
        regex: str

        if await db.exists(filter_by(BadWord, regex=regex)):
            raise CommandError(t.already_blacklisted)

        if len(description) > 500:
            raise CommandError(t.description_length)

        await BadWord.create(regex, description, delete)
        await add_reactions(ctx.message, "white_check_mark")
        await send_to_changelog(
            ctx.guild, t.log_content_filter_added(regex, ctx.author.mention))
コード例 #15
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"])
コード例 #16
0
    async def regex(self, ctx: Context, pattern: ContentFilterConverter, *,
                    new_regex: RegexConverter):
        pattern: BadWord
        new_regex: str

        if await db.exists(filter_by(BadWord, regex=new_regex)):
            raise CommandError(t.already_blacklisted)

        old = pattern.regex
        pattern.regex = new_regex
        await sync_redis()

        await add_reactions(ctx.message, "white_check_mark")
        await send_to_changelog(ctx.guild,
                                t.log_regex_updated(old, pattern.regex))
コード例 #17
0
    async def on_member_role_remove(self, member: Member, role: Role):
        link: RoleNotification
        async for link in await db.stream(
                filter_by(RoleNotification, role_id=role.id)):
            channel: Optional[TextChannel] = self.bot.get_channel(
                link.channel_id)
            if channel is None:
                continue

            role_name = role.mention if link.ping_role else f"`@{role}`"
            user_name = member.mention if link.ping_user else f"`@{member}`"
            try:
                await channel.send(t.rn_role_removed(role_name, user_name))
            except Forbidden:
                await send_alert(member.guild, t.cannot_send(channel.mention))
コード例 #18
0
ファイル: cog.py プロジェクト: PyDrocsid/cogs
    async def joined(self, ctx: Context, member: Member = None):
        """
        Returns a rough estimate for the user's time on the server
        """

        member = member or ctx.author
        verification: Optional[Verification] = await db.first(
            filter_by(Verification, member=member.id).order_by(Verification.timestamp.desc())
        )
        ts: datetime = verification.timestamp if verification else member.joined_at

        embed = Embed(
            title=t.userinfo, description=f"{member.mention} {date_diff_to_str(utcnow(), ts)}", color=Colors.joined
        )
        embed.set_author(name=str(member), icon_url=member.display_avatar.url)
        await reply(ctx, embed=embed)
コード例 #19
0
    async def reactionrole_reinialize(self, ctx: Context, msg: Message,
                                      emoji: Optional[EmojiConverter]):
        if emoji:
            emoji: PartialEmoji

            if not await ReactionRole.get(msg.channel.id, msg.id, str(emoji)):
                raise CommandError(t.rr_link_not_found)

            for reaction in msg.reactions:
                if str(reaction) == str(emoji):
                    try:
                        await reaction.clear()
                    except Forbidden:
                        raise CommandError(t.could_not_remove_reactions)
                    break

            try:
                await msg.add_reaction(emoji)
            except Forbidden:
                raise CommandError(t.could_not_add_reactions)

            await add_reactions(ctx, "white_check_mark")
            return

        links: list[ReactionRole] = await db.all(
            filter_by(ReactionRole,
                      channel_id=msg.channel.id,
                      message_id=msg.id))
        if not links:
            raise CommandError(t.rr_link_not_found)

        try:
            await msg.clear_reactions()
        except Forbidden:
            raise CommandError(t.could_not_remove_reactions)

        for link in links:
            try:
                await msg.add_reaction(link.emoji)
            except Forbidden:
                raise CommandError(t.could_not_add_reactions)

        await add_reactions(ctx, "white_check_mark")
コード例 #20
0
    async def role_notifications_add(self, ctx: Context, role: Role,
                                     channel: TextChannel, ping_role: bool,
                                     ping_user: bool):
        """
        add a role notification link
        """

        check_message_send_permissions(channel)

        if await db.exists(
                filter_by(RoleNotification,
                          role_id=role.id,
                          channel_id=channel.id)):
            raise CommandError(t.link_already_exists)

        await RoleNotification.create(role.id, channel.id, ping_role,
                                      ping_user)
        await ctx.message.add_reaction(name_to_emoji["white_check_mark"])
        await send_to_changelog(ctx.guild,
                                t.log_rn_created(role, channel.mention))
コード例 #21
0
ファイル: cog.py プロジェクト: PyDrocsid/cogs
    async def on_member_join(self, member: Member):
        self.join_events[member.id].clear()

        join: Join = await Join.create(member.id, str(member), member.joined_at.replace(microsecond=0))

        async def trigger_join_event():
            await db.wait_for_close_event()
            self.join_id[member.id] = join.id
            self.join_events[member.id].set()

        asyncio.create_task(trigger_join_event())

        last_verification: Optional[Verification] = await db.first(
            filter_by(Verification, member=member.id).order_by(Verification.timestamp.desc())
        )
        if not last_verification or not last_verification.accepted:
            return

        role: Optional[Role] = member.guild.get_role(await RoleSettings.get("verified"))
        if role:
            await member.add_roles(role)
コード例 #22
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"])
コード例 #23
0
    async def roles_list(self, ctx: Context, *, role: Role):
        member_ids: set[int] = {member.id for member in role.members}
        perma: dict[int, str] = {}

        perma_role: PermaRole
        async for perma_role in await db.stream(
                filter_by(PermaRole, role_id=role.id)):
            try:
                user = await self.bot.fetch_user(perma_role.member_id)
            except NotFound:
                continue

            member_ids.add(user.id)
            perma[user.id] = str(user)

        members: list[Member] = []
        for member_id in [*member_ids]:
            if not (member := ctx.guild.get_member(member_id)):
                continue

            members.append(member)
            member_ids.remove(member_id)
コード例 #24
0
 async def exists(channel_id: int) -> bool:
     return await db.exists(filter_by(LogExclude, channel_id=channel_id))
コード例 #25
0
ファイル: cog.py プロジェクト: PyDrocsid/cogs
class RedditCog(Cog, name="Reddit"):
    CONTRIBUTORS = [
        Contributor.Scriptim, Contributor.Defelo, Contributor.wolflu,
        Contributor.Anorak
    ]

    async def on_ready(self):
        interval = await RedditSettings.interval.get()
        await self.start_loop(interval)

    @tasks.loop()
    @db_wrapper
    async def reddit_loop(self):
        await self.pull_hot_posts()

    async def pull_hot_posts(self):
        logger.info("pulling hot reddit posts")
        limit = await RedditSettings.limit.get()
        async for reddit_channel in await db.stream(select(RedditChannel)
                                                    ):  # type: RedditChannel
            text_channel: Optional[TextChannel] = self.bot.get_channel(
                reddit_channel.channel)
            if text_channel is None:
                await db.delete(reddit_channel)
                continue

            try:
                check_message_send_permissions(text_channel, check_embed=True)
            except CommandError:
                await send_alert(self.bot.guilds[0],
                                 t.cannot_send(text_channel.mention))
                continue

            posts = await fetch_reddit_posts(reddit_channel.subreddit, limit)
            if posts is None:
                await send_alert(self.bot.guilds[0],
                                 t.could_not_fetch(reddit_channel.subreddit))
                continue

            for post in posts:
                if await RedditPost.post(post["id"]):
                    await text_channel.send(embed=create_embed(post))

        await RedditPost.clean()

    async def start_loop(self, interval):
        self.reddit_loop.cancel()
        self.reddit_loop.change_interval(hours=interval)
        try:
            self.reddit_loop.start()
        except RuntimeError:
            self.reddit_loop.restart()

    @commands.group()
    @RedditPermission.read.check
    @guild_only()
    async def reddit(self, ctx: Context):
        """
        manage reddit integration
        """

        if ctx.subcommand_passed is not None:
            if ctx.invoked_subcommand is None:
                raise UserInputError
            return

        embed = Embed(title=t.reddit, colour=Colors.Reddit)

        interval = await RedditSettings.interval.get()
        embed.add_field(name=t.interval, value=t.x_hours(cnt=interval))

        limit = await RedditSettings.limit.get()
        embed.add_field(name=t.limit, value=str(limit))

        filter_nsfw = await RedditSettings.filter_nsfw.get()
        embed.add_field(name=t.nsfw_filter,
                        value=tg.enabled if filter_nsfw else tg.disabled,
                        inline=False)

        out = []
        async for reddit_channel in await db.stream(select(RedditChannel)
                                                    ):  # type: RedditChannel
            text_channel: Optional[TextChannel] = self.bot.get_channel(
                reddit_channel.channel)
            if text_channel is None:
                await db.delete(reddit_channel)
            else:
                sub = reddit_channel.subreddit
                out.append(
                    f":small_orange_diamond: [r/{sub}](https://reddit.com/r/{sub}) -> {text_channel.mention}"
                )
        embed.add_field(name=t.reddit_links,
                        value="\n".join(out) or t.no_reddit_links,
                        inline=False)

        await reply(ctx, embed=embed)

    @reddit.command(name="add", aliases=["a", "+"])
    @RedditPermission.write.check
    async def reddit_add(self, ctx: Context, subreddit: str,
                         channel: TextChannel):
        """
        create a link between a subreddit and a channel
        """

        if not (subreddit := await get_subreddit_name(subreddit)):
            raise CommandError(t.subreddit_not_found)

        check_message_send_permissions(channel, check_embed=True)

        if await db.exists(
                filter_by(RedditChannel,
                          subreddit=subreddit,
                          channel=channel.id)):
            raise CommandError(t.reddit_link_already_exists)

        await RedditChannel.create(subreddit, channel.id)
        embed = Embed(title=t.reddit,
                      colour=Colors.Reddit,
                      description=t.reddit_link_created)
        await reply(ctx, embed=embed)
        await send_to_changelog(
            ctx.guild, t.log_reddit_link_created(subreddit, channel.mention))
コード例 #26
0
ファイル: models.py プロジェクト: PyDrocsid/cogs
    channel: Union[Column, int] = Column(BigInteger,
                                         primary_key=True,
                                         unique=True)

    @staticmethod
    async def add(channel: int):
        await redis.setex(f"mediaonly:channel={channel}", CACHE_TTL, 1)
        await db.add(MediaOnlyChannel(channel=channel))

    @staticmethod
    async def exists(channel: int) -> bool:
        if result := await redis.get(key := f"mediaonly:channel={channel}"):
            return result == "1"

        result = await db.exists(filter_by(MediaOnlyChannel, channel=channel))
        await redis.setex(key, CACHE_TTL, int(result))
        return result

    @staticmethod
    async def stream() -> AsyncIterable[int]:
        row: MediaOnlyChannel
        async with redis.pipeline() as pipe:
            async for row in await db.stream(select(MediaOnlyChannel)):
                channel = row.channel
                await pipe.setex(f"mediaonly:channel={channel}", CACHE_TTL, 1)
                yield channel
            await pipe.execute()

    @staticmethod
    async def remove(channel: int):
コード例 #27
0
    async def handle_get_userlog_entries(
            self, user_id: int, author: Member) -> list[tuple[datetime, str]]:
        out: list[tuple[datetime, str]] = []

        if await is_teamler(author):
            report: Report
            async for report in await db.stream(
                    filter_by(Report, member=user_id)):
                out.append((report.timestamp,
                            t.ulog.reported(f"<@{report.reporter}>",
                                            report.reason)))

        warn: Warn
        async for warn in await db.stream(filter_by(Warn, member=user_id)):
            out.append(
                (warn.timestamp, t.ulog.warned(f"<@{warn.mod}>", warn.reason)))

        mute: Mute
        async for mute in await db.stream(filter_by(Mute, member=user_id)):
            text = t.ulog.muted.upgrade if mute.is_upgrade else t.ulog.muted.first

            if mute.days == -1:
                out.append(
                    (mute.timestamp, text.inf(f"<@{mute.mod}>", mute.reason)))
            else:
                out.append((mute.timestamp,
                            text.temp(f"<@{mute.mod}>",
                                      mute.reason,
                                      cnt=mute.days)))

            if not mute.active and not mute.upgraded:
                if mute.unmute_mod is None:
                    out.append(
                        (mute.deactivation_timestamp, t.ulog.unmuted_expired))
                else:
                    out.append((mute.deactivation_timestamp,
                                t.ulog.unmuted(f"<@{mute.unmute_mod}>",
                                               mute.unmute_reason)))

        kick: Kick
        async for kick in await db.stream(filter_by(Kick, member=user_id)):
            if kick.mod is not None:
                out.append((kick.timestamp,
                            t.ulog.kicked(f"<@{kick.mod}>", kick.reason)))
            else:
                out.append((kick.timestamp, t.ulog.autokicked))

        ban: Ban
        async for ban in await db.stream(filter_by(Ban, member=user_id)):
            text = t.ulog.banned.upgrade if ban.is_upgrade else t.ulog.banned.first

            if ban.days == -1:
                out.append((ban.timestamp, text.inf(f"<@{ban.mod}>",
                                                    ban.reason)))
            else:
                out.append((ban.timestamp,
                            text.temp(f"<@{ban.mod}>",
                                      ban.reason,
                                      cnt=ban.days)))

            if not ban.active and not ban.upgraded:
                if ban.unban_mod is None:
                    out.append(
                        (ban.deactivation_timestamp, t.ulog.unbanned_expired))
                else:
                    out.append((ban.deactivation_timestamp,
                                t.ulog.unbanned(f"<@{ban.unban_mod}>",
                                                ban.unban_reason)))

        return out
コード例 #28
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)
コード例 #29
0
ファイル: cog.py プロジェクト: PyDrocsid/cogs
 async def handle_can_respond_on_reaction(self, channel: TextChannel) -> bool:
     return not await db.exists(filter_by(MediaOnlyChannel, channel=channel.id))
コード例 #30
0
    async def ban(self, ctx: Context, user: UserMemberConverter,
                  ban_days: DurationConverter, delete_days: int, *,
                  reason: str):
        """
        ban a user
        set ban_days to `inf` for a permanent ban
        """

        ban_days: Optional[int]
        user: Union[Member, User]

        if not ctx.guild.me.guild_permissions.ban_members:
            raise CommandError(t.cannot_ban_permissions)

        if len(reason) > 900:
            raise CommandError(t.reason_too_long)
        if not 0 <= delete_days <= 7:
            raise CommandError(tg.invalid_duration)

        if user == self.bot.user or await is_teamler(user):
            raise UserCommandError(user, t.cannot_ban)
        if isinstance(user, Member) and (user.top_role >= ctx.guild.me.top_role
                                         or user.id == ctx.guild.owner_id):
            raise UserCommandError(user, t.cannot_ban)

        active_bans: List[Ban] = await db.all(
            filter_by(Ban, active=True, member=user.id))
        for ban in active_bans:
            if ban.days == -1:
                raise UserCommandError(user, t.already_banned)

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

        for ban in active_bans:
            await Ban.upgrade(ban.id, ctx.author.id)
        async for mute in await db.stream(
                filter_by(Mute, active=True, member=user.id)):
            await Mute.upgrade(mute.id, ctx.author.id)

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

        if ban_days is not None:
            await Ban.create(user.id, str(user), ctx.author.id, ban_days,
                             reason, bool(active_bans))
            user_embed.description = t.banned(ctx.author.mention,
                                              ctx.guild.name,
                                              reason,
                                              cnt=ban_days)
            await send_to_changelog_mod(
                ctx.guild,
                ctx.message,
                Colors.ban,
                t.log_banned,
                user,
                reason,
                duration=t.log_field.days(cnt=ban_days))
        else:
            await Ban.create(user.id, str(user), ctx.author.id, -1, reason,
                             bool(active_bans))
            user_embed.description = t.banned_inf(ctx.author.mention,
                                                  ctx.guild.name, reason)
            await send_to_changelog_mod(ctx.guild,
                                        ctx.message,
                                        Colors.ban,
                                        t.log_banned,
                                        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 ctx.guild.ban(user,
                            delete_message_days=delete_days,
                            reason=reason)
        await revoke_verification(user)

        await reply(ctx, embed=server_embed)