Add view clan points command. Break out function for creating the string so that code isn't duplicated.
build_develop / build (push) Successful in 2m11s

This commit is contained in:
2024-12-22 15:48:10 -05:00
parent a56b47a5fa
commit c8f5c5bffb
+87 -24
View File
@@ -12,7 +12,7 @@ from database_setup.sql_data_classes import (
Votes, Votes,
engine, 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"): class ViewCog(commands.Cog, name="View Commands"):
@@ -21,7 +21,7 @@ class ViewCog(commands.Cog, name="View Commands"):
def __init__(self) -> None: def __init__(self) -> None:
"""Default constructor for ViewCog class. Does nothing.""" """Default constructor for ViewCog class. Does nothing."""
@nextcord.slash_command() @nextcord.slash_command(guild_ids=GUILDS)
async def view(self, interaction: nextcord.Interaction) -> None: async def view(self, interaction: nextcord.Interaction) -> None:
"""Parent slash command for set. Never called.""" """Parent slash command for set. Never called."""
@@ -63,30 +63,53 @@ class ViewCog(commands.Cog, name="View Commands"):
return return
quarters = ppdf.groupby("QuarterName") quarters = ppdf.groupby("QuarterName")
content = "" content = create_points_string(interaction, quarters, PointType.EVENT)
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. if len(content) > MAX_DISCORD_MESSAGE_LENGTH:
try: await interaction.followup.send("Message length is too long, please select search to limit results.")
sorted_non_members = unsorted_all.get_group(name=False).sort_values(by="UserId") return
except KeyError:
sorted_non_members = None await interaction.followup.send(content=content, ephemeral=True)
sorted_members = members.sort_values(
by="UserId", @view.subcommand(description="Show event points.")
key=lambda user_ids: ( async def clan_points(
[interaction.guild.get_member(int(user_id)).display_name.lower() for user_id in user_ids] 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) else:
for row in sorted_all.itertuples(): ppdf = pd.read_sql_query(
userid = row.UserId sql=session.query(Points).statement,
points = row.EventPoints con=engine,
discord_member = row.DiscordMember )
content += f"<@{userid}>: {points}\n" if discord_member else f"{userid}: {points}\n"
content += "\n" 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: if len(content) > MAX_DISCORD_MESSAGE_LENGTH:
await interaction.followup.send("Message length is too long, please select search to limit results.") 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()) quarter for quarter in quarters if quarter.lower().startswith(quarter_name.lower())
] ]
await interaction.response.send_autocomplete(autofilled_quarters[:25]) 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