Exemplo n.º 1
0
    async def warn(self, ctx: Context, member: Member, *, reason: str):
        """Warn someone

        Warns do not give any punishments apart fron an entry in the warn list.
        """

        guild, _ = await Guild.get_or_create(id=ctx.guild.id)
        user, _ = await User.get_or_create(id=member.id)
        warn = await Warn.create(moderator=ctx.author.id,
                                 guild=guild,
                                 user=user,
                                 reason=reason)

        embed = Embed(ctx, title=f"Warn [{warn.id}]", color=member.color)
        embed.description = t(ctx,
                              "message",
                              member=member.mention,
                              reason=reason)

        await ctx.send(embed=embed)

        try:
            await member.send(
                t(ctx, "dm_message", guild=ctx.guild, reason=reason))
        except (Forbidden, HTTPException, AttributeError):
            pass
Exemplo n.º 2
0
    async def warns(self, ctx: Context, *, member: Member = None):
        """See someone's warns

        If no member specified, this shows Your warns.
        """

        if not member:
            member = ctx.author

        embed = Embed(
            ctx,
            title=t(ctx, "title", member=member),
            description="",
            color=member.color,
        )

        await ctx.trigger_typing()
        warns = Warn.filter(user__id=member.id, guild__id=ctx.guild.id)

        if not await warns.count():
            return await ctx.send(t(ctx, "no_mutes", member=member))

        async for i in warns:
            moderator = ctx.bot.get_user(i.moderator)
            # TODO: Format time and use timezones (settings)
            embed.description += (
                f"`{i.id}` {str(i.when.time())[:-10]} "
                f"{i.when.date()} **{moderator}**: *{i.reason}*\n")

        await ctx.send(embed=embed)
Exemplo n.º 3
0
    async def level_up_messages(self, ctx: Context, action: str):
        """Toggle level up messages on this server

        Level up messages are not sent until you reach level 6.
        """

        guild, _ = await Guild.get_or_create(id=ctx.guild.id)

        if action == "disable":
            if not guild.level_up_messages:
                return await ctx.send(
                    t(ctx, "already_disabled", guild=ctx.guild))

            guild.level_up_messages = False
            await ctx.send(t(ctx, "disabled", guild=ctx.guild))

        elif action == "enable":
            if guild.level_up_messages:
                return await ctx.send(
                    t(ctx, "already_enabled", guild=ctx.guild))

            guild.level_up_messages = True
            await ctx.send(t(ctx, "enabled", guild=ctx.guild))

        await guild.save()
Exemplo n.º 4
0
    async def mutes(self, ctx: Context, *, member: Member = None):
        """See someone's mutes

        If no member specified, this shows Your mutes.
        """

        if not member:
            member = ctx.author

        embed = Embed(
            ctx,
            title=t(ctx, "title", member=member),
            description="",
            color=member.color,
        )
        await ctx.trigger_typing()

        mutes = Mute.filter(user__id=member.id, guild__id=ctx.guild.id)
        if not await mutes.count():
            return await ctx.send(t(ctx, "no_mutes", member=member))

        async for i in mutes:
            moderator = await self.bot.fetch_user(i.moderator)
            embed.description += (
                f"`{i.id}` {str(i.start.time())[:-10]} "
                f"{i.start.date()} ({str(i.end - i.start)[:-7]}) "
                f"**{moderator}**: *{i.reason or t(ctx, 'no_reason')}* ")
            # TODO: Format time and use timezones
            if i.active:
                embed.description += "🔴"
            embed.description += "\n"

        await ctx.send(embed=embed)
