diff --git a/classes/submission.py b/classes/submission.py index d29a94d..dd932d2 100644 --- a/classes/submission.py +++ b/classes/submission.py @@ -4,8 +4,10 @@ Contains classes and enum for tracking data on submissions. from enum import Enum - from nextcord import Embed +from sqlalchemy import select + +from highscores import session, Category class SubmissionState(Enum): @@ -21,45 +23,46 @@ class SubmissionState(Enum): 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, table: str, username: str) -> None: + 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: str = "" + 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._table: str = table + self._group_id: int = group_id self._username: str = username @property - def category(self) -> str: + def category_id(self) -> int: """ - Getter for Submission's Category name. + Getter for Submission's Category id. Returns: - str: Category name. + int: Category id. """ - return self._category + return self._category_id - @category.setter - def category(self, category: str) -> None: + @category_id.setter + def category_id(self, category: int) -> None: """ - Setter for Submission's Category name. + Setter for Submission's Category id. Args: - category (str): Category name + category (int): Category id """ - self._category = category + self._category_id = category @property def guild_id(self) -> int: @@ -132,24 +135,24 @@ class Submission: self._submission_state = state @property - def table(self) -> str: + def group_id(self) -> str: """ - Getter for table Submission is for. + Getter for group Submission is for. Returns: - str: table name + str: group id """ - return self._table + return self._group_id - @table.setter - def table(self, table: str) -> None: + @group_id.setter + def group_id(self, table: str) -> None: """ Getter for table Submission is for. Args: - table (str): table name + table (str): group id """ - self._table = table + self._group_id = table @property def username(self) -> str: @@ -182,9 +185,7 @@ class Submission: 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)" - ) + 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: @@ -192,9 +193,10 @@ class Submission: embed = Embed(title="Highscores Submission", description=description) embed.add_field(name="User Name", value=self.username, inline=False) - embed.add_field(name="Table", value=self.table, inline=False) - if self.category: - embed.add_field(name="Category", value=self.category, inline=False) + embed.add_field(name="Table", value=self.group_id, inline=False) + if self.category_id: + stmt = select(Category.CategoryName).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) return embed diff --git a/cogs/message_listener/__init__.py b/cogs/message_listener/__init__.py index c8971c6..ffebe98 100644 --- a/cogs/message_listener/__init__.py +++ b/cogs/message_listener/__init__.py @@ -43,18 +43,7 @@ class SubmissionListener(commands.Cog, name="Message Listener"): state = submission.submission_state if state == SubmissionState.SCORE and message.content: - subq = ( - select(CategoryGroup) - .where(CategoryGroup.GuildId == guild_id) - .where(CategoryGroup.GroupName == submission.table) - .subquery() - ) - aliased_category_group = aliased(CategoryGroup, subq) - stmt = ( - select(Category.IsTimeRecord) - .where(Category.GroupId == aliased_category_group.GroupId) - .where(Category.CategoryName == submission.category) - ) + stmt = select(Category.IsTimeRecord).where(Category.CategoryId == submission.category_id) # check with regex if score matches correctly is_time_record = session.scalar(stmt) diff --git a/cogs/submission/submission_views.py b/cogs/submission/submission_views.py index 2398393..1a35136 100644 --- a/cogs/submission/submission_views.py +++ b/cogs/submission/submission_views.py @@ -4,22 +4,25 @@ from typing import Optional import nextcord from nextcord.ext import commands +from sqlalchemy import select +from sqlalchemy.orm import aliased + +# pylint: disable=import-error +from classes.submission import Submission, SubmissionState +from highscores import Category, Guild, CategoryGroup, session, submission_objects -from classes.submission import Submission, SubmissionState # pylint: disable=import-error -from highscores import ( # pylint: disable=import-error - highscores_data, - highscores_message_map, - submission_objects, -) from .verification_view import VerificationView -def category_select_options(guild_id: int, boss_name: str) -> "list[nextcord.SelectOption]": +def category_select_options(group_id: int) -> "list[nextcord.SelectOption]": """Returns list of categories for a given boss.""" options: "list[nextcord.SelectOption]" = [] - category_list = highscores_data.get_guild(guild_id).get_table(boss_name).categories - for category in category_list: - options.append(nextcord.SelectOption(label=category.name)) + subq = select(CategoryGroup).where(CategoryGroup.GroupId == group_id).subquery() + cat_group_alias = aliased(CategoryGroup, subq) + stmt = select(Category).where(Category.GroupId == cat_group_alias.GroupId) + categories_list = session.scalars(stmt) + for category in categories_list: + options.append(nextcord.SelectOption(label=category.CategoryName, value=str(category.CategoryId))) return options @@ -35,14 +38,12 @@ class SubmissionDropdown(nextcord.ui.Select): bot: commands.Bot, options: "list[nextcord.SelectOption]", ): - super().__init__( - placeholder="Choose submission category.", min_values=1, max_values=1, options=options - ) + super().__init__(placeholder="Choose submission category.", min_values=1, max_values=1, options=options) self._bot = bot async def callback(self, interaction: nextcord.Interaction): submission = submission_objects.get_user_submission(interaction.user.id) - submission.category = self.values[0] + submission.category_id = self.values[0] embed = submission.get_embed() await interaction.message.edit( embed=embed, @@ -87,7 +88,7 @@ class NextButton(nextcord.ui.Button): # check if fields have been filled out for each state submission = submission_objects.get_user_submission(interaction.user.id) state: SubmissionState = submission.submission_state - if state == SubmissionState.CATEGORY and not submission.category: + if state == SubmissionState.CATEGORY and not submission.category_id: await interaction.send("Please choose a category.", ephemeral=True) elif state == SubmissionState.SCORE and not submission.score: await interaction.send("Please send a score.", ephemeral=True) @@ -108,9 +109,8 @@ class SubmitButton(nextcord.ui.Button): self._bot = bot async def callback(self, interaction: nextcord.Interaction): - verification_channel_id = highscores_data.get_guild( - interaction.guild_id - ).verification_channel + stmt = select(Guild.VerificationChannel).where(Guild.GuildId == interaction.guild_id) + verification_channel_id = session.scalar(stmt) channel = interaction.guild.get_channel(verification_channel_id) submission = submission_objects.get_user_submission(interaction.user.id) @@ -142,9 +142,7 @@ class SubmissionCreateButton(nextcord.ui.View): super().__init__(timeout=None) self._bot = bot - @nextcord.ui.button( - label="Submit", style=nextcord.ButtonStyle.primary, custom_id="submitcreate" - ) + @nextcord.ui.button(label="Submit", style=nextcord.ButtonStyle.primary, custom_id="submitcreate") async def submitcreate_button( self, button: nextcord.ui.Button, interaction: nextcord.Interaction ): # pylint: disable=unused-argument @@ -154,17 +152,20 @@ class SubmissionCreateButton(nextcord.ui.View): await interaction.send("Please finish in progress submission first.", ephemeral=True) return - table = highscores_message_map[interaction.guild.id][interaction.message.id] - channel = interaction.guild.get_channel( - highscores_data.get_guild(interaction.guild_id).submission_channel + stmt = ( + select(CategoryGroup.GroupId) + .where(CategoryGroup.GuildId == interaction.guild_id) + .where(CategoryGroup.MessageId == interaction.message.id) ) + group_id = session.scalar(stmt) + + stmt = select(Guild.SubmissionChannel).where(Guild.GuildId == interaction.guild_id) + channel = interaction.guild.get_channel(session.scalar(stmt)) # a user should only have 1 submission active at once. - # split username on pipe then limit length. - username: str = interaction.user.display_name.split("|")[0][ - : highscores_data.get_guild(interaction.guild_id).username_length - ] - submission: Submission = Submission(interaction.guild_id, table, username) + # split username on pipe. Decided to store whole username... + username: str = interaction.user.display_name.split("|")[0] + submission: Submission = Submission(interaction.guild_id, group_id, username) submission_objects.add_submission(interaction.user.id, submission) @@ -197,14 +198,12 @@ class SubmissionView(nextcord.ui.View): self._submission_user = submission_user self._bot = bot self._state = submission_objects.get_user_submission(self._submission_user).submission_state - self._boss_name = submission_objects.get_user_submission(self._submission_user).table + self._group_id = submission_objects.get_user_submission(self._submission_user).group_id self._guild_id = submission_objects.get_user_submission(self._submission_user).guild_id # add items depending on given state if self._state is SubmissionState.CATEGORY: - self.add_item( - SubmissionDropdown(bot, category_select_options(self._guild_id, self._boss_name)) - ) + self.add_item(SubmissionDropdown(bot, category_select_options(self._group_id))) self.add_item(CancelButton()) self.add_item(NextButton(self._bot)) elif (