140 lines
4.4 KiB
Python
140 lines
4.4 KiB
Python
"""
|
|
Contains classes and enum for tracking data on submissions.
|
|
"""
|
|
|
|
from dataclasses import dataclass, field
|
|
from enum import Enum
|
|
|
|
from nextcord import Embed
|
|
from sqlalchemy import select
|
|
from sqlalchemy.orm import Session
|
|
|
|
# pylint: disable=import-error
|
|
from utilities.sql_data_classes import Category, CategoryGroup, engine
|
|
from utilities.utils import score_float_to_str
|
|
|
|
|
|
# TODO use the fancy enums
|
|
class SubmissionState(Enum):
|
|
"""
|
|
Enum for which state a submission is in
|
|
"""
|
|
|
|
CATEGORY = 1
|
|
SCORE = 2
|
|
PROOF = 3
|
|
NAME = 4
|
|
SUBMIT = 5
|
|
VERIFY = 6
|
|
|
|
|
|
@dataclass
|
|
class Submission:
|
|
"""
|
|
Class for an individual submission. Contains submission information such as
|
|
guild id, message id, table, category, username, score and submission state.
|
|
"""
|
|
|
|
category_id: int = field(init=False, default=0)
|
|
group_id: int
|
|
guild_id: int
|
|
is_time_record: bool = field(init=False, default=False)
|
|
message_id: int = field(init=False, default=0)
|
|
score: float = field(init=False, default=0.0)
|
|
submission_state: SubmissionState = field(init=False, default=SubmissionState.CATEGORY)
|
|
username: str
|
|
|
|
def get_embed(self) -> Embed:
|
|
"""Creates an embed based off of the submission state and fields filled out."""
|
|
state: SubmissionState = self.submission_state
|
|
|
|
if state is SubmissionState.CATEGORY:
|
|
description = "Step 1: Choose your category!"
|
|
elif state is SubmissionState.SCORE:
|
|
description = "Step 2: Input your score!"
|
|
elif state is SubmissionState.PROOF:
|
|
description = "Step 3: Submit your proof!"
|
|
elif state is SubmissionState.NAME:
|
|
description = "Step 4 (Optional): Change name on submission! (proceed to next if skipping)"
|
|
elif state is SubmissionState.SUBMIT:
|
|
description = "Step 5: Submit if everything looks correct!"
|
|
elif state is SubmissionState.VERIFY:
|
|
description = "Review fields and accept."
|
|
|
|
embed = Embed(title="Highscores Submission", description=description)
|
|
embed.add_field(name="User Name", value=self.username, inline=False)
|
|
stmt = (
|
|
select(CategoryGroup.GroupName)
|
|
.where(CategoryGroup.GuildId == self.guild_id)
|
|
.where(CategoryGroup.GroupId == self.group_id)
|
|
)
|
|
with Session(engine) as session:
|
|
embed.add_field(name="Group", value=session.scalar(stmt), inline=False)
|
|
if self.category_id:
|
|
stmt = (
|
|
select(Category.CategoryName)
|
|
.where(Category.GroupId == self.group_id)
|
|
.where(Category.CategoryId == self.category_id)
|
|
)
|
|
embed.add_field(name="Category", value=session.scalar(stmt), inline=False)
|
|
if self.score:
|
|
embed.add_field(name="Score", value=score_float_to_str(self.score, self.is_time_record), inline=False)
|
|
|
|
return embed
|
|
|
|
|
|
class SubmissionMap:
|
|
"""
|
|
Tracks all active submission.
|
|
"""
|
|
|
|
def __init__(self) -> None:
|
|
"""
|
|
Default constructor for SubmissionMap. Created empty map.
|
|
"""
|
|
self._submission_map: dict = {}
|
|
|
|
def add_submission(self, user_id: int, submission: Submission) -> None:
|
|
"""
|
|
Adds new submission to submission map. User id is used as a key, a user should only
|
|
have one submission at a time.
|
|
|
|
Args:
|
|
user_id (int): User id of submitter. Unique, used as key.
|
|
submission (Submission): Submission object
|
|
"""
|
|
self._submission_map[user_id] = submission
|
|
|
|
def get_user_submission(self, user_id: int) -> Submission:
|
|
"""
|
|
Getter for a user's Submission.
|
|
|
|
Args:
|
|
user_id (int): user id
|
|
|
|
Returns:
|
|
Submission: user's submission
|
|
"""
|
|
return self._submission_map[user_id]
|
|
|
|
def has_user(self, user_id: int) -> bool:
|
|
"""
|
|
Tells if user has an active submission in submission map.
|
|
|
|
Args:
|
|
user_id (int): user id
|
|
|
|
Returns:
|
|
bool: bool indicating if user id is in submission map
|
|
"""
|
|
return user_id in self._submission_map
|
|
|
|
def remove_user_submission(self, user_id: int) -> None:
|
|
"""
|
|
Removes a user's Submission. Use when Submission is complete.
|
|
|
|
Args:
|
|
user_id (int): user id to identify user's Submission
|
|
"""
|
|
self._submission_map.pop(user_id)
|