From 088de263ccfb4df22dda4a3080a60896e3a93385 Mon Sep 17 00:00:00 2001 From: imcompiling Date: Mon, 6 Nov 2023 20:20:58 -0500 Subject: [PATCH] Created initial view votes command. --- cogs/commands/view.py | 87 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 cogs/commands/view.py diff --git a/cogs/commands/view.py b/cogs/commands/view.py new file mode 100644 index 0000000..c20fdb8 --- /dev/null +++ b/cogs/commands/view.py @@ -0,0 +1,87 @@ +""" +Commands for viewing information in the database. +""" + +import nextcord +from nextcord.ext import commands +from sqlalchemy import select +from sqlalchemy.orm import Session + +from database_setup.sql_data_classes import ElectionInformation, Votes, engine + + +class ViewCog(commands.Cog, name="View Commands"): + """ + Holds the view commands. + """ + + def __init__(self) -> None: + """ + Default constructor for ViewCog class. Does nothing. + """ + + @nextcord.slash_command() + async def view(self, interaction: nextcord.Interaction): + """ + Parent slash command for set. Never called. + """ + + @view.subcommand(description="Shows all voters and who they voted for in a given election.") + async def votes( + self, + interaction: nextcord.Interaction, + election_name: str = nextcord.SlashOption( + required=True, description="The election you want to view votes for." + ), + ): + """ + Takes in an election name and sends a response message to the user with a list of people who voted in that + election and who they voted for. Notes those tho abstained. Tells a user if the election is invalid. Uses + autocompletion to assist with getting elections. + + Args: + interaction (nextcord.Interaction): User's interaction with the command. + election_name (str): Is SlashOption. The name of the election to view votes for. + """ + + stmt = select(Votes).where(Votes.ElectionCycle == election_name) + + with Session(engine) as session: + try: + votes = session.scalars(stmt) + content = "" + + for vote in votes: + content += ( + f"<@{vote.VoterId}> voted for <@{vote.VotedForId}>." + if vote.VotedForId is not None + else f"<@{vote.VoterId}> abstained from voted." + ) + + await interaction.response.send_message(content=content, ephemeral=True) + except: + await interaction.response.send_message(f"Invalid election: {election_name}.", ephemeral=True) + + @view.on_autocomplete("election_name") + async def election_autocomplete(self, interaction: nextcord.Interaction, election_name: str): + """ + Collects all elections that start with the election string. + + Args: + interaction (nextcord.Interaction): Interaction with command. + election_name (str): String to run autocomplete on. + """ + + with Session(engine) as session: + stmt = select(ElectionInformation.ElectionCycle) + elections = session.scalars(stmt) + + # if empty compare string + if not election_name: + await interaction.response.send_autocomplete(elections) + return + + autofilled_elections: "list[str]" = [ + election for election in elections if election.lower().startswith(election_name.lower()) + ] + await interaction.response.send_autocomplete(autofilled_elections[:25])