Exemplo n.º 5
0
    async def mute(self,
                   ctx: Context,
                   member: Member,
                   time: Timedelta,
                   *,
                   reason: str = None):
        """Mute someone

        Muting someone gives them the mute role specified by the muterole command and removes the role after the specified time has passed.
        Note: Mutes are checked every 10 seconds, so times are not perfect.
        """

        mute = await Mute.filter(user__id=member.id,
                                 guild__id=ctx.guild.id,
                                 active=True).first()
        if mute:
            mute.end += time
            await mute.save()
            return await ctx.send(
                t(ctx, "message_extended", member=member, time=time))
            # NOTE: Extensions don't add a mute entry, they just make the
            # active mute longer.
            # return await ctx.send(f"{member.name} is already muted.")

        user, _ = await User.get_or_create(id=member.id)
        guild, _ = await Guild.get_or_create(id=ctx.guild.id)
        if not guild.mute_role:
            return await ctx.send(t(ctx, "no_mute_role", guild=ctx.guild))
        mute = await Mute.create(
            moderator=ctx.author.id,
            user=user,
            guild=guild,
            reason=reason,
            end=datetime.utcnow() + time,
        )

        mute_role = ctx.guild.get_role(guild.mute_role)
        # TODO: Check if member has lower permissions required to mute them
        await member.add_roles(
            mute_role,
            reason=f"Muted by {ctx.author} for {time}, reason: {reason}")

        embed = Embed(ctx, title=f"Mute [{mute.id}]", color=member.color)
        embed.set_thumbnail(url=member.avatar_url)
        embed.description = t(ctx,
                              "message",
                              member=member.mention,
                              time=time,
                              reason=reason)

        await ctx.send(embed=embed)

        try:
            await member.send(
                t(ctx, "dm_message", guild=ctx.guild, time=time,
                  reason=reason))
        except (Forbidden, HTTPException, AttributeError):
            pass
Exemplo n.º 6
0
    async def language(self, ctx: Context):
        """Bot language"""

        guild = await Guild.get(id=ctx.guild.id)

        if not guild.locale:
            return await ctx.send(t(ctx, "not_set", guild=ctx.guild.name))

        return await ctx.send(
            t(ctx, "message", guild=ctx.guild.name, locale=guild.locale))
Exemplo n.º 7
0
    async def bug(self, ctx: Context):
        """Where to report bugs and feature requests"""

        embed = Embed(
            ctx,
            title=t(ctx, "title"),
            description=t(ctx, "message"),
        )

        await ctx.send(embed=embed)
Exemplo n.º 8
0
    async def role(self, ctx: Context, *, role: Role):
        """Shows info about a role"""

        embed = Embed(ctx, title=t(ctx, "title", role=role.name), color=role.color)

        embed.add_field(name=t(ctx, "id"), value=role.id)

        if len(role.members) > 1:
            embed.add_field(name=t(ctx, "members"), value=str(len(role.members)))

        embed.add_field(
            name=t(ctx, "mentionable"),
            value=t(ctx, "mentionable_yes")
            if role.mentionable
            else t(ctx, "mentionable_no"),
        )

        if role.color != Color.default():
            embed.add_field(
                name=t(ctx, "color"),
                value=t(
                    ctx,
                    "color_value",
                    hex=str(role.color),
                    rgb=str(role.color.to_rgb()),
                ),
            )

        embed.add_field(name=t(ctx, "created_at"), value=role.created_at)

        await ctx.send(embed=embed)
Exemplo n.º 9
0
    async def invite(self, ctx: Context):
        """Nagatoro's bot invite link"""

        embed = Embed(
            ctx,
            title=t(ctx, "title"),
            url=t(ctx, "invite_url"),
            description=t(ctx, "message"),
        )

        await ctx.send(embed=embed)
