diff --git a/DakinyConfig.py b/DakinySettings.py similarity index 65% rename from DakinyConfig.py rename to DakinySettings.py index f67e26c..42465e3 100644 --- a/DakinyConfig.py +++ b/DakinySettings.py @@ -1,11 +1,15 @@ -"""File contains classes defining the Hydra configuration structure.""" +"""File contains classes defining Dakiny settings structure.""" from dataclasses import dataclass +from dataclass_wizard import YAMLWizard + +CONFIG_LOCATION = "conf/config.yaml" + @dataclass -class Params: - """Class defines the various configuration parameters.""" +class Settings: + """Class defines settings editable by Clan Council.""" admin_channel_id: int # might want to rename this... announcement_category_id: int @@ -13,28 +17,34 @@ class Params: clan_council_role_id: int clan_info_channel_id: int clan_member_role_id: int - discord_token: str event_host_points: int event_host_role_id: int event_participate_points: int event_points_weekly_limit: int event_post_channel_id: int general_channel_id: int - git_branch: str - guild_id: int high_council_role_id: int voting_parent_id: int +@dataclass +class Params: + """Class defines start parameters that shouldn't be changed.""" + + discord_token: str + git_branch: str + guild_id: int + + @dataclass class Election: """Class defines relevant election dates.""" + name: str election_start: str highcouncil_election_announce: str highcouncil_election_end: str highcouncil_election_start: str - name: str term_end: str term_start: str voting_end: str @@ -42,8 +52,16 @@ class Election: @dataclass -class DakinyConfig: +class DakinySettings(YAMLWizard): """Class defines all configs required for Dakiny Bot.""" election_cycles: list[Election] params: Params + settings: Settings + + def save(self) -> None: + """Saves settings to the yaml file.""" + self.to_yaml_file(CONFIG_LOCATION) + + +settings = DakinySettings.from_yaml_file(CONFIG_LOCATION) diff --git a/classes/election.py b/classes/election.py index b21c33f..9b50c70 100644 --- a/classes/election.py +++ b/classes/election.py @@ -9,7 +9,7 @@ from classes.nominate_highcouncil_views import NominateHighCouncilView from classes.nominate_views import NominateView from classes.voting_highcouncil_views import VoteHighcouncilView from classes.voting_views import VoteView -from DakinyConfig import DakinyConfig +from DakinySettings import DakinySettings from database_setup.sql_data_classes import ( CouncilMembers, ElectionInformation, @@ -39,7 +39,7 @@ class Election: the cycle. """ - def __init__(self, cycle: int, config: DakinyConfig, guild: nextcord.Guild) -> None: + def __init__(self, cycle: int, config: DakinySettings, guild: nextcord.Guild) -> None: """ Generates all dates relevant to the election cycle determined by the config and cycle. @@ -48,7 +48,7 @@ class Election: config (DakinyConfig): The entire config object. guild (nextcord.Guild): The guild that this election is running in. """ - self.config: DakinyConfig = config + self.config: DakinySettings = config self.cycle = cycle self.election_cycle = self.config.election_cycles[self.cycle] self.election_start: datetime = get_datetime(self.election_cycle.election_start) diff --git a/classes/nominate_highcouncil_views.py b/classes/nominate_highcouncil_views.py index b007643..1931a68 100644 --- a/classes/nominate_highcouncil_views.py +++ b/classes/nominate_highcouncil_views.py @@ -1,7 +1,7 @@ """Contains various views to be used in the high council nomination process.""" import nextcord -from DakinyConfig import DakinyConfig +from DakinySettings import DakinySettings from database_setup.sql_data_classes import CouncilMembers, engine from nextcord.interactions import Interaction from sqlalchemy import select @@ -23,7 +23,7 @@ class NominateDMModal(nextcord.ui.Modal): def __init__( self, - config: DakinyConfig, + config: DakinySettings, usr_id: int, usr_nominated: bool, # noqa: FBT001 speech_content: str, @@ -33,7 +33,7 @@ class NominateDMModal(nextcord.ui.Modal): timeout=5 * 60, # 5 minutes ) self.usr_id: int = usr_id - self.config: DakinyConfig = config + self.config: DakinySettings = config self.usr_nominated = usr_nominated self.speech = nextcord.ui.TextInput( @@ -85,7 +85,7 @@ class NominateCLModal(nextcord.ui.Modal): def __init__( self, - config: DakinyConfig, + config: DakinySettings, usr_id: int, usr_nominated: bool, # noqa: FBT001 speech_content: str, @@ -95,7 +95,7 @@ class NominateCLModal(nextcord.ui.Modal): timeout=5 * 60, # 5 minutes ) self.usr_id: int = usr_id - self.config: DakinyConfig = config + self.config: DakinySettings = config self.usr_nominated = usr_nominated self.speech = nextcord.ui.TextInput( @@ -141,9 +141,9 @@ class NominateCLModal(nextcord.ui.Modal): class NominateHighCouncilView(nextcord.ui.View): """The buttons to press to start your High Council nomination.""" - def __init__(self, config: DakinyConfig, guild: nextcord.Guild): + def __init__(self, config: DakinySettings, guild: nextcord.Guild): super().__init__(timeout=None) - self.config: DakinyConfig = config + self.config: DakinySettings = config self.guild: nextcord.Guild = guild @nextcord.ui.button( diff --git a/classes/nominate_views.py b/classes/nominate_views.py index e637332..e7a6a85 100644 --- a/classes/nominate_views.py +++ b/classes/nominate_views.py @@ -1,7 +1,7 @@ """Contains various views to be used in the nomination process.""" import nextcord -from DakinyConfig import DakinyConfig +from DakinySettings import DakinySettings from database_setup.sql_data_classes import CouncilMembers, engine from nextcord.interactions import Interaction from sqlalchemy import select @@ -18,7 +18,7 @@ class NominateModal(nextcord.ui.Modal): def __init__( self, - config: DakinyConfig, + config: DakinySettings, usr_id: int, usr_nominated: bool, # noqa: FBT001 speech_content: str, @@ -28,7 +28,7 @@ class NominateModal(nextcord.ui.Modal): timeout=5 * 60, # 5 minutes ) self.usr_id: int = usr_id - self.config: DakinyConfig = config + self.config: DakinySettings = config self.usr_nominated = usr_nominated self.speech = nextcord.ui.TextInput( @@ -79,9 +79,9 @@ class NominateModal(nextcord.ui.Modal): class NominateView(nextcord.ui.View): """The button to press to start your nomination.""" - def __init__(self, config: DakinyConfig, guild: nextcord.Guild): + def __init__(self, config: DakinySettings, guild: nextcord.Guild): super().__init__(timeout=None) - self.config: DakinyConfig = config + self.config: DakinySettings = config self.guild: nextcord.Guild = guild @nextcord.ui.button( diff --git a/classes/voting_highcouncil_views.py b/classes/voting_highcouncil_views.py index fb8b7ae..9096794 100644 --- a/classes/voting_highcouncil_views.py +++ b/classes/voting_highcouncil_views.py @@ -1,7 +1,7 @@ """Contains various views to be used while voting for high council. Controls the logic when performing the vote.""" import nextcord -from DakinyConfig import DakinyConfig +from DakinySettings import DakinySettings from database_setup.sql_data_classes import ( CouncilMembers, ElectionInformation, @@ -18,7 +18,7 @@ from utils import VoteType, build_highcouncil_votes_str, get_election_name class VoteSelect(nextcord.ui.StringSelect): """Vote view string select.""" - def __init__(self, options: list["SelectOption"], config: DakinyConfig, election_type: str) -> None: + def __init__(self, options: list["SelectOption"], config: DakinySettings, election_type: str) -> None: super().__init__( placeholder="Choose 1", min_values=1, @@ -83,7 +83,7 @@ class VoteSelect(nextcord.ui.StringSelect): class VoteHighcouncilView(nextcord.ui.View): """The button to press to start voting for HighCouncil.""" - def __init__(self, config: DakinyConfig, guild: nextcord.Guild): + def __init__(self, config: DakinySettings, guild: nextcord.Guild): super().__init__(timeout=None) self.config = config self.guild = guild diff --git a/classes/voting_views.py b/classes/voting_views.py index a6c485c..75f54f9 100644 --- a/classes/voting_views.py +++ b/classes/voting_views.py @@ -1,7 +1,7 @@ """Contains various views to be used while voting. Controls the logic when performing the vote.""" import nextcord -from DakinyConfig import DakinyConfig +from DakinySettings import DakinySettings from database_setup.sql_data_classes import ( CouncilMembers, ElectionInformation, @@ -18,7 +18,7 @@ from utils import VoteType, build_votes_str, get_election_name class VoteSelect(nextcord.ui.StringSelect): """Vote view string select.""" - def __init__(self, options: list["SelectOption"], config: DakinyConfig) -> None: + def __init__(self, options: list["SelectOption"], config: DakinySettings) -> None: super().__init__( placeholder="Choose 1", min_values=1, @@ -79,7 +79,7 @@ class VoteSelect(nextcord.ui.StringSelect): class VoteView(nextcord.ui.View): """The button to press to start your nomination.""" - def __init__(self, config: DakinyConfig, guild: nextcord.Guild): + def __init__(self, config: DakinySettings, guild: nextcord.Guild): super().__init__(timeout=None) self.config = config self.guild = guild diff --git a/cogs/clan_messages/__init__.py b/cogs/clan_messages/__init__.py index 937dece..9e6bb22 100644 --- a/cogs/clan_messages/__init__.py +++ b/cogs/clan_messages/__init__.py @@ -14,7 +14,7 @@ from utils import REPO_DIR, edit_clan_council_info, update_clan_messages if TYPE_CHECKING: import nextcord - from DakinyConfig import DakinyConfig + from DakinySettings import DakinySettings app = FastAPI() REPO_URL = "https://gitea.cheezers.org/imcompiling/dakiny-messages.git" @@ -30,7 +30,7 @@ class ClanMessages(commands.Cog, name="Clan Messages"): def __init__(self, bot: commands.Bot): self.bot = bot - self.config: DakinyConfig = self.bot.config + self.config: DakinySettings = self.bot.config self.repo_setup() @commands.Cog.listener() diff --git a/cogs/commands/record.py b/cogs/commands/record.py index d844743..00bcafd 100644 --- a/cogs/commands/record.py +++ b/cogs/commands/record.py @@ -4,7 +4,7 @@ import nextcord from discord import TextInputStyle from nextcord.ext import commands -from DakinyConfig import DakinyConfig +from DakinySettings import DakinySettings from utils import GUILDS, MAX_DISCORD_MESSAGE_LENGTH, record_event_points @@ -155,11 +155,11 @@ class EventView(nextcord.ui.View): Also contains a UserSelect object to pick discord members. """ - def __init__(self, name: str, config: DakinyConfig, host_id: int): + def __init__(self, name: str, config: DakinySettings, host_id: int): super().__init__() self.name: str = name - self.config: DakinyConfig = config + self.config: DakinySettings = config self.host_id: int = host_id self.event_participants = ParticipantSelect() diff --git a/cogs/commands/request.py b/cogs/commands/request.py index 37310d3..4be7acb 100644 --- a/cogs/commands/request.py +++ b/cogs/commands/request.py @@ -9,7 +9,7 @@ from sqlalchemy.orm import Session from database_setup.sql_data_classes import Presences, engine if TYPE_CHECKING: - from DakinyConfig import DakinyConfig + from DakinySettings import DakinySettings class RequestCog(commands.Cog, name="Request Commands"): @@ -41,7 +41,7 @@ class RequestCog(commands.Cog, name="Request Commands"): interaction (nextcord.Interaction): Interaction that invoked the command. presence (str): The presence to add. """ - config: DakinyConfig = self.bot.config + config: DakinySettings = 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) @@ -65,7 +65,7 @@ class RequestCog(commands.Cog, name="Request Commands"): interaction (nextcord.Interaction): Interaction that invoked the command. new_nickname(str): The username to change to. """ - config: DakinyConfig = self.bot.config + config: DakinySettings = self.bot.config content = f'<@{interaction.user.id}> would like to change their username to "{new_nickname}."' view = UsernameRequest(interaction.user.id, new_nickname) await self.bot.get_channel(config.params.admin_channel_id).send(content=content, view=view) diff --git a/cogs/commands/test.py b/cogs/commands/test.py index dfce500..a64de71 100644 --- a/cogs/commands/test.py +++ b/cogs/commands/test.py @@ -9,7 +9,7 @@ from classes.election import Election from utils import GUILDS, get_current_election_cycle if TYPE_CHECKING: - from DakinyConfig import DakinyConfig + from DakinySettings import DakinySettings ME = 206602713511886849 @@ -44,7 +44,7 @@ class TestCog(commands.Cog, name="Test commands."): Args: interaction (nextcord.Interaction): Interaction with the message. """ - config: DakinyConfig = self.bot.config + config: DakinySettings = self.bot.config cycle = Election( get_current_election_cycle(config), config, @@ -62,7 +62,7 @@ class TestCog(commands.Cog, name="Test commands."): Args: interaction (nextcord.Interaction): Interaction with the message. """ - config: DakinyConfig = self.bot.config + config: DakinySettings = self.bot.config cycle = Election( get_current_election_cycle(config), config, @@ -80,7 +80,7 @@ class TestCog(commands.Cog, name="Test commands."): Args: interaction (nextcord.Interaction): Interaction with the message. """ - config: DakinyConfig = self.bot.config + config: DakinySettings = self.bot.config cycle = Election( get_current_election_cycle(config), config, @@ -98,7 +98,7 @@ class TestCog(commands.Cog, name="Test commands."): Args: interaction (nextcord.Interaction): Interaction with the message. """ - config: DakinyConfig = self.bot.config + config: DakinySettings = self.bot.config cycle = Election( get_current_election_cycle(config), config, @@ -116,7 +116,7 @@ class TestCog(commands.Cog, name="Test commands."): Args: interaction (nextcord.Interaction): Interaction with the message. """ - config: DakinyConfig = self.bot.config + config: DakinySettings = self.bot.config cycle = Election( get_current_election_cycle(config), config, @@ -134,7 +134,7 @@ class TestCog(commands.Cog, name="Test commands."): Args: interaction (nextcord.Interaction): Interaction with the message. """ - config: DakinyConfig = self.bot.config + config: DakinySettings = self.bot.config cycle = Election( get_current_election_cycle(config), config, @@ -152,7 +152,7 @@ class TestCog(commands.Cog, name="Test commands."): Args: interaction (nextcord.Interaction): Interaction with the message. """ - config: DakinyConfig = self.bot.config + config: DakinySettings = self.bot.config cycle = Election( get_current_election_cycle(config), config, diff --git a/cogs/loops/daily_loop.py b/cogs/loops/daily_loop.py index a44e72e..91898fb 100644 --- a/cogs/loops/daily_loop.py +++ b/cogs/loops/daily_loop.py @@ -17,7 +17,7 @@ from utils import get_current_election_cycle if TYPE_CHECKING: import nextcord - from DakinyConfig import DakinyConfig + from DakinySettings import DakinySettings KANDY = 239547993106284544 @@ -76,7 +76,7 @@ class DailyLoop(commands.Cog, name="Daily Loop"): Returns: Election: Current election cycle, None if there is no election happening. """ - config: DakinyConfig = self.bot.config + config: DakinySettings = self.bot.config cycle = get_current_election_cycle(config) # prevent exception from using cycle as an Int in an array diff --git a/main.py b/main.py index 469792d..a2ad8c2 100644 --- a/main.py +++ b/main.py @@ -10,7 +10,7 @@ from classes.nominate_highcouncil_views import NominateHighCouncilView from classes.nominate_views import NominateView from classes.voting_highcouncil_views import VoteHighcouncilView from classes.voting_views import VoteView -from DakinyConfig import DakinyConfig +from DakinySettings import DakinySettings from database_setup import create_database birthday_list: list[int] = [] diff --git a/pyproject.toml b/pyproject.toml index 3b9aa6d..4e74b55 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,7 +16,7 @@ pytz = "^2024.1" sqlalchemy = "^2.0.30" aiofiles = "^23.2.1" setuptools = "^70.0.0" -pyyaml = "^6.0.2" +dataclass-wizard = "^0.22.3" [tool.poetry.group.dev.dependencies] diff --git a/utils.py b/utils.py index 455cbfb..f7ab6df 100644 --- a/utils.py +++ b/utils.py @@ -12,7 +12,7 @@ import nextcord from sqlalchemy import select, true, update from sqlalchemy.orm import Session -from DakinyConfig import DakinyConfig +from DakinySettings import DakinySettings from database_setup.sql_data_classes import ( CouncilMembers, EventPoints, @@ -57,7 +57,7 @@ def get_datetime(day: str) -> datetime: return datetime(year, month, day, tzinfo=UTC) -def get_election_name(config: DakinyConfig) -> str: +def get_election_name(config: DakinySettings) -> str: """ Builds the unique name of the current election cycle. @@ -72,7 +72,7 @@ def get_election_name(config: DakinyConfig) -> str: return f"vote-{get_datetime(current_cycle.term_start).year}-{current_cycle.name}" -def get_quarter_name(config: DakinyConfig) -> str: +def get_quarter_name(config: DakinySettings) -> str: """ Builds the name of the current cycle/quarter. @@ -88,7 +88,7 @@ def get_quarter_name(config: DakinyConfig) -> str: return f"{get_datetime(current_cycle.term_start).year}-{current_cycle.name}" -def get_current_election_cycle(config: DakinyConfig) -> int: +def get_current_election_cycle(config: DakinySettings) -> int: """ Returns index for active election. An election is considered active between the election start and the term start. @@ -111,7 +111,7 @@ def get_current_election_cycle(config: DakinyConfig) -> int: return get_quarter_cycle(config) -def get_quarter_cycle(config: DakinyConfig) -> int: +def get_quarter_cycle(config: DakinySettings) -> int: """ Returns the index for the current cycle/quarter. Defined as between term start and end. Shouldn't return none. @@ -132,7 +132,7 @@ def get_quarter_cycle(config: DakinyConfig) -> int: return None -def build_votes_str(config: DakinyConfig, guild: nextcord.Guild) -> str: +def build_votes_str(config: DakinySettings, guild: nextcord.Guild) -> str: """ Creates a string that contains all nominees and their votes to be sent as a discord message. @@ -168,7 +168,7 @@ def build_votes_str(config: DakinyConfig, guild: nextcord.Guild) -> str: return votes_str -def build_highcouncil_votes_str(config: DakinyConfig, guild: nextcord.Guild) -> str: +def build_highcouncil_votes_str(config: DakinySettings, guild: nextcord.Guild) -> str: """ Creates a string that contains all high council nominees and their votes to be sent as a discord message. @@ -302,7 +302,7 @@ def decorate_dm_nomination(user_id: int, speech: str) -> str: return msg -def record_event_points(config: DakinyConfig, users: Sequence[str], add_points: int, *, is_member: bool) -> None: +def record_event_points(config: DakinySettings, users: Sequence[str], add_points: int, *, is_member: bool) -> None: """ Adds event points to all users listed. @@ -502,7 +502,7 @@ async def edit_clan_message( session.commit() -async def edit_clan_council_info(guild: nextcord.Guild, config: DakinyConfig) -> None: +async def edit_clan_council_info(guild: nextcord.Guild, config: DakinySettings) -> None: """ Gets the winners of the elections and updates the permanent message that states the current council.