Fix ruff smells in classes dir and config.py.

This commit is contained in:
2024-05-22 16:58:27 -04:00
parent e485c119f6
commit 6cd82dfcc4
6 changed files with 81 additions and 88 deletions
+19 -26
View File
@@ -1,9 +1,8 @@
"""
Contains the election cycle class
"""
"""Contains the election cycle class."""
import collections
from datetime import UTC, datetime, timedelta
from pathlib import Path
import nextcord
from classes.nominate_highcouncil_views import NominateHighCouncilView
@@ -29,9 +28,13 @@ from utils import (
get_election_name,
)
REQUIRED_VOTES_TO_BE_ELECTED = 3
class ElectionCycle:
"""
ElectionCycle class.
This class represents all the dates required for an election cycle along with all the functions needed to operate
the cycle.
"""
@@ -67,7 +70,7 @@ class ElectionCycle:
list[str]: A list of message contents in the correct order. Must be a string because the message is too
long.
"""
with open(f"{TEMPLATES_DIR}/election_announcement.txt", encoding="utf8") as file:
with Path(f"{TEMPLATES_DIR}/election_announcement.txt", encoding="utf8").open() as file:
message = file.read()
next_election = get_datetime(
@@ -95,7 +98,7 @@ class ElectionCycle:
Returns:
str: Message to send.
"""
with open(f"{TEMPLATES_DIR}/highcouncil_election.txt", encoding="utf8") as file:
with Path(f"{TEMPLATES_DIR}/highcouncil_election.txt", encoding="utf8").open() as file:
message = file.read()
return message.format(
@@ -113,7 +116,7 @@ class ElectionCycle:
Returns:
str: Message to send.
"""
with open(f"{TEMPLATES_DIR}/highcouncil_vote.txt", encoding="utf8") as file:
with Path(f"{TEMPLATES_DIR}/highcouncil_vote.txt", encoding="utf8").open() as file:
message = file.read()
return message.format(
@@ -128,7 +131,7 @@ class ElectionCycle:
Returns:
str: Message to send
"""
with open(f"{TEMPLATES_DIR}/vote_start.txt", encoding="utf8") as file:
with Path(f"{TEMPLATES_DIR}/vote_start.txt", encoding="utf8").open() as file:
message = file.read()
vote_end: datetime = get_datetime(self.config.election_cycles[self.cycle].voting_end)
@@ -139,9 +142,7 @@ class ElectionCycle:
)
async def check_date(self) -> None:
"""
Function checks current date to see if something needs to be run.
"""
"""Function checks current date to see if something needs to be run."""
today = datetime.now(tz=UTC).date()
# check all dates if action is needed
@@ -159,9 +160,7 @@ class ElectionCycle:
await self.term_start_action()
async def election_start_action(self) -> None:
"""
Performs required actions for when the election cycle starts.
"""
"""Performs required actions for when the election cycle starts."""
# create new channel for election
parent: nextcord.TextChannel = self.guild.get_channel(self.config.params.voting_parent_id)
quarter_name: str = get_election_name(self.config)
@@ -193,6 +192,8 @@ class ElectionCycle:
async def voting_start_action(self) -> None:
"""
Actions performed when starting a vote.
Sends message informing members that voting has started.
Removes write permission from the general clan member role.
"""
@@ -217,9 +218,7 @@ class ElectionCycle:
await nominate_msg.edit(view=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."""
message = self.build_highcouncil_election_announce()
council_elect_role: nextcord.Role = self.guild.get_role(self.config.params.clan_council_elect_role_id)
election_thread: nextcord.Thread = self.guild.get_thread(self.get_election_info().ThreadId)
@@ -250,7 +249,7 @@ class ElectionCycle:
vote_count = collections.Counter(session.scalars(stmt))
for user_id, votes in vote_count.items():
if votes >= 3:
if votes >= REQUIRED_VOTES_TO_BE_ELECTED:
stmt = (
select(CouncilMembers)
.where(CouncilMembers.ElectionCycle == election_name)
@@ -268,9 +267,7 @@ class ElectionCycle:
)
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."""
message = self.build_highcouncil_vote_start()
election_thread: nextcord.Thread = self.guild.get_thread(self.get_election_info().ThreadId)
await election_thread.send(message)
@@ -292,9 +289,7 @@ class ElectionCycle:
await nomination_msg.edit(view=None)
async def term_start_action(self) -> None:
"""
Marks the election as over.
"""
"""Marks the election as over."""
self.election_over = True
elect_role: nextcord.Role = self.guild.get_role(self.config.params.clan_council_elect_role_id)
@@ -394,9 +389,7 @@ class ElectionCycle:
return session.scalar(stmt)
async def election_reminder(self) -> None:
"""
Sends a message to general chat reminder clan about election.
"""
"""Sends a message to general chat reminder clan about election."""
general: nextcord.TextChannel = self.guild.get_channel(self.config.params.general_channel_id)
message = f"Reminder to <@&{self.config.params.clan_member_role_id}>! Clan elections are happening! Head over "
+18 -15
View File
@@ -1,14 +1,11 @@
"""
Contains various views to be used in the high council nomination process.
"""
"""Contains various views to be used in the high council nomination process."""
import nextcord
from config import DakinyConfig
from database_setup.sql_data_classes import CouncilMembers, engine
from nextcord.interactions import Interaction
from sqlalchemy import select
from sqlalchemy.orm import Session
from config import DakinyConfig
from database_setup.sql_data_classes import CouncilMembers, engine
from utils import (
NOMINEE_SPLITTER,
decorate_cl_nomination,
@@ -19,14 +16,16 @@ from utils import (
class NominateDMModal(nextcord.ui.Modal):
"""
Modal for nominating oneself. User writes a speech and then the callback sends the speech into the correct channel.
Modal for nominating oneself.
User writes a speech and then the callback sends the speech into the correct channel.
"""
def __init__(
self,
config: DakinyConfig,
usr_id: int,
usr_nominated: bool,
usr_nominated: bool, # noqa: FBT001
speech_content: str,
):
super().__init__(
@@ -79,14 +78,16 @@ class NominateDMModal(nextcord.ui.Modal):
class NominateCLModal(nextcord.ui.Modal):
"""
Modal for nominating oneself. User writes a speech and then the callback sends the speech into the correct channel.
Modal for nominating oneself.
User writes a speech and then the callback sends the speech into the correct channel.
"""
def __init__(
self,
config: DakinyConfig,
usr_id: int,
usr_nominated: bool,
usr_nominated: bool, # noqa: FBT001
speech_content: str,
):
super().__init__(
@@ -138,9 +139,7 @@ class NominateCLModal(nextcord.ui.Modal):
class NominateHighCouncilView(nextcord.ui.View):
"""
The buttons to press to start your High Council nomination.
"""
"""The buttons to press to start your High Council nomination."""
def __init__(self, config: DakinyConfig, guild: nextcord.Guild):
super().__init__(timeout=None)
@@ -152,8 +151,10 @@ class NominateHighCouncilView(nextcord.ui.View):
style=nextcord.ButtonStyle.primary,
custom_id="nominate-dm",
)
async def nominate_dm(self, button: nextcord.ui.Button, interaction: nextcord.Interaction) -> None:
async def nominate_dm(self, button: nextcord.ui.Button, interaction: nextcord.Interaction) -> None: # noqa: ARG002
"""
Button for nominating oneself for Discord Manager.
Gathers previous information about the user if they have already nominated themselves, then launches
the nomination modal to get their speech.
@@ -195,8 +196,10 @@ class NominateHighCouncilView(nextcord.ui.View):
style=nextcord.ButtonStyle.primary,
custom_id="nominate-cl",
)
async def nominate_cl(self, button: nextcord.ui.Button, interaction: nextcord.Interaction) -> None:
async def nominate_cl(self, button: nextcord.ui.Button, interaction: nextcord.Interaction) -> None: # noqa: ARG002
"""
Button for nominating oneself for Clan Leader.
Gathers previous information about the user if they have already nominated themselves, then launches
the nomination modal to get their speech.
+11 -12
View File
@@ -1,27 +1,26 @@
"""
Contains various views to be used in the nomination process.
"""
"""Contains various views to be used in the nomination process."""
import nextcord
from config import DakinyConfig
from database_setup.sql_data_classes import CouncilMembers, engine
from nextcord.interactions import Interaction
from sqlalchemy import select
from sqlalchemy.orm import Session
from config import DakinyConfig
from database_setup.sql_data_classes import CouncilMembers, engine
from utils import NOMINEE_SPLITTER, decorate_nomination, get_election_name
class NominateModal(nextcord.ui.Modal):
"""
Modal for nominating oneself. User writes a speech and then the callback sends the speech into the correct channel.
Modal for nominating oneself.
User writes a speech and then the callback sends the speech into the correct channel.
"""
def __init__(
self,
config: DakinyConfig,
usr_id: int,
usr_nominated: bool,
usr_nominated: bool, # noqa: FBT001
speech_content: str,
):
super().__init__(
@@ -78,9 +77,7 @@ class NominateModal(nextcord.ui.Modal):
class NominateView(nextcord.ui.View):
"""
The button to press to start your nomination.
"""
"""The button to press to start your nomination."""
def __init__(self, config: DakinyConfig, guild: nextcord.Guild):
super().__init__(timeout=None)
@@ -92,8 +89,10 @@ class NominateView(nextcord.ui.View):
style=nextcord.ButtonStyle.primary,
custom_id="nominate",
)
async def nominate(self, button: nextcord.ui.Button, interaction: nextcord.Interaction) -> None:
async def nominate(self, button: nextcord.ui.Button, interaction: nextcord.Interaction) -> None: # noqa: ARG002
"""
Button to nominate onself for Clan Council.
Gathers previous information about the user if they have already nominated themselves, then launches
the nomination modal to get their speech.
+3
View File
@@ -2,6 +2,9 @@
# Extend the `pyproject.toml` file in the parent directory...
extend = "../pyproject.toml"
# Exclude a variety of commonly ignored directories.
exclude = ["gitea_webhook.py"]
[tool.ruff.lint]
# ignore implicit-namespace-package in this directory.
ignore = ["INP001"]
+26 -23
View File
@@ -1,14 +1,6 @@
"""
Contains various views to be used while voting for high council. Controls the logic when performing the vote.
"""
"""Contains various views to be used while voting for high council. Controls the logic when performing the vote."""
import nextcord
from nextcord import SelectOption
from nextcord.interactions import Interaction
from sqlalchemy import exc, select, update
from sqlalchemy.orm import Session
from config import DakinyConfig
from database_setup.sql_data_classes import (
CouncilMembers,
@@ -16,10 +8,16 @@ from database_setup.sql_data_classes import (
Votes,
engine,
)
from nextcord import SelectOption
from nextcord.interactions import Interaction
from sqlalchemy import exc, select, update
from sqlalchemy.orm import Session
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:
super().__init__(
placeholder="Choose 1",
@@ -30,7 +28,16 @@ class VoteSelect(nextcord.ui.StringSelect):
self.config = config
self.election_type = election_type
async def callback(self, interaction: Interaction):
async def callback(self, interaction: Interaction) -> None:
"""
Callback override for the StringSelect.
Submits the High Council vote to database if a user is selected. Handles adding vs editing a vote.
Returns message informing user that vote has been recorded.
Args:
interaction (Interaction): Interaction with this callback.
"""
election_name: str = get_election_name(self.config)
with Session(engine) as session:
stmt = select(ElectionInformation.HighCouncilVoteMsgId).where(
@@ -38,10 +45,7 @@ class VoteSelect(nextcord.ui.StringSelect):
)
vote_msg_id = session.scalar(stmt)
if self.values[0] == "Abstain":
voted_for = None
else:
voted_for = int(self.values[0])
voted_for = None if self.values[0] == "Abstain" else int(self.values[0])
new_vote = Votes(
ElectionCycle=election_name,
@@ -71,18 +75,13 @@ class VoteSelect(nextcord.ui.StringSelect):
vote_msg: nextcord.Message = await interaction.channel.fetch_message(vote_msg_id)
await vote_msg.edit(content=vote_message_str)
if voted_for is not None:
msg = f"You have voted for <@{voted_for}>"
else:
msg = "You have abstained from voting."
msg = f"You have voted for <@{voted_for}>" if voted_for is not None else "You have abstained from voting."
await interaction.edit(content=msg, view=None)
class VoteHighcouncilView(nextcord.ui.View):
"""
The button to press to start voting for HighCouncil.
"""
"""The button to press to start voting for HighCouncil."""
def __init__(self, config: DakinyConfig, guild: nextcord.Guild):
super().__init__(timeout=None)
@@ -94,8 +93,10 @@ class VoteHighcouncilView(nextcord.ui.View):
style=nextcord.ButtonStyle.primary,
custom_id="vote-cl",
)
async def vote_cl(self, button: nextcord.ui.Button, interaction: nextcord.Interaction) -> None:
async def vote_cl(self, button: nextcord.ui.Button, interaction: nextcord.Interaction) -> None: # noqa: ARG002
"""
Button to vote for Clan Leader.
Enforces only council elect vote. Gets election cycle, creates voting
options for clan leader (checking if user has voted already),
then sends the voting view.
@@ -164,8 +165,10 @@ class VoteHighcouncilView(nextcord.ui.View):
style=nextcord.ButtonStyle.primary,
custom_id="vote-dm",
)
async def vote_dm(self, button: nextcord.ui.Button, interaction: nextcord.Interaction) -> None:
async def vote_dm(self, button: nextcord.ui.Button, interaction: nextcord.Interaction) -> None: # noqa: ARG002
"""
Button to vote for Discord Manager.
Enforces only council elect vote. Gets election cycle, creates voting
options for discord manager (checking if user has voted already),
then sends the voting view.
+4 -12
View File
@@ -1,15 +1,11 @@
"""
File contains classes defining the Hydra configuraton structure.
"""
"""File contains classes defining the Hydra configuraton structure."""
from dataclasses import dataclass
@dataclass
class Params:
"""
Class defines the various configuration parameters.
"""
"""Class defines the various configuration parameters."""
admin_channel_id: int # might want to rename this...
announcement_category_id: int
@@ -32,9 +28,7 @@ class Params:
@dataclass
class ElectionCycle:
"""
Class defines relevant election dates.
"""
"""Class defines relevant election dates."""
election_start: str
highcouncil_election_announce: str
@@ -49,9 +43,7 @@ class ElectionCycle:
@dataclass
class DakinyConfig:
"""
Class defines all configs required for Dakiny Bot.
"""
"""Class defines all configs required for Dakiny Bot."""
election_cycles: list[ElectionCycle]
params: Params