Compare commits

..
Author SHA1 Message Date
imcompiling 29a6b000ac Merge branch '49-view-votes-cant-see-HC-elections'
build_latest / build (push) Successful in 17s
build_release / build (push) Successful in 17s
2024-05-19 11:29:41 -04:00
imcompiling dbd2863aab Pass VoteType str instead of manual one in VoteSelect.
build_develop / build (push) Successful in 1m24s
2024-05-19 11:29:04 -04:00
imcompiling 426f009ca7 Use VoteType in utils. Remove old functions of getting clan leader and discord manager election names. 2024-05-19 10:50:23 -04:00
imcompiling ed07b2e231 Use VoteType in view command. 2024-05-19 10:46:05 -04:00
imcompiling 0caa41cc90 use VoteType in voting views. 2024-05-19 10:40:41 -04:00
imcompiling e93f37dcf0 Use VoteType in voting highcouncil views. 2024-05-19 10:38:10 -04:00
imcompiling 44c3961c46 Use VoteType in election_cycle 2024-05-19 10:31:16 -04:00
imcompiling 0dcdd038b8 Make the VoteType StrEnum and edit column in database to enforce only 3 values.
build_develop / build (push) Successful in 1m21s
2024-05-18 23:08:01 -04:00
imcompiling eb5d465ac9 Merge branch 'main' into 49--view-votes-can't-see-HC-elections
build_develop / build (push) Failing after 16s
2024-05-18 22:41:11 -04:00
imcompiling eb1c87fbf4 install sqlite3 onto container. Using it a lot for debugging/fixes.
build_latest / build (push) Successful in 1m29s
build_release / build (push) Successful in 22s
2024-05-18 22:38:57 -04:00
imcompiling cbd73a104e Merge branch '61-Create-virtual-environment-and-update-python-version' 2024-05-18 22:34:35 -04:00
imcompiling bc56830396 Merge branch '49--view-votes-can't-see-HC-elections' of https://gitea.cheezers.org/imcompiling/dakiny-bot into 49--view-votes-can't-see-HC-elections
build_develop / build (push) Failing after 17s
2024-05-18 16:36:03 -04:00
imcompiling 1d14f8171d Add vote type to one statement. 2024-05-18 16:34:33 -04:00
imcompiling 2efd380a7e Add VoteType Enum. 2024-05-18 16:26:11 -04:00
imcompiling 475170025a Edit database to add a type field to Votes. 2024-05-18 16:25:19 -04:00
imcompiling f4f3bfe103 Edit database to add a type field to Votes.
build_develop / build (push) Failing after 18s
2024-05-18 15:39:13 -04:00
7 changed files with 85 additions and 76 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
FROM python:3.11.9-slim FROM python:3.11.9-slim
# install dependencies # install dependencies
RUN apt-get update && apt-get -y upgrade && apt-get -y install git RUN apt-get update && apt-get -y upgrade && apt-get -y install git sqlite3
WORKDIR /home WORKDIR /home
+20 -10
View File
@@ -22,12 +22,11 @@ from database_setup.sql_data_classes import (
) )
from utils import ( from utils import (
TEMPLATES_DIR, TEMPLATES_DIR,
VoteType,
build_highcouncil_votes_str, build_highcouncil_votes_str,
build_votes_str, build_votes_str,
edit_clan_council_info, edit_clan_council_info,
get_cl_election_name,
get_datetime, get_datetime,
get_dm_election_name,
get_election_name, get_election_name,
) )
@@ -294,7 +293,11 @@ class ElectionCycle:
session.commit() session.commit()
# add the highcouncil role to everyone with 3 or more votes. set elected to true in database # add the highcouncil role to everyone with 3 or more votes. set elected to true in database
stmt = select(Votes.VotedForId).where(Votes.ElectionCycle == election_name) stmt = (
select(Votes.VotedForId)
.where(Votes.ElectionCycle == election_name)
.where(Votes.Type == VoteType.COUNCIL)
)
vote_count = collections.Counter(session.scalars(stmt)) vote_count = collections.Counter(session.scalars(stmt))
for user_id, votes in vote_count.items(): for user_id, votes in vote_count.items():
@@ -358,11 +361,13 @@ class ElectionCycle:
self.config.params.clan_council_role_id self.config.params.clan_council_role_id
) )
election_cycle = get_election_name(self.config)
with Session(engine) as session: with Session(engine) as session:
# role management # role management
stmt = ( stmt = (
select(CouncilMembers.MemberId) select(CouncilMembers.MemberId)
.where(CouncilMembers.ElectionCycle == get_election_name(self.config)) .where(CouncilMembers.ElectionCycle == election_cycle)
.where(CouncilMembers.Elected == true()) .where(CouncilMembers.Elected == true())
) )
@@ -379,14 +384,19 @@ class ElectionCycle:
# announce high council members # announce high council members
# ties are undefined behavior. # ties are undefined behavior.
dm_election = get_dm_election_name(self.config) stmt = (
cl_election = get_cl_election_name(self.config) select(Votes.VotedForId)
stmt = select(Votes.VotedForId).where(Votes.ElectionCycle == dm_election) .where(Votes.ElectionCycle == election_cycle)
.where(Votes.Type == VoteType.DISCORDMANAGER)
)
dm_votes = collections.Counter(session.scalars(stmt)) dm_votes = collections.Counter(session.scalars(stmt))
stmt = select(Votes.VotedForId).where(Votes.ElectionCycle == cl_election) stmt = (
select(Votes.VotedForId)
.where(Votes.ElectionCycle == election_cycle)
.where(Votes.Type == VoteType.CLANLEADER)
)
cl_votes = collections.Counter(session.scalars(stmt)) cl_votes = collections.Counter(session.scalars(stmt))
election_cycle = get_election_name(self.config)
try: try:
dm_winner = max(dm_votes, key=dm_votes.get) dm_winner = max(dm_votes, key=dm_votes.get)
stmt = ( stmt = (
@@ -425,7 +435,7 @@ class ElectionCycle:
await vote_msg.edit(view=None) await vote_msg.edit(view=None)
highcouncil_msg: str = ( highcouncil_msg: str = (
f"Congratulations for our high council members!\n Clan Leader: <@{cl_winner}>\n" f"Congratulations for our high council members!\nClan Leader: <@{cl_winner}>\n"
) )
highcouncil_msg += f"Discord Manager: <@{dm_winner}>" highcouncil_msg += f"Discord Manager: <@{dm_winner}>"
await election_thread.send(highcouncil_msg) await election_thread.send(highcouncil_msg)
+22 -28
View File
@@ -17,12 +17,7 @@ from database_setup.sql_data_classes import (
Votes, Votes,
engine, engine,
) )
from utils import ( from utils import VoteType, build_highcouncil_votes_str, get_election_name
build_highcouncil_votes_str,
get_cl_election_name,
get_dm_election_name,
get_election_name,
)
class VoteSelect(nextcord.ui.StringSelect): class VoteSelect(nextcord.ui.StringSelect):
@@ -39,20 +34,10 @@ class VoteSelect(nextcord.ui.StringSelect):
self.election_type = election_type self.election_type = election_type
async def callback(self, interaction: Interaction): async def callback(self, interaction: Interaction):
# decide on election type election_name: str = get_election_name(self.config)
match self.election_type:
case "cl":
election_name: str = get_cl_election_name(self.config)
case "dm":
election_name: str = get_dm_election_name(self.config)
case _:
# should never happen
raise ValueError('election type was not "cl" or "dm"')
cycle: str = get_election_name(self.config)
with Session(engine) as session: with Session(engine) as session:
stmt = select(ElectionInformation.HighCouncilVoteMsgId).where( stmt = select(ElectionInformation.HighCouncilVoteMsgId).where(
ElectionInformation.ElectionCycle == cycle ElectionInformation.ElectionCycle == election_name
) )
vote_msg_id = session.scalar(stmt) vote_msg_id = session.scalar(stmt)
@@ -65,6 +50,7 @@ class VoteSelect(nextcord.ui.StringSelect):
ElectionCycle=election_name, ElectionCycle=election_name,
VoterId=interaction.user.id, VoterId=interaction.user.id,
VotedForId=voted_for, VotedForId=voted_for,
Type=self.election_type,
) )
try: try:
@@ -72,11 +58,13 @@ class VoteSelect(nextcord.ui.StringSelect):
session.commit() session.commit()
except exc.IntegrityError: except exc.IntegrityError:
# user already has a vote in the election and election type
session.rollback() session.rollback()
stmt = ( stmt = (
update(Votes) update(Votes)
.where(Votes.ElectionCycle == election_name) .where(Votes.ElectionCycle == election_name)
.where(Votes.VoterId == interaction.user.id) .where(Votes.VoterId == interaction.user.id)
.where(Votes.Type == self.election_type)
.values(VotedForId=voted_for) .values(VotedForId=voted_for)
) )
session.execute(stmt) session.execute(stmt)
@@ -135,20 +123,20 @@ class VoteHighcouncilView(nextcord.ui.View):
) )
return return
cycle: str = get_election_name(self.config) election_name: str = get_election_name(self.config)
election: str = get_cl_election_name(self.config)
with Session(engine) as session: with Session(engine) as session:
stmt = ( stmt = (
select(Votes.VotedForId) select(Votes.VotedForId)
.where(Votes.ElectionCycle == election) .where(Votes.ElectionCycle == election_name)
.where(Votes.VoterId == interaction.user.id) .where(Votes.VoterId == interaction.user.id)
.where(Votes.Type == VoteType.CLANLEADER)
) )
voted_for = session.scalar(stmt) voted_for = session.scalar(stmt)
stmt = ( stmt = (
select(CouncilMembers.MemberId) select(CouncilMembers.MemberId)
.where(CouncilMembers.ElectionCycle == cycle) .where(CouncilMembers.ElectionCycle == election_name)
.filter(CouncilMembers.ClanLeaderSpeechId.is_not(None)) .filter(CouncilMembers.ClanLeaderSpeechId.is_not(None))
) )
@@ -175,7 +163,9 @@ class VoteHighcouncilView(nextcord.ui.View):
view = nextcord.ui.View() view = nextcord.ui.View()
view.add_item( view.add_item(
VoteSelect(options=options, config=self.config, election_type="cl") VoteSelect(
options=options, config=self.config, election_type=VoteType.CLANLEADER
)
) )
await interaction.response.send_message( await interaction.response.send_message(
@@ -213,20 +203,20 @@ class VoteHighcouncilView(nextcord.ui.View):
) )
return return
cycle: str = get_election_name(self.config) election_name: str = get_election_name(self.config)
election: str = get_dm_election_name(self.config)
with Session(engine) as session: with Session(engine) as session:
stmt = ( stmt = (
select(Votes.VotedForId) select(Votes.VotedForId)
.where(Votes.ElectionCycle == election) .where(Votes.ElectionCycle == election_name)
.where(Votes.VoterId == interaction.user.id) .where(Votes.VoterId == interaction.user.id)
.where(Votes.Type == VoteType.DISCORDMANAGER)
) )
voted_for = session.scalar(stmt) voted_for = session.scalar(stmt)
stmt = ( stmt = (
select(CouncilMembers.MemberId) select(CouncilMembers.MemberId)
.where(CouncilMembers.ElectionCycle == cycle) .where(CouncilMembers.ElectionCycle == election_name)
.filter(CouncilMembers.DiscordManagerSpeechId.is_not(None)) .filter(CouncilMembers.DiscordManagerSpeechId.is_not(None))
) )
@@ -253,7 +243,11 @@ class VoteHighcouncilView(nextcord.ui.View):
view = nextcord.ui.View() view = nextcord.ui.View()
view.add_item( view.add_item(
VoteSelect(options=options, config=self.config, election_type="dm") VoteSelect(
options=options,
config=self.config,
election_type=VoteType.DISCORDMANAGER,
)
) )
await interaction.response.send_message( await interaction.response.send_message(
+4 -1
View File
@@ -17,7 +17,7 @@ from database_setup.sql_data_classes import (
Votes, Votes,
engine, engine,
) )
from utils import build_votes_str, get_election_name from utils import VoteType, build_votes_str, get_election_name
class VoteSelect(nextcord.ui.StringSelect): class VoteSelect(nextcord.ui.StringSelect):
@@ -47,6 +47,7 @@ class VoteSelect(nextcord.ui.StringSelect):
ElectionCycle=election_name, ElectionCycle=election_name,
VoterId=interaction.user.id, VoterId=interaction.user.id,
VotedForId=voted_for, VotedForId=voted_for,
Type=VoteType.COUNCIL,
) )
try: try:
@@ -59,6 +60,7 @@ class VoteSelect(nextcord.ui.StringSelect):
update(Votes) update(Votes)
.where(Votes.ElectionCycle == election_name) .where(Votes.ElectionCycle == election_name)
.where(Votes.VoterId == interaction.user.id) .where(Votes.VoterId == interaction.user.id)
.where(Votes.Type == VoteType.COUNCIL)
.values(VotedForId=voted_for) .values(VotedForId=voted_for)
) )
session.execute(stmt) session.execute(stmt)
@@ -121,6 +123,7 @@ class VoteView(nextcord.ui.View):
select(Votes.VotedForId) select(Votes.VotedForId)
.where(Votes.ElectionCycle == election) .where(Votes.ElectionCycle == election)
.where(Votes.VoterId == interaction.user.id) .where(Votes.VoterId == interaction.user.id)
.where(Votes.Type == VoteType.COUNCIL)
) )
voted_for = session.scalar(stmt) voted_for = session.scalar(stmt)
+11 -1
View File
@@ -14,6 +14,7 @@ from database_setup.sql_data_classes import (
Votes, Votes,
engine, engine,
) )
from utils import VoteType
class ViewCog(commands.Cog, name="View Commands"): class ViewCog(commands.Cog, name="View Commands"):
@@ -148,6 +149,11 @@ class ViewCog(commands.Cog, name="View Commands"):
election_name: str = nextcord.SlashOption( election_name: str = nextcord.SlashOption(
required=True, description="The election you want to view votes for." required=True, description="The election you want to view votes for."
), ),
election_type: str = nextcord.SlashOption(
required=True,
description="The election type. Council, Discord Manager, or Clan Leader.",
choices=VoteType,
),
): ):
""" """
Takes in an election name and sends a response message to the user with a list of people who voted in that Takes in an election name and sends a response message to the user with a list of people who voted in that
@@ -159,7 +165,11 @@ class ViewCog(commands.Cog, name="View Commands"):
election_name (str): Is SlashOption. The name of the election to view votes for. election_name (str): Is SlashOption. The name of the election to view votes for.
""" """
stmt = select(Votes).where(Votes.ElectionCycle == election_name) stmt = (
select(Votes)
.where(Votes.ElectionCycle == election_name)
.where(Votes.Type == election_type)
)
with Session(engine) as session: with Session(engine) as session:
# Check if election exists. # Check if election exists.
+2 -1
View File
@@ -25,8 +25,9 @@ CREATE TABLE Votes(
ElectionCycle varchar(30) not null, ElectionCycle varchar(30) not null,
VoterId bigint unsigned not null, VoterId bigint unsigned not null,
VotedForId bigint unsigned, VotedForId bigint unsigned,
Type varchar(14) not null DEFAULT 'council' check("Type" in ('council', 'discordmanager', 'clanleader')),
FOREIGN KEY (ElectionCycle) REFERENCES ElectionInformation(ElectionCycle), FOREIGN KEY (ElectionCycle) REFERENCES ElectionInformation(ElectionCycle),
PRIMARY KEY (ElectionCycle, VoterId) PRIMARY KEY (ElectionCycle, VoterId, Type)
); );
CREATE TABLE UserBirthday ( CREATE TABLE UserBirthday (
+25 -34
View File
@@ -4,6 +4,7 @@ File contains util functions.
import os import os
from datetime import datetime from datetime import datetime
from enum import StrEnum
from typing import Iterable from typing import Iterable
import nextcord import nextcord
@@ -24,6 +25,8 @@ REPO_DIR = "./dakiny-messages"
MESSAGES_DIR = f"{REPO_DIR}/messages" MESSAGES_DIR = f"{REPO_DIR}/messages"
TEMPLATES_DIR = f"{REPO_DIR}/message_templates" TEMPLATES_DIR = f"{REPO_DIR}/message_templates"
VoteType = StrEnum("VoteType", ["COUNCIL", "DISCORDMANAGER", "CLANLEADER"])
def get_datetime(day: str) -> datetime: def get_datetime(day: str) -> datetime:
""" """
@@ -82,34 +85,6 @@ def get_quarter_name(config: DakinyConfig) -> str:
return f"{get_datetime(current_cycle.term_start).year}-{current_cycle.name}" return f"{get_datetime(current_cycle.term_start).year}-{current_cycle.name}"
def get_dm_election_name(config: DakinyConfig) -> str:
"""
creates the name of the discord manager election
Args:
config (DakinyConfig): Config sent to get_election_cycle_name
Returns:
str: the name of the election
"""
return f"{get_election_name(config)}-dm"
def get_cl_election_name(config: DakinyConfig) -> str:
"""
creates the name of the clan leader election
Args:
config (DakinyConfig): Config sent to get_election_cycle_name
Returns:
str: the name of the election
"""
return f"{get_election_name(config)}-cl"
def get_current_election_cycle(config: DakinyConfig) -> int: def get_current_election_cycle(config: DakinyConfig) -> int:
""" """
Returns index for active election. An election is considered active between the election start and the term start. Returns index for active election. An election is considered active between the election start and the term start.
@@ -170,9 +145,11 @@ def build_votes_str(config: DakinyConfig, guild: nextcord.Guild) -> str:
votes: dict[int, int] = {} votes: dict[int, int] = {}
election_name = get_election_name(config)
with Session(engine) as session: with Session(engine) as session:
stmt = select(CouncilMembers).where( stmt = select(CouncilMembers).where(
CouncilMembers.ElectionCycle == get_election_name(config) CouncilMembers.ElectionCycle == election_name
) )
for nominee in sorted( for nominee in sorted(
@@ -181,7 +158,11 @@ def build_votes_str(config: DakinyConfig, guild: nextcord.Guild) -> str:
): ):
votes[nominee.MemberId] = 0 votes[nominee.MemberId] = 0
stmt = select(Votes).where(Votes.ElectionCycle == get_election_name(config)) stmt = (
select(Votes)
.where(Votes.ElectionCycle == election_name)
.where(Votes.Type == VoteType.COUNCIL)
)
for vote in session.scalars(stmt): for vote in session.scalars(stmt):
if vote.VotedForId is not None: if vote.VotedForId is not None:
@@ -208,10 +189,12 @@ def build_highcouncil_votes_str(config: DakinyConfig, guild: nextcord.Guild) ->
cl_votes: dict[int, int] = {} cl_votes: dict[int, int] = {}
dm_votes: dict[int, int] = {} dm_votes: dict[int, int] = {}
election_name = get_election_name(config)
with Session(engine) as session: with Session(engine) as session:
stmt = ( stmt = (
select(CouncilMembers) select(CouncilMembers)
.where(CouncilMembers.ElectionCycle == get_election_name(config)) .where(CouncilMembers.ElectionCycle == election_name)
.filter(CouncilMembers.ClanLeaderSpeechId.is_not(None)) .filter(CouncilMembers.ClanLeaderSpeechId.is_not(None))
) )
@@ -221,7 +204,11 @@ def build_highcouncil_votes_str(config: DakinyConfig, guild: nextcord.Guild) ->
): ):
cl_votes[nominee.MemberId] = 0 cl_votes[nominee.MemberId] = 0
stmt = select(Votes).where(Votes.ElectionCycle == get_cl_election_name(config)) stmt = (
select(Votes)
.where(Votes.ElectionCycle == election_name)
.where(Votes.Type == VoteType.CLANLEADER)
)
for vote in session.scalars(stmt): for vote in session.scalars(stmt):
if vote.VotedForId is not None: if vote.VotedForId is not None:
@@ -229,7 +216,7 @@ def build_highcouncil_votes_str(config: DakinyConfig, guild: nextcord.Guild) ->
stmt = ( stmt = (
select(CouncilMembers) select(CouncilMembers)
.where(CouncilMembers.ElectionCycle == get_election_name(config)) .where(CouncilMembers.ElectionCycle == election_name)
.filter(CouncilMembers.DiscordManagerSpeechId.is_not(None)) .filter(CouncilMembers.DiscordManagerSpeechId.is_not(None))
) )
@@ -239,7 +226,11 @@ def build_highcouncil_votes_str(config: DakinyConfig, guild: nextcord.Guild) ->
): ):
dm_votes[nominee.MemberId] = 0 dm_votes[nominee.MemberId] = 0
stmt = select(Votes).where(Votes.ElectionCycle == get_dm_election_name(config)) stmt = (
select(Votes)
.where(Votes.ElectionCycle == election_name)
.where(Votes.Type == VoteType.DISCORDMANAGER)
)
for vote in session.scalars(stmt): for vote in session.scalars(stmt):
if vote.VotedForId is not None: if vote.VotedForId is not None: