async def sona(self,
                   ctx: utils.Context,
                   user: typing.Optional[discord.Member],
                   *,
                   name: str = None):
        """
        Gets your sona.
        """

        # Get the sonas
        user = user or ctx.author
        guild_id = ctx.guild.id
        if user.id == self.bot.user.id:
            guild_id = 0
        async with self.bot.database() as db:
            if name is None:
                rows = await db(
                    "SELECT * FROM fursonas WHERE guild_id=$1 AND user_id=$2",
                    guild_id, user.id)
            else:
                rows = await db(
                    "SELECT * FROM fursonas WHERE guild_id=$1 AND user_id=$2 AND LOWER(name)=LOWER($3)",
                    guild_id, user.id, name)

        # Check if they have a valid sona
        if not rows:
            return await ctx.send(
                f"{user.mention} has no sona set up on this server.")
        elif len(rows) > 1:
            available_sonas = [
                i['name'].replace('`',
                                  '\\`').replace('*',
                                                 '\\*').replace('_', '\\_')
                for i in rows
            ]
            available_string = ', '.join(f"`{name}`"
                                         for name in available_sonas)
            return await ctx.send(
                f"{user.mention} has more than one sona set - please get their sona using its name. Available sonas: {available_string}"
            )
        if rows[0]['verified'] is False:
            return await ctx.send(
                f"{user.mention}'s sona has not yet been verified.")
        if rows[0]['nsfw'] is True and ctx.channel.nsfw is False:
            return await ctx.send("I can't show NSFW sonas in a SFW channel.")

        # Wew it's sona time let's go
        sona = localutils.Fursona(**rows[0])
        return await ctx.send(embed=sona.get_embed(mention_user=True))
Exemple #2
0
    def format_page(self, menu: menus.Menu, entry: dict) -> dict:
        """Formats a sona into a thingmie and returns the embed"""

        # Format the data into an embed for the sona
        menu.raw_sona_data = entry.copy()
        content = f"Sona **{entry['name']}** from **{entry['guild_name']}** (sona {menu.current_page + 1}/{self.get_max_pages()})."
        sona = utils.Fursona(**entry)
        sona.verified = False
        menu.sona = sona
        embed = sona.get_embed(mention_user=False, add_image=True)

        # And return it to the user
        return {
            "content": content,
            "embed": embed,
        }
    async def setsonabyjson(self, ctx: utils.Context, *, data: str = None):
        """
        Lets you set your sona with a JSON string.

        Valid keys are: name, gender, age, species, orientation, height, weight, bio, image, and nsfw.
        NSFW must be a boolean. All fields must be filled (apart from image, which must be a provided key but can contain
        a null value).
        """

        # Get current sona names
        current_sona_names = getattr(ctx, "current_sona_names", None)
        if current_sona_names is None:
            async with self.bot.database() as db:
                rows = await db(
                    "SELECT * FROM fursonas WHERE guild_id=$1 AND user_id=$2",
                    ctx.guild.id, ctx.author.id)
            current_sona_names = [row['name'].lower() for row in rows]

        # See if they're at the sona limit
        try:
            sona_limit = max(o for i, o in self.bot.guild_settings[
                ctx.guild.id].setdefault('role_sona_count', dict()).items()
                             if int(i) in ctx.author._roles)
        except ValueError:
            sona_limit = 1
        if len(current_sona_names) >= sona_limit:
            return await ctx.send(
                "You're already at the sona limit - you have to delete one to be able to set another."
            )

        # Load up the information
        information = getattr(ctx, 'information', None) or json.loads(data)
        information.update({
            'guild_id': ctx.guild.id,
            'user_id': ctx.author.id,
        })

        # See if they already have a sona with that name
        if information['name'].lower() in current_sona_names:
            return await ctx.author.send(
                f"You already have a sona with the name `{information['name']}`. Please start your setup again and provide a different name."
            )
        sona_object = localutils.Fursona(**information)

        # Send it back to the user so we can make sure it sends
        user = ctx.author
        try:
            await user.send(embed=sona_object.get_embed())
        except discord.HTTPException as e:
            return await user.send(
                f"I couldn't send that embed to you - `{e}`. Please try again later."
            )

        # Send it to the verification channel
        guild_settings = self.bot.guild_settings[ctx.guild.id]
        modmail_channel_id = guild_settings.get("fursona_modmail_channel_id")
        modmail_message = None
        if modmail_channel_id:
            modmail_channel = self.bot.get_channel(modmail_channel_id)
            if modmail_channel is None:
                return await user.send(
                    f"The moderators for the server **{ctx.guild.name}** have set their fursona modmail channel to an invalid ID - please inform them of such and try again later."
                )
            try:
                modmail_message = await modmail_channel.send(
                    f"New sona submission from {user.mention}",
                    embed=sona_object.get_embed())
            except discord.Forbidden:
                return await user.send(
                    f"The moderators for the server **{ctx.guild.name}** have disallowed me from sending messages to their fursona modmail channel - please inform them of such and try again later."
                )
            try:
                await modmail_message.add_reaction("\N{HEAVY CHECK MARK}")
                await modmail_message.add_reaction("\N{HEAVY MULTIPLICATION X}"
                                                   )
                if self.bot.guild_settings[ctx.guild.id]["nsfw_is_allowed"]:
                    await modmail_message.add_reaction(
                        "\N{SMILING FACE WITH HORNS}")
            except discord.Forbidden:
                await modmail_message.delete()
                return await user.send(
                    f"The moderators for the server **{ctx.guild.name}** have disallowed me from adding reactions in their fursona modmail channel - please inform them of such and try again later."
                )
        else:
            sona_object.verified = True  # Auto verify if there's no modmail channel

        # Save sona to database now it's sent properly
        async with self.bot.database() as db:
            try:
                await sona_object.save(db)
            except asyncpg.StringDataRightTruncationError:
                try:
                    await modmail_message.delete()
                except (AttributeError, discord.HTTPException):
                    pass
                return await user.send(
                    "I couldn't save your sona into the database - one of your provided values was too long to save."
                )

        # Tell them everything was done properly
        if modmail_channel_id:
            return await user.send(
                "Your fursona has been sent to the moderators for approval! Please be patient as they review."
            )
        return await user.send("Your fursona has been saved!")