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))
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!")