Change submission to use database. Also use ids rather than names.

This commit is contained in:
alwayscompiling
2022-11-30 22:36:45 -05:00
parent 814baa27d6
commit 4f255a32e2
3 changed files with 62 additions and 72 deletions
+29 -27
View File
@@ -4,8 +4,10 @@ Contains classes and enum for tracking data on submissions.
from enum import Enum from enum import Enum
from nextcord import Embed from nextcord import Embed
from sqlalchemy import select
from highscores import session, Category
class SubmissionState(Enum): class SubmissionState(Enum):
@@ -21,45 +23,46 @@ class SubmissionState(Enum):
VERIFY = 6 VERIFY = 6
# TODO remake into a data class
class Submission: class Submission:
""" """
Class for an individual submission. Contains submission information such as Class for an individual submission. Contains submission information such as
guild id, message id, table, category, username, score and submission state. 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. 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 Score and category are defaulted at empty, message id is 0, and submission state
is SubmissionState.CATEGORY. is SubmissionState.CATEGORY.
""" """
self._category: str = "" self._category_id: int = 0
self._guild_id: int = guild_id self._guild_id: int = guild_id
self._message_id: int = 0 self._message_id: int = 0
self._score: str = "" self._score: str = ""
self._submission_state: SubmissionState = SubmissionState.CATEGORY self._submission_state: SubmissionState = SubmissionState.CATEGORY
self._table: str = table self._group_id: int = group_id
self._username: str = username self._username: str = username
@property @property
def category(self) -> str: def category_id(self) -> int:
""" """
Getter for Submission's Category name. Getter for Submission's Category id.
Returns: Returns:
str: Category name. int: Category id.
""" """
return self._category return self._category_id
@category.setter @category_id.setter
def category(self, category: str) -> None: def category_id(self, category: int) -> None:
""" """
Setter for Submission's Category name. Setter for Submission's Category id.
Args: Args:
category (str): Category name category (int): Category id
""" """
self._category = category self._category_id = category
@property @property
def guild_id(self) -> int: def guild_id(self) -> int:
@@ -132,24 +135,24 @@ class Submission:
self._submission_state = state self._submission_state = state
@property @property
def table(self) -> str: def group_id(self) -> str:
""" """
Getter for table Submission is for. Getter for group Submission is for.
Returns: Returns:
str: table name str: group id
""" """
return self._table return self._group_id
@table.setter @group_id.setter
def table(self, table: str) -> None: def group_id(self, table: str) -> None:
""" """
Getter for table Submission is for. Getter for table Submission is for.
Args: Args:
table (str): table name table (str): group id
""" """
self._table = table self._group_id = table
@property @property
def username(self) -> str: def username(self) -> str:
@@ -182,9 +185,7 @@ class Submission:
elif state is SubmissionState.PROOF: elif state is SubmissionState.PROOF:
description = "Step 3: Submit your proof!" description = "Step 3: Submit your proof!"
elif state is SubmissionState.NAME: elif state is SubmissionState.NAME:
description = ( description = "Step 4 (Optional): Change name on submission! (proceed to next if skipping)"
"Step 4 (Optional): Change name on submission! (proceed to next if skipping)"
)
elif state is SubmissionState.SUBMIT: elif state is SubmissionState.SUBMIT:
description = "Step 5: Submit if everything looks correct!" description = "Step 5: Submit if everything looks correct!"
elif state is SubmissionState.VERIFY: elif state is SubmissionState.VERIFY:
@@ -192,9 +193,10 @@ class Submission:
embed = Embed(title="Highscores Submission", description=description) embed = Embed(title="Highscores Submission", description=description)
embed.add_field(name="User Name", value=self.username, inline=False) embed.add_field(name="User Name", value=self.username, inline=False)
embed.add_field(name="Table", value=self.table, inline=False) embed.add_field(name="Table", value=self.group_id, inline=False)
if self.category: if self.category_id:
embed.add_field(name="Category", value=self.category, inline=False) stmt = select(Category.CategoryName).where(Category.CategoryId == self.category_id)
embed.add_field(name="Category", value=session.scalar(stmt), inline=False)
if self.score: if self.score:
embed.add_field(name="Score", value=self.score, inline=False) embed.add_field(name="Score", value=self.score, inline=False)
return embed return embed
+1 -12
View File
@@ -43,18 +43,7 @@ class SubmissionListener(commands.Cog, name="Message Listener"):
state = submission.submission_state state = submission.submission_state
if state == SubmissionState.SCORE and message.content: if state == SubmissionState.SCORE and message.content:
subq = ( stmt = select(Category.IsTimeRecord).where(Category.CategoryId == submission.category_id)
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)
)
# check with regex if score matches correctly # check with regex if score matches correctly
is_time_record = session.scalar(stmt) is_time_record = session.scalar(stmt)
+32 -33
View File
@@ -4,22 +4,25 @@ from typing import Optional
import nextcord import nextcord
from nextcord.ext import commands 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 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.""" """Returns list of categories for a given boss."""
options: "list[nextcord.SelectOption]" = [] options: "list[nextcord.SelectOption]" = []
category_list = highscores_data.get_guild(guild_id).get_table(boss_name).categories subq = select(CategoryGroup).where(CategoryGroup.GroupId == group_id).subquery()
for category in category_list: cat_group_alias = aliased(CategoryGroup, subq)
options.append(nextcord.SelectOption(label=category.name)) 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 return options
@@ -35,14 +38,12 @@ class SubmissionDropdown(nextcord.ui.Select):
bot: commands.Bot, bot: commands.Bot,
options: "list[nextcord.SelectOption]", options: "list[nextcord.SelectOption]",
): ):
super().__init__( super().__init__(placeholder="Choose submission category.", min_values=1, max_values=1, options=options)
placeholder="Choose submission category.", min_values=1, max_values=1, options=options
)
self._bot = bot self._bot = bot
async def callback(self, interaction: nextcord.Interaction): async def callback(self, interaction: nextcord.Interaction):
submission = submission_objects.get_user_submission(interaction.user.id) submission = submission_objects.get_user_submission(interaction.user.id)
submission.category = self.values[0] submission.category_id = self.values[0]
embed = submission.get_embed() embed = submission.get_embed()
await interaction.message.edit( await interaction.message.edit(
embed=embed, embed=embed,
@@ -87,7 +88,7 @@ class NextButton(nextcord.ui.Button):
# check if fields have been filled out for each state # check if fields have been filled out for each state
submission = submission_objects.get_user_submission(interaction.user.id) submission = submission_objects.get_user_submission(interaction.user.id)
state: SubmissionState = submission.submission_state 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) await interaction.send("Please choose a category.", ephemeral=True)
elif state == SubmissionState.SCORE and not submission.score: elif state == SubmissionState.SCORE and not submission.score:
await interaction.send("Please send a score.", ephemeral=True) await interaction.send("Please send a score.", ephemeral=True)
@@ -108,9 +109,8 @@ class SubmitButton(nextcord.ui.Button):
self._bot = bot self._bot = bot
async def callback(self, interaction: nextcord.Interaction): async def callback(self, interaction: nextcord.Interaction):
verification_channel_id = highscores_data.get_guild( stmt = select(Guild.VerificationChannel).where(Guild.GuildId == interaction.guild_id)
interaction.guild_id verification_channel_id = session.scalar(stmt)
).verification_channel
channel = interaction.guild.get_channel(verification_channel_id) channel = interaction.guild.get_channel(verification_channel_id)
submission = submission_objects.get_user_submission(interaction.user.id) submission = submission_objects.get_user_submission(interaction.user.id)
@@ -142,9 +142,7 @@ class SubmissionCreateButton(nextcord.ui.View):
super().__init__(timeout=None) super().__init__(timeout=None)
self._bot = bot self._bot = bot
@nextcord.ui.button( @nextcord.ui.button(label="Submit", style=nextcord.ButtonStyle.primary, custom_id="submitcreate")
label="Submit", style=nextcord.ButtonStyle.primary, custom_id="submitcreate"
)
async def submitcreate_button( async def submitcreate_button(
self, button: nextcord.ui.Button, interaction: nextcord.Interaction self, button: nextcord.ui.Button, interaction: nextcord.Interaction
): # pylint: disable=unused-argument ): # pylint: disable=unused-argument
@@ -154,17 +152,20 @@ class SubmissionCreateButton(nextcord.ui.View):
await interaction.send("Please finish in progress submission first.", ephemeral=True) await interaction.send("Please finish in progress submission first.", ephemeral=True)
return return
table = highscores_message_map[interaction.guild.id][interaction.message.id] stmt = (
channel = interaction.guild.get_channel( select(CategoryGroup.GroupId)
highscores_data.get_guild(interaction.guild_id).submission_channel .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. # a user should only have 1 submission active at once.
# split username on pipe then limit length. # split username on pipe. Decided to store whole username...
username: str = interaction.user.display_name.split("|")[0][ username: str = interaction.user.display_name.split("|")[0]
: highscores_data.get_guild(interaction.guild_id).username_length submission: Submission = Submission(interaction.guild_id, group_id, username)
]
submission: Submission = Submission(interaction.guild_id, table, username)
submission_objects.add_submission(interaction.user.id, submission) submission_objects.add_submission(interaction.user.id, submission)
@@ -197,14 +198,12 @@ class SubmissionView(nextcord.ui.View):
self._submission_user = submission_user self._submission_user = submission_user
self._bot = bot self._bot = bot
self._state = submission_objects.get_user_submission(self._submission_user).submission_state 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 self._guild_id = submission_objects.get_user_submission(self._submission_user).guild_id
# add items depending on given state # add items depending on given state
if self._state is SubmissionState.CATEGORY: if self._state is SubmissionState.CATEGORY:
self.add_item( self.add_item(SubmissionDropdown(bot, category_select_options(self._group_id)))
SubmissionDropdown(bot, category_select_options(self._guild_id, self._boss_name))
)
self.add_item(CancelButton()) self.add_item(CancelButton())
self.add_item(NextButton(self._bot)) self.add_item(NextButton(self._bot))
elif ( elif (