Exemplo n.º 10
0
    async def manga(self, ctx: Context, *, title: str):
        """Manga info from AniList"""

        query = """
        query ($title: String) {
            Media (search: $title, type: MANGA) {
                title {romaji}
                coverImage {extraLarge color}
                description (asHtml: false)
                siteUrl
                rankings {rank allTime type context}
                status
                chapters
                volumes
                format
                averageScore
                genres
            }
        }
        """
        manga = (await anilist(query, {"title": title}))["data"]["Media"]

        embed = Embed(
            ctx,
            title=manga["title"]["romaji"],
            description="",
            url=manga["siteUrl"],
            footer="Via AniList",
        )

        embed.set_thumbnail(url=manga["coverImage"]["extraLarge"])

        for i in manga["rankings"]:
            if not i["allTime"]:
                continue

            if i["type"] == "RATED":
                embed.description += "⭐"
            elif i["type"] == "POPULAR":
                embed.description += "❤️"

            embed.description += f" #{i['rank']} {i['context'].title()}\n"
        embed.description += "\n"

        if manga["description"]:
            description = clean_description(manga["description"])
            embed.description += (
                t(ctx, "synopsis_ellipsis", synopsis=description[:250])
                if len(description) >= 250
                else t(ctx, "synopsis", synopsis=description)
            )

        if color_hex := manga["coverImage"]["color"]:
            embed.color = Color(int(color_hex.replace("#", ""), 16))
Exemplo n.º 11
0
    async def language_set(self, ctx: Context, language: str):
        """Set Nagatoro's language on this server"""

        if language not in available_locales():
            return await ctx.send(t(ctx, "not_available", language=language))

        guild = await Guild.get(id=ctx.guild.id)
        guild.locale = language
        await guild.save()
        await self.bot.generate_locale_cache()

        await ctx.send(t(ctx, "message", language=language))
Exemplo n.º 12
0
    async def prefix_delete(self, ctx: Context):
        """Delete the prefix from this server"""

        guild = await Guild.get(id=ctx.guild.id)
        if not guild.prefix:
            return await ctx.send(t(ctx, "not_set", guild=ctx.guild.name))

        guild.prefix = None
        await guild.save()
        await self.bot.generate_prefix_cache()

        await ctx.send(t(ctx, "message", name=ctx.guild.name))
Exemplo n.º 13
0
    async def anime(self, ctx: Context, *, title: str):
        """Anime info from AniList"""

        query = """
        query ($title: String) {
            Media (search: $title, type: ANIME) {
                title {romaji}
                coverImage {extraLarge color}
                description (asHtml: false)
                siteUrl
                rankings {rank allTime type context}
                status
                episodes
                duration
                season
                seasonYear
                format
                averageScore
                genres
                studios (isMain: true) {nodes {name}}
            }
        }
        """
        anime = (await anilist(query, {"title": title}))["data"]["Media"]

        embed = Embed(
            ctx,
            title=anime["title"]["romaji"],
            description="",
            url=anime["siteUrl"],
            footer="Via AniList",
        )

        embed.set_thumbnail(url=anime["coverImage"]["extraLarge"])

        for i in anime["rankings"]:
            if not i["allTime"]:
                continue

            if i["type"] == "RATED":
                embed.description += "⭐"
            elif i["type"] == "POPULAR":
                embed.description += "❤️"

            embed.description += f" #{i['rank']} {i['context'].title()}\n"
        embed.description += "\n"

        if description := clean_description(anime["description"]):
            embed.description += (
                t(ctx, "synopsis_ellipsis", synopsis=description[:250])
                if len(description) >= 250
                else t(ctx, "synopsis", synopsis=description)
            )
Exemplo n.º 14
0
    async def ping(self, ctx: Context):
        """Bot connection latency

        This isn't very accurate, and mainly used as a "is this bot alive?" command.
        """

        embed = Embed(
            ctx,
            title=t(ctx, "title"),
            description=t(ctx, "message", ping=round(self.bot.latency * 1000)),
        )

        await ctx.send(embed=embed)
Exemplo n.º 15
0
    async def unban(self, ctx: Context, user: UserC):
        """Unban someone

        Note: Only works with IDs.
        To get a user's ID, enable Developer Mode under Appearance Settings, right click on the user's name and select "Copy ID".
        """

        if user.id not in [i.user.id for i in await ctx.guild.bans()]:
            return await ctx.send(t(ctx, "not_banned", user=user))

        await ctx.guild.unban(user, reason=f"Moderator: {ctx.author}")

        await ctx.send(t(ctx, "message", user=user))
