Compare commits

...
Author SHA1 Message Date
imcompiling 2596b9fa7b Merge branch '47-incorrect-election-cycle'
build_latest / build (push) Successful in 44s
build_release / build (push) Successful in 45s
2024-01-01 13:32:41 -05:00
imcompiling 8c654612a9 Ensure that rolback months are properly year-ed.
build_develop / build (push) Successful in 1m27s
2024-01-01 13:32:17 -05:00
imcompiling e836ead399 Force crash on no election cycle. -1 was causing last item in config array to be used.
build_develop / build (push) Successful in 1m38s
2024-01-01 13:23:29 -05:00
imcompiling fa691ced5d Space on the wrong side of the quote.
build_latest / build (push) Successful in 1m33s
build_release / build (push) Successful in 45s
2023-12-27 09:50:01 -05:00
imcompiling 81f4c7741b Merge branch '40-remove-presence'
build_latest / build (push) Successful in 1m29s
build_release / build (push) Successful in 45s
2023-12-23 14:48:23 -05:00
imcompiling 2cde9f7109 Fix bug preventing remove from working.
build_develop / build (push) Successful in 1m40s
Remove guild ids.
2023-12-23 14:48:12 -05:00
imcompiling 2632bb883f Filled out remove presence some more. Not currently working.
build_develop / build (push) Successful in 1m25s
2023-12-22 22:05:07 -05:00
imcompiling 2f75f0cdcb Finish up presence auto complete function. 2023-12-22 21:56:29 -05:00
imcompiling deb405f02b Might not have worked without list cast. 2023-12-22 21:35:52 -05:00
imcompiling ee7cbaf2f6 Merge branch '39-view-presences'
build_latest / build (push) Successful in 1m26s
2023-12-22 21:33:45 -05:00
imcompiling 7ba7d3563c Rework logic to use less loops.
build_develop / build (push) Successful in 1m28s
2023-12-22 21:33:34 -05:00
imcompiling 39746123f1 Add beginning of remove presence. 2023-12-22 21:23:29 -05:00
imcompiling c69adb8374 Limit items sent back on autocomplete (small bug) 2023-12-22 21:23:18 -05:00
imcompiling f722a6a87b Do not want guild ids 2023-12-22 16:36:31 -05:00
imcompiling b3550bbf55 Merge commit '0a18d819afecade9a9812df4c9056ba19bb4d211'
build_develop / build (push) Successful in 1m25s
2023-12-22 16:32:42 -05:00
imcompiling 0a18d819af Add command to view presences. 2023-12-22 16:32:32 -05:00
imcompiling 2bd4fcb136 Format change for presence request.
build_latest / build (push) Successful in 1m37s
build_release / build (push) Successful in 45s
build_develop / build (push) Successful in 52s
2023-12-21 19:23:13 -05:00
imcompiling 2a91274d7f Need to use the and keyword. 2023-12-21 19:22:48 -05:00
imcompiling 4fb4927fb8 Merge branch '36-bot-presence'
build_latest / build (push) Successful in 43s
build_develop / build (push) Successful in 45s
2023-12-20 21:47:07 -05:00
imcompiling fbd8419ccf Add the add presence request.
build_develop / build (push) Successful in 1m33s
2023-12-20 21:45:20 -05:00
imcompiling 09ff620e51 Add loop for changing presence. 2023-12-20 21:38:52 -05:00
imcompiling 9c64e574fe Add new table to record bot presences. 2023-12-20 21:02:04 -05:00
imcompiling 011b6551b0 highcouncil election message update.
build_latest / build (push) Successful in 1m31s
build_release / build (push) Successful in 45s
build_develop / build (push) Successful in 56s
2023-12-20 09:27:18 -05:00
imcompiling 45b304308b Merge branch '35-remove-nomination-views'
build_latest / build (push) Successful in 45s
build_release / build (push) Successful in 45s
2023-12-17 15:36:50 -05:00
imcompiling 43ef19fd82 Cover highcouncil edge case.
build_develop / build (push) Successful in 1m29s
2023-12-17 15:36:04 -05:00
imcompiling 757d2e5c19 Stored nomination message in wrong place. 2023-12-17 15:27:54 -05:00
imcompiling 8394cdd6fd Remove nomination views once they are done. 2023-12-17 15:06:19 -05:00
imcompiling a9c3719c29 Add two new fields to election information. 2023-12-17 14:44:32 -05:00
imcompiling 250de5baf8 Merge branch '18-highcouncil-election'
build_latest / build (push) Successful in 1m39s
build_develop / build (push) Successful in 48s
2023-12-17 14:36:57 -05:00
11 changed files with 356 additions and 39 deletions
+1 -2
View File
@@ -7,7 +7,6 @@ From {highcouncil_election_announce} to {highcouncil_election_start}, you will b
Clan Leader Clan Leader
Discord Server Manager Discord Server Manager
Each member of the CCE can cast one for each category by using the emotes: <:Rank_Owner:479008325137072155> for Clan Leader and <:Rank_Deputy:479008295319896064> for Discord Server Manager. Each member of the CCE can vote once in each category (Discord Server Manager and Clan Leader). Alternatively, you may choose to intentionally abstain.
If needed, the icon 🤷 can be used to abstain to vote in any or both categories and it should be applied to all candidates of that category.
Votes can be cast until {highcouncil_election_end}, so we can announce and have everyone set up to start the term by {term_start}. Votes can be cast until {highcouncil_election_end}, so we can announce and have everyone set up to start the term by {term_start}.
+50 -21
View File
@@ -201,16 +201,9 @@ class ElectionCycle:
thread_msg: nextcord.Message = await parent.send(content=quarter_name) thread_msg: nextcord.Message = await parent.send(content=quarter_name)
# create new entry into database.
thread: nextcord.Thread = await parent.create_thread( thread: nextcord.Thread = await parent.create_thread(
name=quarter_name, message=thread_msg name=quarter_name, message=thread_msg
) )
with Session(engine) as session:
new_cycle = ElectionInformation(
ElectionCycle=quarter_name, ThreadId=thread.id
)
session.add(new_cycle)
session.commit()
# post message announcing election # post message announcing election
# election start message is returned as an array of string because it is too long. send each string # election start message is returned as an array of string because it is too long. send each string
@@ -219,10 +212,22 @@ class ElectionCycle:
for index, message in enumerate(messages): for index, message in enumerate(messages):
# if last item, add the nominate button # if last item, add the nominate button
if index + 1 == len(messages): if index + 1 == len(messages):
await thread.send(message, view=NominateView(self.config, self.guild)) nominate_msg: nextcord.Message = await thread.send(
message, view=NominateView(self.config, self.guild)
)
else: else:
await thread.send(message) await thread.send(message)
# create new entry into database.
with Session(engine) as session:
new_cycle = ElectionInformation(
ElectionCycle=quarter_name,
ThreadId=thread.id,
CouncilNominationMsgId=nominate_msg.id,
)
session.add(new_cycle)
session.commit()
async def voting_start_action(self) -> None: async def voting_start_action(self) -> None:
""" """
Sends message informing members that voting has started. Sends message informing members that voting has started.
@@ -246,6 +251,12 @@ class ElectionCycle:
info.CouncilVoteMsgId = vote_msg.id info.CouncilVoteMsgId = vote_msg.id
session.commit() session.commit()
thread: nextcord.Thread = self.guild.get_thread(info.ThreadId)
nominate_msg: nextcord.Message = await thread.fetch_message(
info.CouncilNominationMsgId
)
await nominate_msg.edit(view=None)
async def voting_end_action(self) -> None: async def voting_end_action(self) -> None:
""" """
Performs required actions for when voting time has ended. Performs required actions for when voting time has ended.
@@ -259,18 +270,28 @@ class ElectionCycle:
self.get_election_info().ThreadId self.get_election_info().ThreadId
) )
# remove vote button from vote message nominate_msg: nextcord.Message = await election_thread.send(
message, view=NominateHighCouncilView(self.config, self.guild)
)
election_name = get_election_cycle_name(self.config) election_name = get_election_cycle_name(self.config)
with Session(engine) as session: with Session(engine) as session:
stmt = select(ElectionInformation.CouncilVoteMsgId).where( # remove vote button from vote message
stmt = select(ElectionInformation).where(
ElectionInformation.ElectionCycle == election_name ElectionInformation.ElectionCycle == election_name
) )
vote_msg_id = session.scalar(stmt) info = session.scalar(stmt)
vote_msg: nextcord.Message = await election_thread.fetch_message(vote_msg_id) vote_msg: nextcord.Message = await election_thread.fetch_message(
await vote_msg.edit(view=None) info.CouncilVoteMsgId
)
await vote_msg.edit(view=None)
# add the highcouncil role to everyone with 3 or more votes. set elected to true in database # add the highcouncil nomination message to election information
with Session(engine) as session: info.HighCouncilNominationMsgId = nominate_msg.id
session.commit()
# 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)
vote_count = collections.Counter(session.scalars(stmt)) vote_count = collections.Counter(session.scalars(stmt))
@@ -292,10 +313,6 @@ class ElectionCycle:
reason=f"{member.display_name} has won a nomination and become a Council Elect.", reason=f"{member.display_name} has won a nomination and become a Council Elect.",
) )
await election_thread.send(
message, view=NominateHighCouncilView(self.config, self.guild)
)
async def highcouncil_election_start_action(self) -> None: async def highcouncil_election_start_action(self) -> None:
""" """
Performs required actions for when the highcouncil is elected. Performs required actions for when the highcouncil is elected.
@@ -320,6 +337,12 @@ class ElectionCycle:
info.HighCouncilVoteMsgId = vote_msg.id info.HighCouncilVoteMsgId = vote_msg.id
session.commit() session.commit()
# remove highcouncil nomination view
nomination_msg: nextcord.Message = await election_thread.fetch_message(
info.HighCouncilNominationMsgId
)
await nomination_msg.edit(view=None)
async def term_start_action(self) -> None: async def term_start_action(self) -> None:
""" """
Marks the election as over. Marks the election as over.
@@ -364,8 +387,14 @@ class ElectionCycle:
stmt = select(Votes.VotedForId).where(Votes.ElectionCycle == cl_election) stmt = select(Votes.VotedForId).where(Votes.ElectionCycle == cl_election)
cl_votes = collections.Counter(session.scalars(stmt)) cl_votes = collections.Counter(session.scalars(stmt))
dm_winner = max(dm_votes, key=dm_votes.get) try:
cl_winner = max(cl_votes, key=cl_votes.get) dm_winner = max(dm_votes, key=dm_votes.get)
except ValueError:
dm_winner = "No winner"
try:
cl_winner = max(cl_votes, key=cl_votes.get)
except ValueError:
cl_winner = "No winner"
election_thread: nextcord.Thread = self.guild.get_thread( election_thread: nextcord.Thread = self.guild.get_thread(
self.get_election_info().ThreadId self.get_election_info().ThreadId
+3 -1
View File
@@ -4,6 +4,7 @@ Cog loader. Adds all command cogs to the bot.
from nextcord.ext import commands from nextcord.ext import commands
from cogs.commands.remove import RemoveCog
from cogs.commands.request import RequestCog from cogs.commands.request import RequestCog
from cogs.commands.set import setCog from cogs.commands.set import setCog
from cogs.commands.test import TestCog from cogs.commands.test import TestCog
@@ -17,7 +18,8 @@ def setup(bot: commands.Bot):
Adds all command classes to bot. Adds all command classes to bot.
""" """
bot.add_cog(RemoveCog())
bot.add_cog(RequestCog(bot)) bot.add_cog(RequestCog(bot))
bot.add_cog(TestCog(bot)) bot.add_cog(TestCog(bot))
bot.add_cog(setCog())
bot.add_cog(ViewCog()) bot.add_cog(ViewCog())
bot.add_cog(setCog())
+86
View File
@@ -0,0 +1,86 @@
"""
Commands for removing information in the database.
"""
import nextcord
from nextcord.ext import commands
from sqlalchemy import delete, select
from sqlalchemy.orm import Session
from database_setup.sql_data_classes import Presences, engine
class RemoveCog(commands.Cog, name="Remove Commands"):
"""
Holds the view commands.
"""
def __init__(self) -> None:
"""
Default constructor for RemoveCog class. Does nothing.
"""
@nextcord.slash_command(
default_member_permissions=nextcord.Permissions(administrator=True),
)
async def remove(self, interaction: nextcord.Interaction):
"""
Parent slash command for set. Never called.
"""
@remove.subcommand(description="Remove a presence from the database.")
async def presence(
self,
interaction: nextcord.Interaction,
presence_str: str = nextcord.SlashOption(
description="The presence to remove", required=True
),
):
"""
Deletes the given presence id from the database.
Args:
interaction (nextcord.Interaction): Interaction that invoked the command.
presence (str): Is SlashOption. The presence to remove. Is the ID of the presence.
"""
presence_id = int(presence_str)
with Session(engine) as session:
stmt = delete(Presences).where(Presences.Id == presence_id)
session.execute(stmt)
session.commit()
await interaction.response.send_message("Presence deleted.", ephemeral=True)
@presence.on_autocomplete("presence_str")
async def presence_autocomplete(
self, interaction: nextcord.Interaction, presence_str: str
):
"""
Collects all presences that start with the presence string.
Sends autocomplete dict {Presence Name, Presence Id}
Args:
interaction (nextcord.Interaction): Interaction with command.
presence_str (str): String to run autocomplete on.
"""
with Session(engine) as session:
stmt = select(Presences)
presences_dict: "dict[str,str]" = {
pres.Presence: str(pres.Id) for pres in session.scalars(stmt)
}
# if empty compare string
if not presence_str:
await interaction.response.send_autocomplete(
dict(list(presences_dict.items())[:25])
)
return
autofilled_presences: "dict[str,str]" = {
pres: pres_id
for pres, pres_id in presences_dict.items()
if presence_str.lower() in pres.lower()
}
await interaction.response.send_autocomplete(autofilled_presences[:25])
+108 -9
View File
@@ -4,8 +4,10 @@ Contains commands and views for request commands.
import nextcord import nextcord
from nextcord.ext import commands from nextcord.ext import commands
from sqlalchemy.orm import Session
from config import DakinyConfig from config import DakinyConfig
from database_setup.sql_data_classes import Presences, engine
class RequestCog(commands.Cog, name="Request Commands"): class RequestCog(commands.Cog, name="Request Commands"):
@@ -25,12 +27,46 @@ class RequestCog(commands.Cog, name="Request Commands"):
Parent slash command for help. Never called. Parent slash command for help. Never called.
""" """
@request.subcommand(
description="Request to add a presence to the bot's presence list."
)
async def add_presence(
self,
interaction: nextcord.Interaction,
presence: str = nextcord.SlashOption(
required=True,
min_length=1,
max_length=100,
description="The presence you want to add.",
),
):
"""
Sends a message to admins to request to add a presence.
Args:
interaction (nextcord.Interaction): Interaction that invoked the command.
presence (str): The presence to add.
"""
config: DakinyConfig = self.bot.config
content = f'<@{interaction.user.id}> would like to add presence "{presence}."'
view = PresenceChange(presence)
await self.bot.get_channel(config.params.admin_channel_id).send(
content=content, view=view
)
await interaction.response.send_message(
"Request sent to admins.", ephemeral=True
)
@request.subcommand(description="Request to change your Dakiny nickname") @request.subcommand(description="Request to change your Dakiny nickname")
async def change_nickname( async def change_nickname(
self, self,
interaction: nextcord.Interaction, interaction: nextcord.Interaction,
new_nickname: str = nextcord.SlashOption( new_nickname: str = nextcord.SlashOption(
required=True, min_length=2, max_length=32, description="Your requested new nickname." required=True,
min_length=2,
max_length=32,
description="Your requested new nickname.",
), ),
): ):
""" """
@@ -44,8 +80,12 @@ class RequestCog(commands.Cog, name="Request Commands"):
config: DakinyConfig = self.bot.config config: DakinyConfig = self.bot.config
content = f'<@{interaction.user.id}> would like to change their username to "{new_nickname}."' content = f'<@{interaction.user.id}> would like to change their username to "{new_nickname}."'
view = UsernameRequest(interaction.user.id, new_nickname) view = UsernameRequest(interaction.user.id, new_nickname)
await self.bot.get_channel(config.params.admin_channel_id).send(content=content, view=view) await self.bot.get_channel(config.params.admin_channel_id).send(
await interaction.response.send_message("Request sent to admins.", ephemeral=True) content=content, view=view
)
await interaction.response.send_message(
"Request sent to admins.", ephemeral=True
)
class UsernameRequest(nextcord.ui.View): class UsernameRequest(nextcord.ui.View):
@@ -53,13 +93,19 @@ class UsernameRequest(nextcord.ui.View):
View provides approve and deny buttons and action for a username change request. View provides approve and deny buttons and action for a username change request.
""" """
def __init__(self, user_id: int, new_nickname: str, *, timeout: float | None = 180, auto_defer: bool = True): def __init__(
super().__init__(timeout=timeout, auto_defer=auto_defer) self,
user_id: int,
new_nickname: str,
):
super().__init__(timeout=None, auto_defer=True)
self.user_id = user_id self.user_id = user_id
self.new_nickname = new_nickname self.new_nickname = new_nickname
@nextcord.ui.button(label="Approve", style=nextcord.ButtonStyle.green) @nextcord.ui.button(label="Approve", style=nextcord.ButtonStyle.green)
async def approve(self, button: nextcord.ui.Button, interaction: nextcord.Interaction): async def approve(
self, button: nextcord.ui.Button, interaction: nextcord.Interaction
):
""" """
Approve button for a nickname change request. Changes the target's nickname to self.new_nickname. Approve button for a nickname change request. Changes the target's nickname to self.new_nickname.
Catches an error if the target as a higher role than the bot. Catches an error if the target as a higher role than the bot.
@@ -73,7 +119,10 @@ class UsernameRequest(nextcord.ui.View):
if user is not None: if user is not None:
try: try:
await user.edit(nick=self.new_nickname) await user.edit(nick=self.new_nickname)
content = interaction.message.content + f"\nApproved by <@{interaction.user.id}>." content = (
interaction.message.content
+ f"\nApproved by <@{interaction.user.id}>."
)
await interaction.response.edit_message(content=content, view=None) await interaction.response.edit_message(content=content, view=None)
except nextcord.errors.Forbidden: except nextcord.errors.Forbidden:
await interaction.response.send_message( await interaction.response.send_message(
@@ -84,10 +133,13 @@ class UsernameRequest(nextcord.ui.View):
interaction.message.content interaction.message.content
+ "\n\nFailed. User has too high permissions for bot to change nickname." + "\n\nFailed. User has too high permissions for bot to change nickname."
) )
await interaction.followup.edit_message(interaction.message.id, content=content, view=None) await interaction.followup.edit_message(
interaction.message.id, content=content, view=None
)
else: else:
await interaction.response.edit_message( await interaction.response.edit_message(
content="An error occured while changing the user's nickname.", view=None content="An error occured while changing the user's nickname.",
view=None,
) )
@nextcord.ui.button(label="Deny", style=nextcord.ButtonStyle.red) @nextcord.ui.button(label="Deny", style=nextcord.ButtonStyle.red)
@@ -101,3 +153,50 @@ class UsernameRequest(nextcord.ui.View):
""" """
content = interaction.message.content + f"\nDenied by <@{interaction.user.id}>." content = interaction.message.content + f"\nDenied by <@{interaction.user.id}>."
await interaction.response.edit_message(content=content, view=None) await interaction.response.edit_message(content=content, view=None)
class PresenceChange(nextcord.ui.View):
"""
View provides approve and deny buttons and action for a username change request.
"""
def __init__(
self,
presence: str,
):
super().__init__(timeout=None, auto_defer=True)
self.presence = presence
@nextcord.ui.button(label="Approve", style=nextcord.ButtonStyle.green)
async def approve(
self, button: nextcord.ui.Button, interaction: nextcord.Interaction
):
"""
Approve button for a presence add request. Adds the presence to the database.
Removes the view from the interaction message.
Args:
button (nextcord.ui.Button): Unused.
interaction (nextcord.Interaction): The interaction of the user clicking the button.
"""
with Session(engine) as session:
session.add(Presences(Presence=self.presence))
session.commit()
content = (
interaction.message.content + f"\nApproved by <@{interaction.user.id}>."
)
await interaction.response.edit_message(content=content, view=None)
@nextcord.ui.button(label="Deny", style=nextcord.ButtonStyle.red)
async def deny(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
"""
Deny button for a presence add request. Just removes the view and logs who denied the request.
Args:
button (nextcord.ui.Button): Unused.
interaction (nextcord.Interaction): The interaction of the user clicking the button.
"""
content = interaction.message.content + f"\nDenied by <@{interaction.user.id}>."
await interaction.response.edit_message(content=content, view=None)
+43 -2
View File
@@ -7,7 +7,12 @@ from nextcord.ext import commands
from sqlalchemy import select from sqlalchemy import select
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from database_setup.sql_data_classes import ElectionInformation, Votes, engine from database_setup.sql_data_classes import (
ElectionInformation,
Presences,
Votes,
engine,
)
class ViewCog(commands.Cog, name="View Commands"): class ViewCog(commands.Cog, name="View Commands"):
@@ -26,6 +31,42 @@ class ViewCog(commands.Cog, name="View Commands"):
Parent slash command for set. Never called. Parent slash command for set. Never called.
""" """
@view.subcommand(description="Show all possible presence choices.")
async def presences(
self,
interaction: nextcord.Interaction,
search: str = nextcord.SlashOption(
description="A word or string to search for in the presences.",
required=False,
),
):
"""
Gathers all presences from the database and responds with a message showing them.
Args:
interaction (nextcord.Integration): User's interaction with the command.
"""
# might take a while depending on number of presences
await interaction.response.defer(ephemeral=True)
with Session(engine) as session:
stmt = select(Presences.Presence)
presences = session.scalars(stmt)
if search:
message = "\n".join(
[
presence
for presence in presences
if search.lower() in presence.lower()
]
)
else:
message = "\n".join(list(presences))
await interaction.followup.send(content=message, ephemeral=True)
@view.subcommand( @view.subcommand(
description="Shows all voters and who they voted for in a given election." description="Shows all voters and who they voted for in a given election."
) )
@@ -85,7 +126,7 @@ class ViewCog(commands.Cog, name="View Commands"):
# if empty compare string # if empty compare string
if not election_name: if not election_name:
await interaction.response.send_autocomplete(elections) await interaction.response.send_autocomplete(list(elections)[:25])
return return
autofilled_elections: "list[str]" = [ autofilled_elections: "list[str]" = [
+3 -1
View File
@@ -4,7 +4,8 @@ Initializing code for all loops.
from nextcord.ext import commands from nextcord.ext import commands
from .daily_loop import DailyLoop from cogs.loops.bot_presence import BotPresence
from cogs.loops.daily_loop import DailyLoop
def setup(bot: commands.Bot): def setup(bot: commands.Bot):
@@ -12,4 +13,5 @@ def setup(bot: commands.Bot):
Adds functions to bot. Adds functions to bot.
""" """
bot.add_cog(BotPresence(bot))
bot.add_cog(DailyLoop(bot)) bot.add_cog(DailyLoop(bot))
+48
View File
@@ -0,0 +1,48 @@
"""
Functions for controlling the bot's presence. Also contains the loop.
"""
import nextcord
from nextcord.ext import commands, tasks
from sqlalchemy import func, select
from sqlalchemy.orm import Session
from database_setup.sql_data_classes import Presences, engine
class BotPresence(commands.Cog, name="Bot Presence"):
"""Class for bot presence functions."""
def __init__(self, bot: commands.Bot):
self.bot = bot
@commands.Cog.listener()
async def on_guild_join(
self, guild: nextcord.Guild
): # pylint: disable=unused-argument
"""Listener for Guild Join. Updated presence on guild join."""
await self.change_presence()
@commands.Cog.listener()
async def on_ready(self):
"""Starts the loop when bot is ready."""
await self.bot.wait_until_ready()
# pylint doesn't recognize that periodic_change_presense is subclassed from tasks.loop.
self.periodic_change_presence.start() # pylint: disable=no-member
@tasks.loop(minutes=5)
async def periodic_change_presence(self):
"""Loops every 5 minutes and changes presence."""
await self.change_presence()
async def change_presence(self):
"""Randomly chooses a presence and updates bot's presence."""
with Session(engine) as session:
presence = session.scalar(
select(Presences.Presence).order_by(func.random())
)
await self.bot.change_presence(
activity=nextcord.CustomActivity(name="Custom Status", state=presence)
)
+7
View File
@@ -3,6 +3,8 @@ CREATE TABLE ElectionInformation(
ThreadId bigint unsigned not null, ThreadId bigint unsigned not null,
CouncilVoteMsgId bigint unsigned, CouncilVoteMsgId bigint unsigned,
HighCouncilVoteMsgId bigint unsigned, HighCouncilVoteMsgId bigint unsigned,
CouncilNominationMsgId bigint unsigned,
HighCouncilNominationMsgId bigint unsigned,
PRIMARY KEY (ElectionCycle) PRIMARY KEY (ElectionCycle)
); );
@@ -31,4 +33,9 @@ CREATE TABLE UserBirthday (
UserId bigint unsigned not null, UserId bigint unsigned not null,
Birthday varchar(5) not null, Birthday varchar(5) not null,
PRIMARY KEY (UserId) PRIMARY KEY (UserId)
);
CREATE TABLE Presences (
Id integer PRIMARY KEY,
Presence varchar(100) not null
); );
+1
View File
@@ -15,3 +15,4 @@ ElectionInformation = Base.classes.ElectionInformation
CouncilMembers = Base.classes.CouncilMembers CouncilMembers = Base.classes.CouncilMembers
Votes = Base.classes.Votes Votes = Base.classes.Votes
UserBirthday = Base.classes.UserBirthday UserBirthday = Base.classes.UserBirthday
Presences = Base.classes.Presences
+6 -3
View File
@@ -28,9 +28,12 @@ def get_datetime(day: str) -> datetime:
day = int(day.split("/")[1]) day = int(day.split("/")[1])
# ensure that year rolls over if current month is December and the next month is less than 12. # ensure that year rolls over if current month is December and the next month is less than 12.
if datetime.today().month == 12 & month < 12: if datetime.today().month == 12 and month < 12:
year += 1 year += 1
if datetime.today().month == 1 and month > 1:
year -= 1
return datetime(year, month, day) return datetime(year, month, day)
@@ -88,7 +91,7 @@ def get_current_cycle(config: DakinyConfig) -> int:
config (DakinyConfig): Config object to use config (DakinyConfig): Config object to use
Returns: Returns:
int: cycle index for active election. -1 for no active cycle int: cycle index for active election. None for no active cycle
""" """
today = datetime.today() today = datetime.today()
@@ -100,7 +103,7 @@ def get_current_cycle(config: DakinyConfig) -> int:
): ):
return cycle return cycle
return -1 return None
def build_votes_str(config: DakinyConfig) -> str: def build_votes_str(config: DakinyConfig) -> str: