Compare commits
9
Commits
main
...
af3b8e9e69
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
af3b8e9e69 | ||
|
|
a5655c4d6b | ||
|
|
a277566654 | ||
|
|
6adb98111b | ||
|
|
4d96aebeb1 | ||
|
|
d38f56ff41 | ||
|
|
95fb9e289b | ||
|
|
3bcd1a3a01 | ||
|
|
6c57644eb0 |
+1
-1
@@ -12,7 +12,7 @@ from dakiny_bot.classes.voting_highcouncil_views import VoteHighcouncilView
|
|||||||
from dakiny_bot.classes.voting_views import VoteView
|
from dakiny_bot.classes.voting_views import VoteView
|
||||||
from dakiny_bot.database import create_database
|
from dakiny_bot.database import create_database
|
||||||
|
|
||||||
from .DakinySettings import settings
|
from .dakiny_settings import settings
|
||||||
|
|
||||||
birthday_list: list[int] = []
|
birthday_list: list[int] = []
|
||||||
|
|
||||||
|
|||||||
@@ -5,14 +5,11 @@ from datetime import UTC, datetime, timedelta
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import nextcord
|
import nextcord
|
||||||
from sqlalchemy import select, true, update
|
|
||||||
from sqlalchemy.orm import Session
|
|
||||||
|
|
||||||
from dakiny_bot.classes.nominate_highcouncil_views import NominateHighCouncilView
|
from dakiny_bot.classes.nominate_highcouncil_views import NominateHighCouncilView
|
||||||
from dakiny_bot.classes.nominate_views import NominateView
|
from dakiny_bot.classes.nominate_views import NominateView
|
||||||
from dakiny_bot.classes.voting_highcouncil_views import VoteHighcouncilView
|
from dakiny_bot.classes.voting_highcouncil_views import VoteHighcouncilView
|
||||||
from dakiny_bot.classes.voting_views import VoteView
|
from dakiny_bot.classes.voting_views import VoteView
|
||||||
from dakiny_bot.DakinySettings import settings
|
from dakiny_bot.dakiny_settings import settings
|
||||||
from dakiny_bot.database.sql_data_classes import (
|
from dakiny_bot.database.sql_data_classes import (
|
||||||
CouncilMembers,
|
CouncilMembers,
|
||||||
ElectionInformation,
|
ElectionInformation,
|
||||||
@@ -28,6 +25,8 @@ from dakiny_bot.utils import (
|
|||||||
get_datetime,
|
get_datetime,
|
||||||
get_election_name,
|
get_election_name,
|
||||||
)
|
)
|
||||||
|
from sqlalchemy import select, true, update
|
||||||
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
REQUIRED_VOTES_TO_BE_ELECTED = 3
|
REQUIRED_VOTES_TO_BE_ELECTED = 3
|
||||||
|
|
||||||
@@ -70,7 +69,7 @@ class Election:
|
|||||||
list[str]: A list of message contents in the correct order. Must be a string because the message is too
|
list[str]: A list of message contents in the correct order. Must be a string because the message is too
|
||||||
long.
|
long.
|
||||||
"""
|
"""
|
||||||
with Path(f"{TEMPLATES_DIR}/election_announcement.txt", encoding="utf8").open() as file:
|
with Path(f"{TEMPLATES_DIR}/election_announcement.txt").open() as file:
|
||||||
message = file.read()
|
message = file.read()
|
||||||
|
|
||||||
next_election = get_datetime(
|
next_election = get_datetime(
|
||||||
@@ -98,7 +97,7 @@ class Election:
|
|||||||
Returns:
|
Returns:
|
||||||
str: Message to send.
|
str: Message to send.
|
||||||
"""
|
"""
|
||||||
with Path(f"{TEMPLATES_DIR}/highcouncil_election.txt", encoding="utf8").open() as file:
|
with Path(f"{TEMPLATES_DIR}/highcouncil_election.txt").open() as file:
|
||||||
message = file.read()
|
message = file.read()
|
||||||
|
|
||||||
return message.format(
|
return message.format(
|
||||||
@@ -116,7 +115,7 @@ class Election:
|
|||||||
Returns:
|
Returns:
|
||||||
str: Message to send.
|
str: Message to send.
|
||||||
"""
|
"""
|
||||||
with Path(f"{TEMPLATES_DIR}/highcouncil_vote.txt", encoding="utf8").open() as file:
|
with Path(f"{TEMPLATES_DIR}/highcouncil_vote.txt").open() as file:
|
||||||
message = file.read()
|
message = file.read()
|
||||||
|
|
||||||
return message.format(
|
return message.format(
|
||||||
@@ -131,7 +130,7 @@ class Election:
|
|||||||
Returns:
|
Returns:
|
||||||
str: Message to send
|
str: Message to send
|
||||||
"""
|
"""
|
||||||
with Path(f"{TEMPLATES_DIR}/vote_start.txt", encoding="utf8").open() as file:
|
with Path(f"{TEMPLATES_DIR}/vote_start.txt").open() as file:
|
||||||
message = file.read()
|
message = file.read()
|
||||||
vote_end: datetime = get_datetime(settings.election_cycles[self.cycle].voting_end)
|
vote_end: datetime = get_datetime(settings.election_cycles[self.cycle].voting_end)
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,7 @@
|
|||||||
"""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
|
import nextcord
|
||||||
from nextcord.interactions import Interaction
|
from dakiny_bot.dakiny_settings import settings
|
||||||
from sqlalchemy import select
|
|
||||||
from sqlalchemy.orm import Session
|
|
||||||
|
|
||||||
from dakiny_bot.DakinySettings import settings
|
|
||||||
from dakiny_bot.database.sql_data_classes import CouncilMembers, engine
|
from dakiny_bot.database.sql_data_classes import CouncilMembers, engine
|
||||||
from dakiny_bot.utils import (
|
from dakiny_bot.utils import (
|
||||||
NOMINEE_SPLITTER,
|
NOMINEE_SPLITTER,
|
||||||
@@ -13,6 +9,9 @@ from dakiny_bot.utils import (
|
|||||||
decorate_dm_nomination,
|
decorate_dm_nomination,
|
||||||
get_election_name,
|
get_election_name,
|
||||||
)
|
)
|
||||||
|
from nextcord.interactions import Interaction
|
||||||
|
from sqlalchemy import select
|
||||||
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
|
|
||||||
class NominateDMModal(nextcord.ui.Modal):
|
class NominateDMModal(nextcord.ui.Modal):
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
"""Contains various views to be used in the nomination process."""
|
"""Contains various views to be used in the nomination process."""
|
||||||
|
|
||||||
import nextcord
|
import nextcord
|
||||||
|
from dakiny_bot.dakiny_settings import settings
|
||||||
|
from dakiny_bot.database.sql_data_classes import CouncilMembers, engine
|
||||||
|
from dakiny_bot.utils import NOMINEE_SPLITTER, decorate_nomination, get_election_name
|
||||||
from nextcord.interactions import Interaction
|
from nextcord.interactions import Interaction
|
||||||
from sqlalchemy import select
|
from sqlalchemy import select
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
from dakiny_bot.DakinySettings import settings
|
|
||||||
from dakiny_bot.database.sql_data_classes import CouncilMembers, engine
|
|
||||||
from dakiny_bot.utils import NOMINEE_SPLITTER, decorate_nomination, get_election_name
|
|
||||||
|
|
||||||
|
|
||||||
class NominateModal(nextcord.ui.Modal):
|
class NominateModal(nextcord.ui.Modal):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -1,12 +1,7 @@
|
|||||||
"""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
|
import nextcord
|
||||||
from nextcord import SelectOption
|
from dakiny_bot.dakiny_settings import settings
|
||||||
from nextcord.interactions import Interaction
|
|
||||||
from sqlalchemy import exc, select, update
|
|
||||||
from sqlalchemy.orm import Session
|
|
||||||
|
|
||||||
from dakiny_bot.DakinySettings import settings
|
|
||||||
from dakiny_bot.database.sql_data_classes import (
|
from dakiny_bot.database.sql_data_classes import (
|
||||||
CouncilMembers,
|
CouncilMembers,
|
||||||
ElectionInformation,
|
ElectionInformation,
|
||||||
@@ -14,6 +9,10 @@ from dakiny_bot.database.sql_data_classes import (
|
|||||||
engine,
|
engine,
|
||||||
)
|
)
|
||||||
from dakiny_bot.utils import VoteType, build_highcouncil_votes_str, get_election_name
|
from dakiny_bot.utils import VoteType, build_highcouncil_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
|
||||||
|
|
||||||
|
|
||||||
class VoteSelect(nextcord.ui.StringSelect):
|
class VoteSelect(nextcord.ui.StringSelect):
|
||||||
|
|||||||
@@ -1,12 +1,7 @@
|
|||||||
"""Contains various views to be used while voting. Controls the logic when performing the vote."""
|
"""Contains various views to be used while voting. Controls the logic when performing the vote."""
|
||||||
|
|
||||||
import nextcord
|
import nextcord
|
||||||
from nextcord import SelectOption
|
from dakiny_bot.dakiny_settings import settings
|
||||||
from nextcord.interactions import Interaction
|
|
||||||
from sqlalchemy import exc, select, update
|
|
||||||
from sqlalchemy.orm import Session
|
|
||||||
|
|
||||||
from dakiny_bot.DakinySettings import settings
|
|
||||||
from dakiny_bot.database.sql_data_classes import (
|
from dakiny_bot.database.sql_data_classes import (
|
||||||
CouncilMembers,
|
CouncilMembers,
|
||||||
ElectionInformation,
|
ElectionInformation,
|
||||||
@@ -14,6 +9,10 @@ from dakiny_bot.database.sql_data_classes import (
|
|||||||
engine,
|
engine,
|
||||||
)
|
)
|
||||||
from dakiny_bot.utils import VoteType, build_votes_str, get_election_name
|
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
|
||||||
|
|
||||||
|
|
||||||
class VoteSelect(nextcord.ui.StringSelect):
|
class VoteSelect(nextcord.ui.StringSelect):
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ from git import Repo
|
|||||||
from nextcord.ext import commands
|
from nextcord.ext import commands
|
||||||
|
|
||||||
from dakiny_bot.classes.gitea_webhook import GiteaWebhook
|
from dakiny_bot.classes.gitea_webhook import GiteaWebhook
|
||||||
from dakiny_bot.DakinySettings import settings
|
from dakiny_bot.dakiny_settings import settings
|
||||||
from dakiny_bot.utils import REPO_DIR, edit_clan_council_info, update_clan_messages
|
from dakiny_bot.utils import REPO_DIR, edit_clan_council_info, update_clan_messages
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import nextcord
|
|||||||
from discord import TextInputStyle
|
from discord import TextInputStyle
|
||||||
from nextcord.ext import commands
|
from nextcord.ext import commands
|
||||||
|
|
||||||
from dakiny_bot.DakinySettings import settings
|
from dakiny_bot.dakiny_settings import settings
|
||||||
from dakiny_bot.utils import GUILDS, MAX_DISCORD_MESSAGE_LENGTH, PointType, record_points
|
from dakiny_bot.utils import GUILDS, MAX_DISCORD_MESSAGE_LENGTH, PointType, record_points
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import nextcord
|
|||||||
from nextcord.ext import commands
|
from nextcord.ext import commands
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
from dakiny_bot.DakinySettings import settings
|
from dakiny_bot.dakiny_settings import settings
|
||||||
from dakiny_bot.database.sql_data_classes import Presences, engine
|
from dakiny_bot.database.sql_data_classes import Presences, engine
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
import nextcord
|
import nextcord
|
||||||
from nextcord.ext import commands
|
from nextcord.ext import commands
|
||||||
|
|
||||||
from dakiny_bot.DakinySettings import settings
|
from dakiny_bot.dakiny_settings import settings
|
||||||
from dakiny_bot.utils import GUILDS
|
from dakiny_bot.utils import GUILDS
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import nextcord
|
|||||||
from nextcord.ext import application_checks, commands
|
from nextcord.ext import application_checks, commands
|
||||||
|
|
||||||
from dakiny_bot.classes.election import Election
|
from dakiny_bot.classes.election import Election
|
||||||
from dakiny_bot.DakinySettings import settings
|
from dakiny_bot.dakiny_settings import settings
|
||||||
from dakiny_bot.utils import GUILDS, get_active_election_cycle, get_quarter_name
|
from dakiny_bot.utils import GUILDS, get_active_election_cycle, get_quarter_name
|
||||||
|
|
||||||
ME = 206602713511886849
|
ME = 206602713511886849
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ from sqlalchemy.orm import Session
|
|||||||
|
|
||||||
from dakiny_bot.app import birthday_list
|
from dakiny_bot.app import birthday_list
|
||||||
from dakiny_bot.classes.election import Election
|
from dakiny_bot.classes.election import Election
|
||||||
from dakiny_bot.DakinySettings import settings
|
from dakiny_bot.dakiny_settings import settings
|
||||||
from dakiny_bot.database.sql_data_classes import UserBirthday, engine
|
from dakiny_bot.database.sql_data_classes import UserBirthday, engine
|
||||||
from dakiny_bot.utils import get_active_election_cycle
|
from dakiny_bot.utils import get_active_election_cycle
|
||||||
|
|
||||||
|
|||||||
@@ -83,4 +83,5 @@ class DakinySettings(YAMLWizard):
|
|||||||
self.to_yaml_file(CONFIG_LOCATION)
|
self.to_yaml_file(CONFIG_LOCATION)
|
||||||
|
|
||||||
|
|
||||||
settings = DakinySettings.from_yaml_file(CONFIG_LOCATION)
|
tmp = DakinySettings.from_yaml_file(CONFIG_LOCATION)
|
||||||
|
settings: DakinySettings = tmp[0] if isinstance(tmp, list) else tmp
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
"""Empty init for testing util functions."""
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
"""Empty init for testing util functions."""
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
"""Tests for get_datetime function."""
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
from freezegun import freeze_time
|
||||||
|
|
||||||
|
from dakiny_bot.utils import get_datetime
|
||||||
|
|
||||||
|
|
||||||
|
@freeze_time("2025-6-16")
|
||||||
|
def test_regular_get_datetime() -> None:
|
||||||
|
date_time = get_datetime("6/16")
|
||||||
|
assert date_time == datetime.datetime(2025, 6, 16)
|
||||||
+15
-9
@@ -21,7 +21,7 @@ from dakiny_bot.database.sql_data_classes import (
|
|||||||
engine,
|
engine,
|
||||||
)
|
)
|
||||||
|
|
||||||
from .DakinySettings import settings
|
from .dakiny_settings import settings
|
||||||
|
|
||||||
NOMINEE_SPLITTER = "========================================\n\n"
|
NOMINEE_SPLITTER = "========================================\n\n"
|
||||||
REPO_DIR = "./dakiny-messages"
|
REPO_DIR = "./dakiny-messages"
|
||||||
@@ -34,20 +34,20 @@ VoteType = StrEnum("VoteType", ["COUNCIL", "DISCORDMANAGER", "CLANLEADER"])
|
|||||||
PointType = StrEnum("PointType", ["CLAN", "EVENT"])
|
PointType = StrEnum("PointType", ["CLAN", "EVENT"])
|
||||||
|
|
||||||
|
|
||||||
def get_datetime(day: str) -> datetime:
|
def get_datetime(month_day: str) -> datetime:
|
||||||
"""
|
"""
|
||||||
Takes in a string month and day and returns a datetime object of that Month/Day this year.
|
Takes in a string month and day and returns a datetime object of that Month/Day this year.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
day (str): Month/Day in that format.
|
month_day (str): Month/Day in that format.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
datetime: Datetime representation of Month/Day.
|
datetime: Datetime representation of Month/Day.
|
||||||
"""
|
"""
|
||||||
today = datetime.now(tz=UTC).date()
|
today = datetime.now(tz=UTC).date()
|
||||||
year = today.year
|
year = today.year
|
||||||
month = int(day.split("/")[0])
|
month = int(month_day.split("/")[0])
|
||||||
day = int(day.split("/")[1])
|
day = int(month_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 today.month == calendar.DECEMBER and month < calendar.OCTOBER:
|
if today.month == calendar.DECEMBER and month < calendar.OCTOBER:
|
||||||
@@ -66,7 +66,10 @@ def get_election_name() -> str:
|
|||||||
Returns:
|
Returns:
|
||||||
str: the name of the election cycle
|
str: the name of the election cycle
|
||||||
"""
|
"""
|
||||||
cycle = get_active_election_cycle()
|
if cycle := get_active_election_cycle() is None:
|
||||||
|
# undefined behavior
|
||||||
|
print("Did not find an active election cycle. Undefined behavior with return string.") # noqa: T201
|
||||||
|
return "No-active-election-cycle"
|
||||||
current_cycle = settings.election_cycles[cycle]
|
current_cycle = settings.election_cycles[cycle]
|
||||||
return f"vote-{get_datetime(current_cycle.term_start).year}-{current_cycle.name}"
|
return f"vote-{get_datetime(current_cycle.term_start).year}-{current_cycle.name}"
|
||||||
|
|
||||||
@@ -78,13 +81,16 @@ def get_quarter_name() -> str:
|
|||||||
Returns:
|
Returns:
|
||||||
str: the name of the cycle.
|
str: the name of the cycle.
|
||||||
"""
|
"""
|
||||||
cycle = get_quarter_cycle()
|
if cycle := get_quarter_cycle() is None:
|
||||||
|
# undefined behavior
|
||||||
|
print("Did not find a quarter cycle. Undefined behavior with return string.") # noqa: T201
|
||||||
|
return "no-quarter-cycle"
|
||||||
current_cycle = settings.election_cycles[cycle]
|
current_cycle = settings.election_cycles[cycle]
|
||||||
|
|
||||||
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_active_election_cycle() -> int:
|
def get_active_election_cycle() -> int | None:
|
||||||
"""
|
"""
|
||||||
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.
|
||||||
|
|
||||||
@@ -104,7 +110,7 @@ def get_active_election_cycle() -> int:
|
|||||||
return get_quarter_cycle()
|
return get_quarter_cycle()
|
||||||
|
|
||||||
|
|
||||||
def get_quarter_cycle() -> int:
|
def get_quarter_cycle() -> int | None:
|
||||||
"""
|
"""
|
||||||
Returns the index for the current cycle/quarter. Defined as between term start and end.
|
Returns the index for the current cycle/quarter. Defined as between term start and end.
|
||||||
|
|
||||||
|
|||||||
+9
-1
@@ -19,7 +19,12 @@ description = "Dakiny's Discord Bot."
|
|||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|
||||||
[dependency-groups]
|
[dependency-groups]
|
||||||
dev = ["ruff<1.0.0,>=0.6.9"]
|
dev = [
|
||||||
|
"freezegun>=1.5.1",
|
||||||
|
"pytest>=8.3.5",
|
||||||
|
"pytest-cov>=6.1.1",
|
||||||
|
"ruff<1.0.0,>=0.6.9",
|
||||||
|
]
|
||||||
|
|
||||||
[tool.ruff]
|
[tool.ruff]
|
||||||
# Exclude a variety of commonly ignored directories.
|
# Exclude a variety of commonly ignored directories.
|
||||||
@@ -126,3 +131,6 @@ docstring-code-format = true
|
|||||||
# This only has an effect when the `docstring-code-format` setting is
|
# This only has an effect when the `docstring-code-format` setting is
|
||||||
# enabled.
|
# enabled.
|
||||||
docstring-code-line-length = "dynamic"
|
docstring-code-line-length = "dynamic"
|
||||||
|
|
||||||
|
[tool.ruff.lint.per-file-ignores]
|
||||||
|
"**/{tests}/*" = ["ANN001", "ANN201", "S101", "PLR2004"]
|
||||||
|
|||||||
Reference in New Issue
Block a user