Exemplo n.º 16
0
    async def ranking_level(self, ctx: Context):
        """User ranking, by level"""

        embed = Embed(ctx, title=t(ctx, "title"), description="", color=Color.blue())

        await ctx.trigger_typing()
        async for pos, i in aenumerate(User.all().order_by("-exp").limit(10), start=1):
            user = await self.bot.fetch_user(i.id)
            embed.description += t(
                ctx, "ranking_entry", pos=pos, user=user, lvl=i.level, exp=i.exp
            )

        await ctx.send(embed=embed)
Exemplo n.º 17
0
    async def studio(self, ctx: Context, *, name: str):
        """Studio info from AniList"""

        query = """
        query ($name: String) {
            Studio (search: $name, sort: SEARCH_MATCH) {
                name
                siteUrl
                isAnimationStudio
                media (sort: POPULARITY_DESC, perPage: 10) {
                    nodes {
                        title {romaji}
                        coverImage {extraLarge}
                        siteUrl
                        popularity
                        favourites
                    }
                }
            }
        }
        """
        studio = (await anilist(query, {"name": name}))["data"]["Studio"]

        embed = Embed(
            ctx, title=studio["name"], url=studio["siteUrl"], footer="Via AniList"
        )

        embed.set_thumbnail(url=studio["media"]["nodes"][0]["coverImage"]["extraLarge"])

        if studio["isAnimationStudio"]:
            embed.description = t(ctx, "animation_studio")

        # TODO: Observe, if this breaks when isAnimationStudio=False.
        most_popular = [t(ctx, "most_popular_header")]
        for i in studio["media"]["nodes"]:
            most_popular.append(
                t(
                    ctx,
                    "most_popular_item",
                    popularity=i["popularity"],
                    favorites=i["favourites"],
                    title=i["title"]["romaji"],
                    url=i["siteUrl"],
                )
            )

        embed.add_field(
            name=t(ctx, "most_popular_title"), value="\n".join(most_popular)
        )

        await ctx.send(embed=embed)
Exemplo n.º 18
0
    async def send_group_help(self, group):
        ctx = self.context
        embed = Embed(
            ctx,
            title=f"`{self.get_command_signature(group)}`",
            description=t(ctx, "description", group),
            color=Color.blue(),
        )

        commands = self.get_formatted_commands(await self.filter_commands(
            group.commands))
        embed.add_field(name=t(ctx, "commands"), value="\n".join(commands))

        await ctx.send(embed=embed)
Exemplo n.º 19
0
    async def send_cog_help(self, cog):
        ctx = self.context
        embed = Embed(
            ctx,
            title=t(ctx, "cog_commands", cog=cog.qualified_name),
            description=tc(ctx, cog),
            color=Color.blue(),
        )

        commands = self.get_formatted_commands(await self.filter_commands(
            cog.get_commands()))
        embed.add_field(name=t(ctx, "commands"), value="\n".join(commands))

        await ctx.send(embed=embed)
Exemplo n.º 20
0
    async def user(self, ctx: Context, *, user: Union[Member, User] = None):
        """Shows info about an user or a member"""

        if not user:
            user = ctx.author

        title = str(user) if not user.bot else t(ctx, "title_bot", user=user.name)
        embed = Embed(ctx, title=title, color=user.color)
        embed.set_thumbnail(url=user.avatar_url)
        embed.add_fields(
            (t(ctx, "id"), user.id),
            (t(ctx, "created_at"), user.created_at),
        )

        await ctx.send(embed=embed)
Exemplo n.º 21
0
    async def uptime(self, ctx: Context):
        """Bot uptime"""

        timestamp_difference = round(time() - self.bot.start_timestamp)
        uptime = timedelta(seconds=timestamp_difference)
        embed = Embed(ctx, title=t(ctx, "title"), description=str(uptime))

        await ctx.send(embed=embed)
Exemplo n.º 22
0
    async def warn_delete(self, ctx: Context, id: int):
        """Delete a warn from the database

        Use the warn id given when muting or viewing someone's warns (the number in square brackets, e.g. [32]).
        """

        if not (warn := await Warn.get_or_none(id=id)):
            return await ctx.send(t(ctx, "doesnt_exist", id=id))
