diff --git a/cogs/commands/view.py b/cogs/commands/view.py index 0620e4a..3852d6e 100644 --- a/cogs/commands/view.py +++ b/cogs/commands/view.py @@ -12,7 +12,7 @@ from database_setup.sql_data_classes import ( Votes, engine, ) -from utils import MAX_DISCORD_MESSAGE_LENGTH, VoteType +from utils import GUILDS, MAX_DISCORD_MESSAGE_LENGTH, PointType, VoteType class ViewCog(commands.Cog, name="View Commands"): @@ -21,7 +21,7 @@ class ViewCog(commands.Cog, name="View Commands"): def __init__(self) -> None: """Default constructor for ViewCog class. Does nothing.""" - @nextcord.slash_command() + @nextcord.slash_command(guild_ids=GUILDS) async def view(self, interaction: nextcord.Interaction) -> None: """Parent slash command for set. Never called.""" @@ -63,30 +63,53 @@ class ViewCog(commands.Cog, name="View Commands"): return quarters = ppdf.groupby("QuarterName") - content = "" - for quarter in quarters.groups: - content += f"**{quarter}**\n" - unsorted_all = quarters.get_group(quarter).groupby("DiscordMember") - members = unsorted_all.get_group(name=True) + content = create_points_string(interaction, quarters, PointType.EVENT) - # there can be no non-discord members sometimes. - try: - sorted_non_members = unsorted_all.get_group(name=False).sort_values(by="UserId") - except KeyError: - sorted_non_members = None - sorted_members = members.sort_values( - by="UserId", - key=lambda user_ids: ( - [interaction.guild.get_member(int(user_id)).display_name.lower() for user_id in user_ids] - ), + if len(content) > MAX_DISCORD_MESSAGE_LENGTH: + await interaction.followup.send("Message length is too long, please select search to limit results.") + return + + await interaction.followup.send(content=content, ephemeral=True) + + @view.subcommand(description="Show event points.") + async def clan_points( + self, + interaction: nextcord.Interaction, + quarter_name: str = nextcord.SlashOption( + description="The quarter to view", + required=False, + ), + ) -> None: + """ + View the clan points. + + Builds a message with the clan points for the quarter that matches with quarter_name. + + Args: + interaction (nextcord.Interaction): Interaction with the message. + quarter_name (str, optional): Same of quarter to autofill with. Is SlashOption. + """ + # just in case + await interaction.response.defer(ephemeral=True) + + with Session(engine) as session: + if quarter_name: + ppdf = pd.read_sql_query( + sql=session.query(Points).where(Points.QuarterName.startswith(quarter_name)).statement, + con=engine, ) - sorted_all = pd.concat([sorted_members, sorted_non_members], ignore_index=True, sort=False) - for row in sorted_all.itertuples(): - userid = row.UserId - points = row.EventPoints - discord_member = row.DiscordMember - content += f"<@{userid}>: {points}\n" if discord_member else f"{userid}: {points}\n" - content += "\n" + else: + ppdf = pd.read_sql_query( + sql=session.query(Points).statement, + con=engine, + ) + + if ppdf.empty: + await interaction.followup.send(f'Quarter "{quarter_name}" is invalid.', ephemeral=True) + return + + quarters = ppdf.groupby("QuarterName") + content = create_points_string(interaction, quarters, PointType.CLAN) if len(content) > MAX_DISCORD_MESSAGE_LENGTH: await interaction.followup.send("Message length is too long, please select search to limit results.") @@ -213,3 +236,43 @@ class ViewCog(commands.Cog, name="View Commands"): quarter for quarter in quarters if quarter.lower().startswith(quarter_name.lower()) ] await interaction.response.send_autocomplete(autofilled_quarters[:25]) + + +def create_points_string(interaction: nextcord.Interaction, quarters: any, point_type: PointType) -> str: + """ + Creates the string to show how many clan/event points users have. + + Args: + interaction (nextcord.Interaction): Discord interaction of the command. + quarters (any): Pandas objects grouped by quarters. + point_type (PointType): The type of points to create the message for. + + Returns: + str: The string with the message content. + """ + content: str = "" + for quarter in quarters.groups: + content += f"**{quarter}**\n" + unsorted_all = quarters.get_group(quarter).groupby("DiscordMember") + members = unsorted_all.get_group(name=True) + + # there can be no non-discord members sometimes. + try: + sorted_non_members = unsorted_all.get_group(name=False).sort_values(by="UserId") + except KeyError: + sorted_non_members = None + sorted_members = members.sort_values( + by="UserId", + key=lambda user_ids: ( + [interaction.guild.get_member(int(user_id)).display_name.lower() for user_id in user_ids] + ), + ) + sorted_all = pd.concat([sorted_members, sorted_non_members], ignore_index=True, sort=False) + for row in sorted_all.itertuples(): + userid = row.UserId + points = row.EventPoints if point_type == PointType.EVENT else row.ClanPoints + discord_member = row.DiscordMember + if points > 0: + content += f"<@{userid}>: {points}\n" if discord_member else f"{userid}: {points}\n" + content += "\n" + return content