Example #1
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=f"{member.name}'s profile",
                      color=member.color)
        embed.set_thumbnail(url=member.avatar_url)

        embed.add_fields(
            ("Rank", str(rank + 1)),
            ("Level", f"{user.level}"),
            ("Experience", f"{user.exp}/{next_level_exp} ({progress}%)"),
            ("Balance", f"{user.balance} coins"),
        )

        if mutes := await Mute.filter(guild__id=ctx.guild.id,
                                      user__id=member.id).count():
            embed.add_field(name="Mutes", value=str(mutes))
Example #2
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)
Example #3
0
    async def mutes_active(self, ctx: Context):
        """See active mutes"""

        embed = Embed(ctx, title="Active mutes")
        await ctx.trigger_typing()

        mutes = Mute.filter(guild__id=ctx.guild.id, active=True)
        if not await mutes.count():
            return await ctx.send(
                f"There are no active mutes in **{ctx.guild.name}**.")

        # TODO: Split active mutes into different embeds when more than 10
        #       and add scrolling (◀️ ▶️)
        async for i in mutes.prefetch_related("user"):
            moderator = ctx.guild.get_member(i.moderator)
            user = ctx.guild.get_member(i.user.id)

            description = (
                f"**Given at**: {str(i.start.time())[:-10]} {str(i.start.date())[5:]}\n"
                f"**Duration**: {str(i.end - i.start)[:-7]}\n"
                f"**Moderator**: {moderator.mention}")
            if i.reason:
                description += f"\n**Reason**: *{i.reason}*"

            embed.add_field(name=f"{user} [{i.id}]",
                            value=description,
                            inline=False)

        await ctx.send(embed=embed)
Example #4
0
    async def character(self, ctx: Context, *, name: str):
        """Character info from AniList"""

        query = """
        query ($name: String) {
            Character (search: $name) {
                name {full}
                image {large}
                description (asHtml: false)
                siteUrl
                favourites
                media (perPage: 10) {
                    edges {
                        node {
                            title {romaji}
                            siteUrl
                        }
                        characterRole
                    }
                }
            }
        }
        """

        character = (await anilist(query, {"name": name}))["data"]["Character"]

        embed = Embed(ctx,
                      title=character["name"]["full"],
                      description="",
                      url=character["siteUrl"],
                      footer="Via AniList",
                      color=Color.blue())

        embed.set_thumbnail(url=character["image"]["large"])

        if character["favourites"]:
            embed.description += f"❤️ {character['favourites']} favorites \n\n"

        if character["description"]:
            description = clean_description(character["description"])
            embed.description += f"Description: ||{description[:250]}...||" \
                if len(description) >= 250 \
                else f"Description: ||{description}||"

        appears_in = ["Main 🌕 Supporting 🌗 Background 🌑"]
        for i in character["media"]["edges"]:
            role = i["characterRole"] \
                .replace("MAIN", "🌕") \
                .replace("SUPPORTING", "🌗") \
                .replace("BACKGROUND", "🌑")

            appears_in.append(f"{role} [{i['node']['title']['romaji']}]"
                              f"({i['node']['siteUrl']})")

        embed.add_field(name="Appears in", value="\n".join(appears_in))

        await ctx.send(embed=embed)
Example #5
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)
Example #6
0
    async def send_group_help(self, group):
        ctx = self.context
        embed = Embed(
            ctx,
            title=f"`{self.get_command_signature(group)}`",
            description=group.help,
            color=Color.blue(),
        )

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

        await ctx.send(embed=embed)
Example #7
0
    async def send_cog_help(self, cog):
        ctx = self.context
        embed = Embed(
            ctx,
            title=f"{cog.qualified_name} Commands",
            description=cog.description,
            color=Color.blue(),
        )

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

        await ctx.send(embed=embed)
Example #8
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 = "Animation Studio"

        # TODO: Observe, if this breaks when isAnimationStudio=False.
        most_popular = ["Popularity ⭐ Favorites ❤"]
        for i in studio["media"]["nodes"]:
            most_popular.append(f"{i['popularity']} ⭐ {i['favourites']} ❤️ "
                                f"[{i['title']['romaji']}]({i['siteUrl']}) ")

        embed.add_field(name="Most popular productions",
                        value="\n".join(most_popular))

        await ctx.send(embed=embed)
Example #9
0
    async def role(self, ctx: Context, *, role: Role):
        """Shows info about a role"""

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

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

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

        embed.add_field(name="Mentionable",
                        value="Yes" if role.mentionable else "No")

        if role.color != Color.default():
            embed.add_field(name="Color",
                            value=f"{role.color}, rgb{role.color.to_rgb()}")

        embed.add_field(name="Created at", value=role.created_at)

        await ctx.send(embed=embed)
Example #10
0
    async def mutes_active(self, ctx: Context):
        """See active mutes"""

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

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

        # TODO: Split active mutes into different embeds when more than 10
        #       and add scrolling (◀️ ▶️)
        async for i in mutes.prefetch_related("user"):
            moderator = ctx.guild.get_member(i.moderator)
            user = ctx.guild.get_member(i.user.id)

            if i.reason:
                description = t(
                    ctx,
                    "entry_with_reason",
                    given_at=
                    f"{str(i.start.time())[:-10]} {str(i.start.date())[5:]}",
                    duration=i.end - i.start,
                    moderator=moderator.mention,
                    reason=i.reason,
                )
            else:
                description = t(
                    ctx,
                    "entry",
                    given_at=
                    f"{str(i.start.time())[:-10]} {str(i.start.date())[5:]}",
                    duration=i.end - i.start,
                    moderator=moderator.mention,
                )

            embed.add_field(name=f"{user} [{i.id}]",
                            value=description,
                            inline=False)

        await ctx.send(embed=embed)
