""" Contains classes and enum for tracking data on submissions. """ 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 class SubmissionState(Enum): """ Enum for which state a submission is in """ CATEGORY = 1 SCORE = 2 PROOF = 3 NAME = 4 SUBMIT = 5 VERIFY = 6 # TODO remake into a data class class Submission: """ Class for an individual submission. Contains submission information such as guild id, message id, table, category, username, score and submission state. """ def __init__(self, guild_id: int, group_id: int, username: str) -> None: """ Default constructor for Submission. Just need to know guild_id, table, and username. Score and category are defaulted at empty, message id is 0, and submission state is SubmissionState.CATEGORY. """ self._category_id: int = 0 self._guild_id: int = guild_id self._message_id: int = 0 self._score: str = "" self._submission_state: SubmissionState = SubmissionState.CATEGORY self._group_id: int = group_id self._username: str = username @property def category_id(self) -> int: """ Getter for Submission's Category id. Returns: int: Category id. """ return self._category_id @category_id.setter def category_id(self, category: int) -> None: """ Setter for Submission's Category id. Args: category (int): Category id """ self._category_id = category @property def guild_id(self) -> int: """ Getter for guild id Submission is happening in. Will not change. Returns: int: guild id """ return self._guild_id @property def message_id(self) -> int: """ Getter for message id that Submission has a view on. Returns: int: message id """ return self._message_id @message_id.setter def message_id(self, m_id: int) -> None: """ Setter for message id that Submission has a view on. Args: m_id (int): message id """ self._message_id = m_id @property def score(self) -> str: """ Getter for score. Returns: str: score """ return self._score @score.setter def score(self, score: str) -> None: """ Setter for score. Args: score (str): score """ self._score = score @property def submission_state(self) -> SubmissionState: """ Getter for state Submission is in. Returns: SubmissionState: State the Submission is in """ return self._submission_state @submission_state.setter def submission_state(self, state: SubmissionState) -> None: """ Setter for state Submission is in. Args: state (SubmissionState): State to change to """ self._submission_state = state @property def group_id(self) -> str: """ Getter for group Submission is for. Returns: str: group id """ return self._group_id @group_id.setter def group_id(self, table: str) -> None: """ Getter for table Submission is for. Args: table (str): group id """ self._group_id = table @property def username(self) -> str: """ Getter for Submission owner's username. Returns: str: Submission owner's username """ return self._username @username.setter def username(self, username: str) -> None: """ Setter for Submission owner's username. Args: username (str): Submission owner's username """ self._username = username def get_embeds(self) -> "list[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=self.score, inline=False) embeds = [embed] if state is SubmissionState.VERIFY: embed = Embed(title="Bot Information", description="Please disregard.") embed.add_field(name="GroupId", value=self.group_id) embed.add_field(name="CategoryId", value=self.category_id) embeds.append(embed) return embeds 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)