diff --git a/dakiny_bot/classes/voting_views.py b/dakiny_bot/classes/voting_views.py index 44b6b4f..efaffbd 100644 --- a/dakiny_bot/classes/voting_views.py +++ b/dakiny_bot/classes/voting_views.py @@ -1,18 +1,17 @@ """Contains various views to be used while voting. Controls the logic when performing the vote.""" import nextcord -from dakiny_bot.dakiny_settings import settings -from dakiny_bot.database.sql_data_classes import ( - CouncilMembers, - ElectionInformation, - Votes, - engine, -) -from dakiny_bot.utils import VoteType, build_votes_str, get_election_name from nextcord import SelectOption from nextcord.interactions import Interaction from sqlalchemy import exc, select, update from sqlalchemy.orm import Session +from sqlmodel import col + +from dakiny_bot.dakiny_settings import settings +from dakiny_bot.database.db import engine +from dakiny_bot.database.models import CouncilMember, ElectionInformation, Vote +from dakiny_bot.logger import dakiny_logger +from dakiny_bot.utils import VoteType, build_votes_str, get_election_name class VoteSelect(nextcord.ui.StringSelect): @@ -36,18 +35,32 @@ class VoteSelect(nextcord.ui.StringSelect): Args: interaction (Interaction): Interaction with this callback. """ + if ( + interaction.user is None + or not isinstance(interaction.channel, nextcord.TextChannel) + or interaction.guild is None + ): + # ignore none... Don't know what situation this is. + # if not textchannel, don't know how callback happened + # if no guild, is problem because should only be in guild. + return + election_name = get_election_name() with Session(engine) as session: - stmt = select(ElectionInformation.CouncilVoteMsgId).where(ElectionInformation.ElectionName == election_name) - vote_msg_id = session.scalar(stmt) + stmt = select(col(ElectionInformation.council_vote_msg_id)).where( + col(ElectionInformation.name == election_name) + ) + if (vote_msg_id := session.scalar(stmt)) is None: + dakiny_logger.error("Unable to find a Vote Message ID in database.") + return voted_for = None if self.values[0] == "Abstain" else int(self.values[0]) - new_vote = Votes( - ElectionName=election_name, - VoterId=interaction.user.id, - VotedForId=voted_for, - Type=VoteType.COUNCIL, + new_vote = Vote( + election_name=election_name, + voter_id=interaction.user.id, + voted_for_id=voted_for, + type=VoteType.COUNCIL, ) try: @@ -57,10 +70,10 @@ class VoteSelect(nextcord.ui.StringSelect): except exc.IntegrityError: session.rollback() stmt = ( - update(Votes) - .where(Votes.ElectionName == election_name) - .where(Votes.VoterId == interaction.user.id) - .where(Votes.Type == VoteType.COUNCIL) + update(Vote) + .where(col(Vote.election_name == election_name)) + .where(col(Vote.voter_id == interaction.user.id)) + .where(col(Vote.type == VoteType.COUNCIL)) .values(VotedForId=voted_for) ) session.execute(stmt) @@ -94,6 +107,10 @@ class VoteView(nextcord.ui.View): button (nextcord.ui.Button): Unused. idk why its needed in the decorator interaction (nextcord.Interaction): Interaction of user who pressed the button """ + if not isinstance(interaction.user, nextcord.Member): + # the user should only be a member of the guild. + return + # enforce members only if self.guild.get_role(settings.role_ids.clan_member) not in interaction.user.roles: await interaction.response.send_message( @@ -106,28 +123,25 @@ class VoteView(nextcord.ui.View): with Session(engine) as session: stmt = ( - select(Votes.VotedForId) - .where(Votes.ElectionName == election_name) - .where(Votes.VoterId == interaction.user.id) - .where(Votes.Type == VoteType.COUNCIL) + select(col(Vote.voted_for_id)) + .where(col(Vote.election_name == election_name)) + .where(col(Vote.voter_id == interaction.user.id)) + .where(col(Vote.type == VoteType.COUNCIL)) ) voted_for = session.scalar(stmt) - stmt = select(CouncilMembers.MemberId).where(CouncilMembers.ElectionName == election_name) + stmt = select(col(CouncilMember.member_id)).where(col(CouncilMember.election_name == election_name)) options = [ SelectOption( - label=( - f"{self.guild.get_member(nominee).display_name} ☑️" - if voted_for == nominee - else f"{self.guild.get_member(nominee).display_name}" - ), + label=(f"{member.display_name} ☑️" if voted_for == nominee else f"{member.display_name}"), value=str(nominee), ) for nominee in sorted( session.scalars(stmt), - key=lambda nominee: self.guild.get_member(nominee).display_name.lower(), + key=lambda nominee: self.guild.get_member(nominee).display_name.lower(), # pyright: ignore[reportOptionalMemberAccess] ) + if (member := self.guild.get_member(nominee)) is not None ] options.append( SelectOption(