Exemplo n.º 23
0
    async def mute_delete(self, ctx: Context, id: int):
        """Delete a mute and unmute someone

        Use the mute id given when muting or viewing someone's mutes (the number in square brackets, e.g. [64]).
        """

        if not (mute := await Mute.get_or_none(id=id)):
            return await ctx.send(t(ctx, "doesnt_exist", id=id))
Exemplo n.º 24
0
    async def balance(self, ctx: Context, *, member: Member = None):
        """Coin balance"""

        if not member:
            member = ctx.author

        user, _ = await User.get_or_create(id=member.id)
        await ctx.send(t(ctx, "messsage", member=member.name, bal=user.balance))
Exemplo n.º 25
0
    async def level(self, ctx: Context, *, member: Member = None):
        """User's level"""

        if not member:
            member = ctx.author

        user, _ = await User.get_or_create(id=member.id)
        await ctx.send(t(ctx, "message", member=member.name, lvl=user.level))
Exemplo n.º 26
0
    async def mute_role_set(self, ctx: Context, role: Role):
        """Set this server's mute role"""

        guild, _ = await Guild.get_or_create(id=ctx.guild.id)
        guild.mute_role = role.id
        await guild.save()

        await ctx.send(t(ctx, "message", role=role))
Exemplo n.º 27
0
    async def mute_role(self, ctx: Context):
        """Check the mute role

        This is the role given to muted users, it stays with them until the mute ends or they are unmuted manually.
        """

        guild, _ = await Guild.get_or_create(id=ctx.guild.id)
        mute_role = ctx.guild.get_role(guild.mute_role)

        if not guild.mute_role:
            return await ctx.send(t(ctx, "not_set"))
        if not mute_role:
            return await ctx.send(t(ctx, "doesnt_exist"))

        return await ctx.send(
            t(ctx, "message", guild=ctx.guild, name=mute_role,
              id=mute_role.id))
Exemplo n.º 28
0
    async def profile(self, ctx: Context, *, member: Member = None):
        """User's profile"""

        if not member:
            member = ctx.author

        user, _ = await User.get_or_create(id=member.id)
        # Calculate current level progress:
        # (exp - curr lvl req) * 100 / (curr lvl req - next lvl req)
        current_level_exp = (user.level * 4) ** 2
        next_level_exp = ((user.level + 1) * 4) ** 2
        progress = round(
            (user.exp - current_level_exp) * 100 / (next_level_exp - current_level_exp)
        )
        # Find position of profile in global user ranking
        rank = (await User.all().order_by("-exp")).index(user)

        embed = Embed(
            ctx, title=t(ctx, "title", member=member.name), color=member.color
        )
        embed.set_thumbnail(url=member.avatar_url)

        embed.add_fields(
            (t(ctx, "rank"), str(rank + 1)),
            (t(ctx, "level"), f"{user.level}"),
            (t(ctx, "experience"), f"{user.exp}/{next_level_exp} ({progress}%)"),
            (t(ctx, "balance"), t(ctx, "balance_value", bal=user.balance)),
        )

        if mutes := await Mute.filter(
            guild__id=ctx.guild.id, user__id=member.id
        ).count():
            embed.add_field(name=t(ctx, "mutes"), value=str(mutes))
Exemplo n.º 29
0
    async def prefix_set(self, ctx: Context, prefix: str):
        """Set a custom prefix for this server"""

        guild = await Guild.get(id=ctx.guild.id)
        guild.prefix = prefix
        await guild.save()
        await self.bot.generate_prefix_cache()

        await ctx.send(t(ctx, "message", prefix=prefix))
Exemplo n.º 30
0
    async def avatar(self, ctx: Context, *, user: User = None):
        """Shows an user's avatar"""

        if not user:
            user = ctx.author

        embed = Embed(ctx, title=t(ctx, "title", user=user.name))
        embed.set_image(url=user.avatar_url_as(size=2048))
        await ctx.send(embed=embed)