async def importsona(self, ctx: utils.Context): """ Get your sona from another server. """ # See if they're setting one up already if ctx.author.id in self.currently_setting_sonas: return await ctx.send( "You're already setting up a sona! Please finish that one off first!" ) # Try and send them an initial DM try: await ctx.author.send( f"Now taking you through importing your sona to **{ctx.guild.name}**!" ) except discord.Forbidden: return await ctx.send( "I couldn't send you a DM! Please open your DMs for this server and try again." ) self.currently_setting_sonas.add(ctx.author.id) await ctx.send("Sent you a DM!") # Get sona data async with self.bot.database() as db: database_rows = await db("SELECT * FROM fursonas WHERE user_id=$1", ctx.author.id) # Format that into a list all_user_sonas = [] for row in database_rows: try: guild = self.bot.get_guild( row['guild_id']) or await self.bot.fetch_guild( row['guild_id']) except discord.Forbidden: guild = None # Add to the all sona list menu_data = dict(row) if guild: menu_data.update({"guild_name": guild.name}) else: menu_data.update({"guild_name": "Unknown Guild Name"}) all_user_sonas.append(menu_data) # Let's add our other servers via their APIs for api_data in self.OTHER_FURRY_GUILD_DATA[::-1]: # Format data url = api_data['url'] params = { i: o.format(user=ctx.author, guild=ctx.guild, bot=self.bot) for i, o in api_data.get('params', dict()).copy().items() } headers = { i: o.format(user=ctx.author, guild=ctx.guild, bot=self.bot) for i, o in api_data.get('headers', dict()).copy().items() } # Run request try: async with self.bot.session.get(url, params=params, headers=headers) as r: grabbed_sona_data = await r.json() except Exception: grabbed_sona_data = {'data': []} # Add to lists if grabbed_sona_data['data']: guild_id = api_data['guild_id'] guild_name = api_data['name'] # Add to the all sona list for sona in grabbed_sona_data['data']: menu_data = sona.copy() menu_data.update({ "guild_name": guild_name, "guild_id": guild_id }) all_user_sonas.append(menu_data) # Filter the list all_user_sonas = [ i for i in all_user_sonas if i['guild_id'] != ctx.guild.id ] if not self.bot.guild_settings[ctx.guild.id]["nsfw_is_allowed"]: all_user_sonas = [i for i in all_user_sonas if i['nsfw'] is False] if not all_user_sonas: self.currently_setting_sonas.remove(ctx.author.id) return await ctx.send( "You have no sonas available to import from other servers.") # Send it off to the user pages = menus.MenuPages( source=FursonaPageSource(all_user_sonas, per_page=1)) await pages.start(ctx, channel=ctx.author, wait=True) # Ask if the user wants to import the sona they stopped on sona_data = pages.raw_sona_data ask_import_message = await ctx.author.send( f"Do you want to import your sona from **{sona_data['guild_name']}**?" ) await ask_import_message.add_reaction(self.CHECK_MARK_EMOJI) await ask_import_message.add_reaction(self.CROSS_MARK_EMOJI) try: check = lambda r, u: r.message.id == ask_import_message.id and u.id == ctx.author.id reaction, _ = await self.bot.wait_for("reaction_add", check=check, timeout=120) except asyncio.TimeoutError: self.currently_setting_sonas.remove(ctx.author.id) return await ctx.author.send("Timed out asking about sona import.") # Import data self.currently_setting_sonas.remove(ctx.author.id) emoji = str(reaction.emoji) if emoji == self.CROSS_MARK_EMOJI: return await ctx.author.send( "Alright, cancelled importing your sona.") command = self.bot.get_command("setsonabyjson") ctx.information = sona_data return await command.invoke(ctx)
async def setsona(self, ctx: utils.Context): """ Stores your fursona information in the bot. """ # See if the user already has a fursona stored 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] ctx.current_sona_names = current_sona_names # See if they're at the 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." ) # See if they're setting one up already if ctx.author.id in self.currently_setting_sonas: return await ctx.send( "You're already setting up a sona! Please finish that one off first!" ) # Try and send them an initial DM user = ctx.author start_message = f"Now taking you through setting up your sona on **{ctx.guild.name}**!\n" if not self.bot.guild_settings[ctx.guild.id]["nsfw_is_allowed"]: start_message += f"NSFW fursonas are not allowed for **{ctx.guild.name}** and will be automatically declined.\n" try: await user.send(start_message.strip()) except discord.Forbidden: return await ctx.send( "I couldn't send you a DM! Please open your DMs for this server and try again." ) self.currently_setting_sonas.add(user.id) await ctx.send("Sent you a DM!") # Ask about name name_message = await self.send_verification_message( user, "What is the name of your sona?") if name_message is None: return self.currently_setting_sonas.remove(user.id) if name_message.content.lower() in current_sona_names: self.currently_setting_sonas.remove(user.id) return await user.send( f"You already have a sona with the name `{name_message.content}`. Please start your setup again and provide a different name." ) # Ask about gender gender_message = await self.send_verification_message( user, "What's your sona's gender?") if gender_message is None: return self.currently_setting_sonas.remove(user.id) # Ask about age age_message = await self.send_verification_message( user, "How old is your sona?") if age_message is None: return self.currently_setting_sonas.remove(user.id) # Ask about species species_message = await self.send_verification_message( user, "What species is your sona?") if species_message is None: return self.currently_setting_sonas.remove(user.id) # Ask about orientation orientation_message = await self.send_verification_message( user, "What's your sona's orientation?") if orientation_message is None: return self.currently_setting_sonas.remove(user.id) # Ask about height height_message = await self.send_verification_message( user, "How tall is your sona?") if height_message is None: return self.currently_setting_sonas.remove(user.id) # Ask about weight weight_message = await self.send_verification_message( user, "What's the weight of your sona?") if weight_message is None: return self.currently_setting_sonas.remove(user.id) # Ask about bio bio_message = await self.send_verification_message( user, "What's the bio of your sona?", max_length=1000) if bio_message is None: return self.currently_setting_sonas.remove(user.id) # Ask about image def check(m) -> bool: return all([ isinstance(m.channel, discord.DMChannel), m.author.id == user.id, any([ m.content.lower() == "no", self.get_image_from_message(m) ]), ]) image_message = await self.send_verification_message( user, "Do you have an image for your sona? Please post it if you have one (as a link or an attachment), or say `no` to continue without.", check=check) if image_message is None: return self.currently_setting_sonas.remove(user.id) # Ask about NSFW if self.bot.guild_settings[ctx.guild.id]["nsfw_is_allowed"]: check = lambda m: isinstance( m.channel, discord.DMChannel ) and m.author.id == user.id and m.content.lower( ) in ["yes", "no"] nsfw_message = await self.send_verification_message( user, "Is your sona NSFW? Please either say `yes` or `no`.", check=check) if nsfw_message is None: return self.currently_setting_sonas.remove(user.id) else: nsfw_content = nsfw_message.content.lower() else: nsfw_content = "no" # Format that into data image_content = None if image_message.content.lower( ) == "no" else self.get_image_from_message(image_message) information = { 'name': name_message.content, 'gender': gender_message.content, 'age': age_message.content, 'species': species_message.content, 'orientation': orientation_message.content, 'height': height_message.content, 'weight': weight_message.content, 'bio': bio_message.content, 'image': image_content, 'nsfw': nsfw_content == "yes", } self.currently_setting_sonas.remove(user.id) ctx.information = information if information['nsfw'] and not self.bot.guild_settings[ ctx.guild.id]["nsfw_is_allowed"]: return await user.send( "Your fursona has been automatically declined as it is NSFW") await self.bot.get_command("setsonabyjson").invoke(ctx)