Compare commits
11
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
490c30e88c | ||
|
|
35670358c4 | ||
|
|
7a59f3b453 | ||
|
|
e01ab64411 | ||
|
|
df482d80f0 | ||
|
|
0d06d98060 | ||
|
|
c267762efa | ||
|
|
e837cec46b | ||
|
|
0a856755c8 | ||
|
|
eb8cfee7fd | ||
|
|
6b5dc771d4 |
@@ -0,0 +1,210 @@
|
|||||||
|
"""File holds all model definitions of SQL tables."""
|
||||||
|
|
||||||
|
from sqlalchemy.dialects.mysql import BIGINT, BOOLEAN, INTEGER, VARCHAR
|
||||||
|
from sqlmodel import Column, Field, ForeignKey, Relationship, SQLModel
|
||||||
|
|
||||||
|
|
||||||
|
class ElectionInformation(SQLModel, table=True):
|
||||||
|
"""
|
||||||
|
Represents all required information for an election.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
name: Name of the election.
|
||||||
|
thread_id: Thread of where all the election related messages take place.
|
||||||
|
council_vote_msg_id: Message where the council vote is presented.
|
||||||
|
high_council_vote_msg_id: Message where the high council vote is presented.
|
||||||
|
council_nomination_msg_id: Message where council nomination button is held.
|
||||||
|
high_council_nomination_msg_id: Message where high council nomination button is held.
|
||||||
|
council_members: List of council members who ran during this election.
|
||||||
|
votes: All votes cast during this election.
|
||||||
|
"""
|
||||||
|
|
||||||
|
name: str = Field(sa_column=Column("ElectionName", VARCHAR, primary_key=True, unique=True), max_length=30)
|
||||||
|
thread_id: int = Field(sa_column=Column("ThreadId", BIGINT(unsigned=True), nullable=False))
|
||||||
|
council_vote_msg_id: int | None = Field(
|
||||||
|
sa_column=Column("CouncilVoteMsgId", BIGINT(unsigned=True), nullable=True), default=None
|
||||||
|
)
|
||||||
|
high_council_vote_msg_id: int | None = Field(
|
||||||
|
sa_column=Column("HighCouncilVoteMsgId", BIGINT(unsigned=True), nullable=True), default=None
|
||||||
|
)
|
||||||
|
council_nomination_msg_id: int | None = Field(
|
||||||
|
sa_column=Column("CouncilNominationMsgId", BIGINT(unsigned=True), nullable=True), default=None
|
||||||
|
)
|
||||||
|
high_council_nomination_msg_id: int | None = Field(
|
||||||
|
sa_column=Column("HighCouncilNominationMsgId", BIGINT(unsigned=True), nullable=True), default=None
|
||||||
|
)
|
||||||
|
|
||||||
|
council_members: list["CouncilMember"] = Relationship(back_populates="election", cascade_delete=True)
|
||||||
|
votes: list["Vote"] = Relationship(back_populates="election", cascade_delete=True)
|
||||||
|
|
||||||
|
|
||||||
|
class CouncilMember(SQLModel, table=True):
|
||||||
|
"""
|
||||||
|
Represents members involved in a given election.
|
||||||
|
|
||||||
|
Records speech message ids for general election and high council position. Booleans record if the user was elected
|
||||||
|
to a council/high council position.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
member_id: User that is running for council's discord id.
|
||||||
|
speech_msg_id: Message id of user's speech.
|
||||||
|
elected: Whether the user got elected to council.
|
||||||
|
discord_manager: Whether the user got elected to the Discord Manager position.
|
||||||
|
clan_leader: Whether the user got elected to the Clan Leader position.
|
||||||
|
discord_manager_speech_id: Message id of the user's Discord Manager speech.
|
||||||
|
clan_leader_speech_id: Message id of the user's Clan Leader speech.
|
||||||
|
election: The election this user object is for.
|
||||||
|
votes: A list of votes for this user.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__tablename__: str = "CouncilMembers"
|
||||||
|
|
||||||
|
election_name: str = Field(
|
||||||
|
sa_column=Column(
|
||||||
|
"ElectionName",
|
||||||
|
VARCHAR,
|
||||||
|
ForeignKey("ElectionInformation.ElectionName", ondelete="CASCADE"),
|
||||||
|
primary_key=True,
|
||||||
|
),
|
||||||
|
max_length=30,
|
||||||
|
)
|
||||||
|
member_id: int = Field(sa_column=Column("MemberId", BIGINT(unsigned=True), primary_key=True, nullable=False))
|
||||||
|
speech_msg_id: int = Field(sa_column=Column("SpeechMsgId", BIGINT(unsigned=True), nullable=False))
|
||||||
|
elected: bool = Field(sa_column=Column("Elected", BOOLEAN), default=False)
|
||||||
|
discord_manager: bool = Field(sa_column=Column("DiscordManager", BOOLEAN), default=False)
|
||||||
|
clan_leader: bool = Field(sa_column=Column("ClanLeader", BOOLEAN), default=False)
|
||||||
|
discord_manager_speech_id: int = Field(
|
||||||
|
sa_column=Column("DiscordManagerSpeechId", BIGINT(unsigned=True), nullable=True)
|
||||||
|
)
|
||||||
|
clan_leader_speech_id: int = Field(sa_column=Column("ClanLeaderSpeechId", BIGINT(unsigned=True), nullable=True))
|
||||||
|
|
||||||
|
election: ElectionInformation | None = Relationship(back_populates="council_members")
|
||||||
|
votes: list["Vote"] = Relationship(back_populates="council_member")
|
||||||
|
|
||||||
|
|
||||||
|
class Vote(SQLModel, table=True):
|
||||||
|
"""
|
||||||
|
Represents a vote cast during an election.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
election_name: Election this vote was cast in.
|
||||||
|
voter_id: User id that cast the vote.
|
||||||
|
voted_for_id: User id that was voted for.
|
||||||
|
type: Type of election, council, discordmanager, or clanleader.
|
||||||
|
election: A link to the ElectionInformation object that the vote was cast in.
|
||||||
|
council_member: A link to the CouncilMember object that the vote is for.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__tablename__: str = "Votes"
|
||||||
|
|
||||||
|
election_name: str = Field(
|
||||||
|
sa_column=Column(
|
||||||
|
"ElectionName",
|
||||||
|
VARCHAR,
|
||||||
|
ForeignKey("ElectionInformation.ElectionName", ondelete="CASCADE"),
|
||||||
|
primary_key=True,
|
||||||
|
),
|
||||||
|
max_length=30,
|
||||||
|
)
|
||||||
|
voter_id: int = Field(sa_column=Column("VoterId", BIGINT(unsigned=True), primary_key=True, nullable=False))
|
||||||
|
# might have to set this foreign key later with alembic migration...
|
||||||
|
voted_for_id: int | None = Field(
|
||||||
|
sa_column=Column("VotedForId", BIGINT(unsigned=True), ForeignKey("CouncilMembers.member_id"), nullable=True)
|
||||||
|
)
|
||||||
|
type: str = Field(sa_column=Column("Type", primary_key=True, nullable=False, default="council"), max_length=14)
|
||||||
|
|
||||||
|
election: ElectionInformation | None = Relationship(back_populates="votes")
|
||||||
|
council_member: CouncilMember | None = Relationship(back_populates="votes")
|
||||||
|
|
||||||
|
|
||||||
|
class UserBirthday(SQLModel, table=True):
|
||||||
|
"""
|
||||||
|
Represents a user's birth month and day.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
id: User's discord id.
|
||||||
|
birthday: Month/day that is a user's birthday.
|
||||||
|
"""
|
||||||
|
|
||||||
|
id: int = Field(sa_column=Column("UserId", BIGINT(unsigned=True), primary_key=True, nullable=False))
|
||||||
|
|
||||||
|
# TODO(imcompiling): split into month and day. Also relies on Alembic migration.
|
||||||
|
# https://gitea.cheezers.org/imcompiling/dakiny-bot/issues/93
|
||||||
|
birthday: str = Field(sa_column=Column("Birthday", VARCHAR, nullable=False), max_length=5)
|
||||||
|
|
||||||
|
|
||||||
|
class Presence(SQLModel, table=True):
|
||||||
|
"""
|
||||||
|
Stores presences for the bot to pull and use.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
id: Auto-incremented id for each entry.
|
||||||
|
presence: The presence itself.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__tablename__: str = "Presences"
|
||||||
|
|
||||||
|
id: int | None = Field(sa_column=Column("Id", INTEGER, primary_key=True), default=None)
|
||||||
|
presence: str = Field(sa_column=Column("Presence", VARCHAR, nullable=False), max_length=100)
|
||||||
|
|
||||||
|
|
||||||
|
class Points(SQLModel, table=True):
|
||||||
|
"""
|
||||||
|
Stores activity points a user can gain by participating in clan activities.
|
||||||
|
|
||||||
|
Event points and clan points were separated out.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
quarter_name: Name of the quarter the points were earned in.
|
||||||
|
user_id: The user that earned them. Is a discord id if the user is a discord member, otherwise their rsn.
|
||||||
|
discord_member: Boolean on whether the user is a discord member or not. Used to know what the user_id
|
||||||
|
represents.
|
||||||
|
event_points: Event points earned during the quarter.
|
||||||
|
clan_points: Clan points earned during the quarter.
|
||||||
|
"""
|
||||||
|
|
||||||
|
quarter_name: str = Field(sa_column=Column("QuarterName", VARCHAR, primary_key=True, nullable=False), max_length=30)
|
||||||
|
user_id: str = Field(sa_column=Column("UserId", VARCHAR, primary_key=True, nullable=False), max_length=32)
|
||||||
|
discord_member: bool = Field(sa_column=Column("DiscordMember", BOOLEAN, nullable=False))
|
||||||
|
event_points: int = Field(sa_column=Column("EventPoints", INTEGER(unsigned=True), nullable=False), default=0)
|
||||||
|
clan_points: int = Field(sa_column=Column("ClanPoints", INTEGER(unsigned=True), nullable=False), default=0)
|
||||||
|
|
||||||
|
|
||||||
|
class Message(SQLModel, table=True):
|
||||||
|
"""
|
||||||
|
Table is used to map folders and files to channels and messages in discord.
|
||||||
|
|
||||||
|
If folder name is stored in path, the corresponding id is a channel id. If the path is to a file, the id is for a
|
||||||
|
message.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
path: Either directory or file pathname.
|
||||||
|
id: Channel or message id depending on the path.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__tablename__: str = "Messages"
|
||||||
|
|
||||||
|
path: str = Field(sa_column=Column("Path", primary_key=True, nullable=False), max_length=100)
|
||||||
|
id: int = Field(sa_column=Column("Id", BIGINT(unsigned=True), nullable=False))
|
||||||
|
|
||||||
|
|
||||||
|
class PointsLimit(SQLModel, table=True):
|
||||||
|
"""
|
||||||
|
Table tracks how many points a user has gained in a week.
|
||||||
|
|
||||||
|
Council didn't want users spamming points, so they added a limit to how many can be gained in a week. This table
|
||||||
|
tracks point gain per week.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
user_id: The user that earned points. Is a discord id if the user is a discord member, otherwise their rsn.
|
||||||
|
week: week number/year representation of the week. Ex: 04/2025.
|
||||||
|
event_points: Number of event points earned during this week.
|
||||||
|
clan_points: Number of clan points earned during this week.
|
||||||
|
"""
|
||||||
|
|
||||||
|
user_id: str = Field(sa_column=Column("UserId", VARCHAR, primary_key=True, nullable=False), max_length=32)
|
||||||
|
|
||||||
|
# Maybe should break this out into two columns, week and year. Better data validation and more clear.
|
||||||
|
week: str = Field(sa_column=Column("Week", VARCHAR, primary_key=True, nullable=False), max_length=7)
|
||||||
|
event_points: int = Field(sa_column=Column("EventPoints", INTEGER(unsigned=True), nullable=False), default=0)
|
||||||
|
clan_points: int = Field(sa_column=Column("ClanPoints", INTEGER(unsigned=True), nullable=False), default=0)
|
||||||
@@ -13,6 +13,7 @@ dependencies = [
|
|||||||
"dataclass-wizard[yaml]>=0.22.3,<1.0.0",
|
"dataclass-wizard[yaml]>=0.22.3,<1.0.0",
|
||||||
"uvicorn>=0.34.0",
|
"uvicorn>=0.34.0",
|
||||||
"audioop-lts>=0.2.1",
|
"audioop-lts>=0.2.1",
|
||||||
|
"sqlmodel>=0.0.24",
|
||||||
]
|
]
|
||||||
name = "dakiny-bot"
|
name = "dakiny-bot"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|||||||
Reference in New Issue
Block a user