""" 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)