Untitled

mail@pastecode.io avatar
unknown
plain_text
7 months ago
6.0 kB
4
Indexable
Never
from typing import Any, Union, Optional
import discord
import sentry_sdk
from io import BytesIO
from database import Database, User
from enkacard import encbanner
from utility import EmbedTemplate, get_app_command_mention, config
from utility.custom_log import LOG


async def fetch_profile(uid: int):
    async with encbanner.ENC(uid=str(uid)) as encard:
        profile_data = await encard.profile(teamplate=1, card=True)
        return profile_data


async def fetch_characters(uid: int):
    async with encbanner.ENC(uid=str(uid)) as encard:
        characters_data = await encard.creat(template=4)
        return characters_data


async def create_profile_image(interaction: discord.Interaction, profile_data: Any):
    profile = profile_data.card
    player_data = profile_data.player
    embed = discord.Embed(title=f"{player_data.name}'s Characters Showcase")
    with BytesIO() as image_binary:
        profile.save(image_binary, "PNG")
        image_binary.seek(0)
        dfile = discord.File(image_binary, filename="profile.png")
        embed.set_image(url=f"attachment://profile.png") # noqa
        return embed, dfile


async def create_character_showcase(interaction: discord.Interaction, characters_data: Any, character_index: int):
    characters_data = characters_data.card
    embed = discord.Embed
    if 0 <= character_index < len(characters_data):
        character_data = characters_data[character_index]
        character_image = character_data.card
        with BytesIO as image_binary:
            character_image.save(image_binary, "PNG")
            image_binary.seek(0)
            dfile = discord.File(image_binary, filename="image1.png")
            embed.set_image(url=f"attachment://image1.png") # noqa
            return embed, dfile


class ShowcaseCharactersDropdown(discord.ui.Select):
    """Characters showcase dropdown menu"""
    def __init__(self, characters_data: Any) -> None:
        self.characters_data = characters_data
        # self.uid = characters_data.info['uid']
        self.uid = 821323218
        options = []
        options.append(discord.SelectOption(label="Player Overview", value="-1", emoji="📜"))
        for i, character in enumerate(characters_data.card):
            if i > 8:
                break
            print(character.name)
            options.append(discord.SelectOption(label=character.name, value=str(i), emoji=None))
        super().__init__(placeholder="Choose character to showcase:", options=options)

    async def callback(self, interaction: discord.Interaction):
        index = int(self.values[0])
        if index >= 0:
            await interaction.edit_original_response(view=ShowcaseView(self.characters_data, index))
        elif index == -1:
            profile_data = await fetch_profile(self.uid)
            embed, dfile = await create_profile_image(interaction, profile_data)
            await interaction.edit_original_response(view=ShowcaseView(embed, dfile))


class GenerateImageButton(discord.ui.Button):
    """Generate Image Button"""

    def __init__(self, characters_data: Any, character_index: int):
        super().__init__(style=discord.ButtonStyle.primary, label="Image")
        self.characters_data = characters_data
        self.character_index = character_index

    async def callback(self, interaction: discord.Interaction) -> Any:
        await self.handle_image_response(interaction, self.characters_data, self.character_index)

    @classmethod
    async def handle_image_response(
        cls, interaction: discord.Interaction, characters_data: Any, character_index: int
    ) -> None:
        """Generate character image, handle discord interaction response by sending embed to the user"""
        embed, dfile = await create_character_showcase(interaction, characters_data, character_index)
        await interaction.edit_original_response(embed=embed, attachments=[dfile])


class ShowcaseView(discord.ui.View):
    """Character showcase view, display multiple templates"""
    def __init__(self, characters_data: Any, character_index: Optional[int] = None):
        super().__init__(timeout=config.discord_view_long_timeout)
        if character_index is not None:
            self.add_item(GenerateImageButton(characters_data, character_index))
        else:
            self.add_item(ShowcaseCharactersDropdown(characters_data))


async def showcase(
    interaction: discord.Interaction,
    user: Union[discord.User, discord.Member],
    uid: Optional[int] = None
):
    await interaction.response.defer()
    _user = await Database.select_one(User, User.discord_id.is_(user.id))
    uid = uid or (_user.uid_genshin if _user else None)
    if uid is None:
        await interaction.edit_original_response(
            embed=EmbedTemplate.error(
                f"Please use {get_app_command_mention('uid-settings')} first, or directly input the UID in the command",
                title="UID not found",
            )
        )
    elif len(str(uid)) != 9 or str(uid)[0] not in ["1", "2", "5", "6", "7", "8", "9"]:
        await interaction.edit_original_response(embed=EmbedTemplate.error("Invalid UID format"))
    else:
        try:
            profile_data = await fetch_profile(uid)
            characters_data = await fetch_characters(uid)
            view = ShowcaseView(characters_data)
            embed, dfile = await create_profile_image(interaction, profile_data)
            await interaction.edit_original_response(embed=embed, attachments=[dfile], view=view)
        except Exception as e:
            LOG.ErrorLog(interaction, e)
            sentry_sdk.capture_exception(e)

            embed = EmbedTemplate.error(
                str(e) + f"\nWebsite Status Down", title=f"UID: {uid}" # noqa
            )
            await interaction.edit_original_response(embed=embed)
Leave a Comment