Example #11
0
    async def send_bot_help(self, mapping):
        ctx = self.context
        embed = Embed(
            ctx,
            title="Commands",
            description=self.get_opening_note(),
            color=Color.blue(),
        )

        for cog, commands in mapping.items():
            if not cog:
                # Don't show commands without a cog (e.g. the help command)
                continue

            category_name = cog.qualified_name
            filtered_commands = await self.filter_commands(commands)

            embed.add_field(
                name=category_name,
                value=", ".join(i.name for i in filtered_commands),
                inline=False,
            )

        await ctx.send(embed=embed)
Example #12
0
    async def anilist(self, ctx: Context, *, username: str):
        """AniList profile

        Shows anime/manga stats and favorites.
        """

        query = """
        query ($username: String) {
            User (name: $username) {
                name
                avatar {large}
                siteUrl
                favourites {
                    anime {
                        nodes {title {romaji} siteUrl}
                    }
                    manga {
                        nodes {title {romaji} siteUrl}
                    }
                    characters {
                        nodes {name {full} siteUrl}
                    }
                    staff {
                        nodes {name {full} siteUrl}
                    }
                    studios {
                        nodes {name siteUrl}
                    }
                }
            }
        }
        """
        list_query = """
        query ($username: String, $type: MediaType) {
            MediaListCollection (userName: $username, type: $type) {
                lists {status name entries {id}}
            }
        }
        """

        await ctx.trigger_typing()
        user = (await anilist(query, {"username": username}))["data"]["User"]
        anime_lists, manga_lists = [
            (await anilist(list_query, {"username": username, "type": i}))["data"][
                "MediaListCollection"
            ]["lists"]
            for i in ["ANIME", "MANGA"]
        ]

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

        embed.set_thumbnail(url=user["avatar"]["large"])

        if anime_lists:
            anime_list_body = ""
            for i in anime_lists:
                if i["status"]:
                    status = (
                        i["status"]
                        .replace("COMPLETED", "✅")
                        .replace("PLANNING", "🗓️")
                        .replace("DROPPED", "🗑️")
                        .replace("CURRENT", "📺")
                        .replace("PAUSED", "⏸️")
                        .replace("REPEATING", "🔁")
                    )
                else:
                    status = "⚙️"

                anime_list_body += f"{status} **{len(i['entries'])}** " f"{i['name']}\n"

            embed.add_field(name=t(ctx, "anime"), value=anime_list_body)

        if manga_lists:
            manga_list_body = ""
            for i in manga_lists:
                if i["status"]:
                    status = (
                        i["status"]
                        .replace("COMPLETED", "✅")
                        .replace("PLANNING", "🗓️")
                        .replace("DROPPED", "🗑️️")
                        .replace("CURRENT", "📖")
                        .replace("PAUSED", "⏸️")
                        .replace("REPEATING", "🔁")
                    )
                else:
                    status = "⚙️"

                manga_list_body += f"{status} **{len(i['entries'])}** " f"{i['name']}\n"

            embed.add_field(name=t(ctx, "manga"), value=manga_list_body)

        if any(user["favourites"][i]["nodes"] for i in user["favourites"]):
            favorites_body = ""
            for i in user["favourites"]:
                if not user["favourites"][i]["nodes"]:
                    continue

                # Section header
                favorites_body += f"__{i.title()}__"

                # Show total amount of favs if they exceed a limit (3)
                if (favorites_count := len(user["favourites"][i]["nodes"])) > 3:
                    favorites_body += f" ({favorites_count})"
                favorites_body += "\n"

                for item in user["favourites"][i]["nodes"][:3]:
                    # There are three types of names, so unify them.
                    if i in ["anime", "manga"]:
                        name = item["title"]["romaji"]
                    elif i in ["characters", "staff"]:
                        name = item["name"]["full"]
                    else:
                        name = item["name"]

                    favorites_body += f"[{name}]({item['siteUrl']})\n"

            embed.add_field(
                name=t(ctx, "favorites"), value=favorites_body, inline=False
            )
Example #13
0
    async def character(self, ctx: Context, *, name: str):
        """Character info from AniList"""

        query = """
        query ($name: String) {
            Character (search: $name) {
                name {full}
                image {large}
                description (asHtml: false)
                siteUrl
                favourites
                media (perPage: 10) {
                    edges {
                        node {
                            title {romaji}
                            siteUrl
                        }
                        characterRole
                    }
                }
            }
        }
        """

        character = (await anilist(query, {"name": name}))["data"]["Character"]

        embed = Embed(
            ctx,
            title=character["name"]["full"],
            description="",
            url=character["siteUrl"],
            footer="Via AniList",
            color=Color.blue(),
        )

        embed.set_thumbnail(url=character["image"]["large"])

        if character["favourites"]:
            embed.description += (
                t(ctx, "favorites", favorites=character["favourites"]) + "\n\n"
            )

        if character["description"]:
            description = clean_description(character["description"])
            embed.description += (
                t(ctx, "character_description_ellipsis", description=description[:250])
                if len(description) >= 250
                else t(ctx, "character_description", description=description)
            )

        appears_in = [t(ctx, "appears_in_header")]
        for i in character["media"]["edges"]:
            role = (
                i["characterRole"]
                .replace("MAIN", "🌕")
                .replace("SUPPORTING", "🌗")
                .replace("BACKGROUND", "🌑")
            )

            appears_in.append(
                t(
                    ctx,
                    "appears_in_item",
                    role=role,
                    title=i["node"]["title"]["romaji"],
                    url=i["node"]["siteUrl"],
                )
            )

        embed.add_field(name=t(ctx, "appears_in_title"), value="\n".join(appears_in))

        await ctx.send(embed=embed)