Squashed commit of the following:

commit 3627419e12
Merge: 2db744d 3446ce9
Author: alwayscompiling <[email protected]>
Date:   Tue Dec 6 22:36:51 2022 -0500

    Merge branch '45-sql-connection-timing-out' into develop

commit 3446ce9ca2
Author: alwayscompiling <[email protected]>
Date:   Tue Dec 6 22:27:05 2022 -0500

    Change session usage to on use basis.

commit 2db744d170
Author: alwayscompiling <[email protected]>
Date:   Sun Dec 4 21:44:54 2022 -0500

    Add restart policy.

commit fa33be1b4a
Author: alwayscompiling <[email protected]>
Date:   Sun Dec 4 21:25:57 2022 -0500

    Renamed docker compose file.
This commit is contained in:
alwayscompiling
2022-12-06 23:02:01 -05:00
parent 582b88e248
commit d04b8c5e32
12 changed files with 359 additions and 307 deletions
+98 -84
View File
@@ -8,10 +8,10 @@ import time
import nextcord
import pandas as pd
from sqlalchemy import distinct, select
from sqlalchemy.orm import aliased
from sqlalchemy.orm import Session, aliased
# pylint: disable=import-error
from utilities.sql_alchemy_connection import Category, CategoryGroup, Guild, Score, engine, session
from utilities.sql_data_classes import Category, CategoryGroup, Guild, Score, engine
MAX_LINE_LENGTH = 142
@@ -30,16 +30,17 @@ def autofill_categories(guild_id: int, group_id: int, category_begin: str) -> "d
dict[str, str]: List of all category names that start with category_begin.
"""
# search database for all category names
subq = (
select(CategoryGroup)
.where(CategoryGroup.GuildId == guild_id)
.where(CategoryGroup.GroupId == group_id)
.subquery()
)
cat_group_alias = aliased(CategoryGroup, subq)
stmt = select(Category).where(Category.GroupId == cat_group_alias.GroupId)
categories_dict: dict = {cat.CategoryName: str(cat.CategoryId) for cat in session.scalars(stmt)}
with Session(engine) as session:
# search database for all category names
subq = (
select(CategoryGroup)
.where(CategoryGroup.GuildId == guild_id)
.where(CategoryGroup.GroupId == group_id)
.subquery()
)
cat_group_alias = aliased(CategoryGroup, subq)
stmt = select(Category).where(Category.GroupId == cat_group_alias.GroupId)
categories_dict: dict = {cat.CategoryName: str(cat.CategoryId) for cat in session.scalars(stmt)}
# if string empty, return all category names
if not category_begin:
@@ -65,11 +66,12 @@ def autofill_groups(guild_id: int, group_begin: str) -> "dict[str, str]":
dict[str, str]: Dict of group names and ids where group name start with group_begin. Key is name, value is id.
"""
# Select all groups in guild.
stmt = select(CategoryGroup).where(CategoryGroup.GuildId == guild_id)
with Session(engine) as session:
# Select all groups in guild.
stmt = select(CategoryGroup).where(CategoryGroup.GuildId == guild_id)
# dict has to have key values of same type for discord.
group_dict: dict = {group.GroupName: str(group.GroupId) for group in session.scalars(stmt)}
# dict has to have key values of same type for discord.
group_dict: dict = {group.GroupName: str(group.GroupId) for group in session.scalars(stmt)}
# if string empty, return all group names
if not group_begin:
@@ -98,32 +100,33 @@ def autofill_users_in_group_category(guild_id: int, group_id: int, category_id:
list[str]: List of users that start with user_begin.
"""
# get all categories in the group
subq = (
select(CategoryGroup)
.where(CategoryGroup.GuildId == guild_id)
.where(CategoryGroup.GroupId == group_id)
.subquery()
)
category_group = aliased(CategoryGroup, subq)
# If no category id, get all users in group.
if category_id == 0:
subq = select(Category.CategoryId).where(Category.GroupId == category_group.GroupId)
stmt = select(distinct(Score.UserName)).where(Score.CategoryId.in_(subq))
else:
# get all users in category_id
with Session(engine) as session:
# get all categories in the group
subq = (
select(Category)
.where(Category.GroupId == category_group.GroupId)
.where(Category.CategoryId == category_id)
select(CategoryGroup)
.where(CategoryGroup.GuildId == guild_id)
.where(CategoryGroup.GroupId == group_id)
.subquery()
)
category = aliased(Category, subq)
stmt = select(distinct(Score.UserName)).where(Score.CategoryId == category.CategoryId)
category_group = aliased(CategoryGroup, subq)
users_list: "list[str]" = list(session.scalars(stmt))
# If no category id, get all users in group.
if category_id == 0:
subq = select(Category.CategoryId).where(Category.GroupId == category_group.GroupId)
stmt = select(distinct(Score.UserName)).where(Score.CategoryId.in_(subq))
else:
# get all users in category_id
subq = (
select(Category)
.where(Category.GroupId == category_group.GroupId)
.where(Category.CategoryId == category_id)
.subquery()
)
category = aliased(Category, subq)
stmt = select(distinct(Score.UserName)).where(Score.CategoryId == category.CategoryId)
users_list: "list[str]" = list(session.scalars(stmt))
# if string empty, return all users
if not user_begin:
@@ -146,10 +149,12 @@ def autofill_users_in_guild(guild_id: int, user_begin: str) -> "list[str]":
Returns:
list[str]: All users with submissions in the guild.
"""
group_ids = select(CategoryGroup.GroupId).where(CategoryGroup.GuildId == guild_id)
category_ids = select(Category.CategoryId).where(Category.GroupId.in_(group_ids))
stmt = select(distinct(Score.UserName)).where(Score.CategoryId.in_(category_ids))
users_list: "list[str]" = list(session.scalars(stmt))
with Session(engine) as session:
group_ids = select(CategoryGroup.GroupId).where(CategoryGroup.GuildId == guild_id)
category_ids = select(Category.CategoryId).where(Category.GroupId.in_(group_ids))
stmt = select(distinct(Score.UserName)).where(Score.CategoryId.in_(category_ids))
users_list: "list[str]" = list(session.scalars(stmt))
# if string empty, return all users
if not user_begin:
@@ -161,18 +166,20 @@ def autofill_users_in_guild(guild_id: int, user_begin: str) -> "list[str]":
return users
def format_highscore_message(group: CategoryGroup) -> str:
def format_highscore_message(session: Session, group: CategoryGroup) -> str:
"""
Creates a formatted string for a boss's highscore discord message.
This formatted string is in discord's code block to ensure monospace text.
Loops through each category to build the message one place at a time.
Args:
group (group): group object that contains the contents of the message.
session (Session): the sqlalchemy session used for this function call.
group (CategoryGroup): group object that contains the contents of the message.
Returns:
str: Formatted string for discord message
"""
ret_string = f"**{group.GroupName}**\n```"
stmt = select(Guild).where(Guild.GuildId == group.GuildId)
@@ -291,19 +298,23 @@ def get_time_str(time_in: float) -> str:
return time.strftime(f"%-M:%S.{milliseconds}", time.gmtime(time_in))
async def send_highscore_message(channel: nextcord.TextChannel, group: CategoryGroup) -> nextcord.Message:
async def send_highscore_message(
session: Session, channel: nextcord.TextChannel, group: CategoryGroup
) -> nextcord.Message:
"""
Function takes care of checking if a message exists for a group.
Creates and sends/edits the message.
Args:
session (Session): The sqlalchemy session being used for this function call.
channel (nextcord.TextChannel): Discord channel object where message is sent
group (CategoryGroup): group to post to the message
Returns:
nextcord.Message: Message object that was posted with group contents
"""
highscore_string = format_highscore_message(group)
highscore_string = format_highscore_message(session, group)
try:
message: nextcord.Message = await channel.fetch_message(group.MessageId)
@@ -332,37 +343,38 @@ async def submit_score(
score (str): Score to submit. Need to convert to correct type.
"""
stmt = select(Category.IsTimeRecord).where(Category.CategoryId == category_id)
is_time_record = session.scalar(stmt)
with Session(engine) as session:
stmt = select(Category.IsTimeRecord).where(Category.CategoryId == category_id)
is_time_record = session.scalar(stmt)
if is_time_record:
minutes = float(score.split(":", maxsplit=1)[0])
seconds = float(score.split(":", maxsplit=1)[1])
score = (minutes * 60) + seconds
else:
score = float(score)
if is_time_record:
minutes = float(score.split(":", maxsplit=1)[0])
seconds = float(score.split(":", maxsplit=1)[1])
score = (minutes * 60) + seconds
else:
score = float(score)
stmt = select(Score).where(Score.UserName == username).where(Score.CategoryId == category_id)
existing_score = session.scalar(stmt)
stmt = select(Score).where(Score.UserName == username).where(Score.CategoryId == category_id)
existing_score = session.scalar(stmt)
if existing_score:
existing_score.Score = score
else:
score_obj = Score(UserName=username, Score=score, CategoryId=category_id)
session.add(score_obj)
session.commit()
if existing_score:
existing_score.Score = score
else:
score_obj = Score(UserName=username, Score=score, CategoryId=category_id)
session.add(score_obj)
session.commit()
stmt = select(CategoryGroup).where(CategoryGroup.GroupId == group_id)
group = session.scalar(stmt)
stmt = select(CategoryGroup).where(CategoryGroup.GroupId == group_id)
group = session.scalar(stmt)
# edit message
channel = interaction.guild.get_channel(group.ChannelId)
# edit message
channel = interaction.guild.get_channel(group.ChannelId)
error_response = "Registered Highscores channel does not exist or was never registered."
error_response += 'Register with "/register" command.'
assert channel is not None, await interaction.send(error_response, ephemeral=True)
error_response = "Registered Highscores channel does not exist or was never registered."
error_response += 'Register with "/register" command.'
assert channel is not None, await interaction.send(error_response, ephemeral=True)
await send_highscore_message(channel, group)
await send_highscore_message(session, channel, group)
def add_preset_configuration(guild_id: int, config_str: str) -> None:
@@ -374,19 +386,21 @@ def add_preset_configuration(guild_id: int, config_str: str) -> None:
guild_id (int): Guild id to add config to
config_str (str): Config name to add
"""
with open(f"example_config/{config_str}.json", encoding="utf-8", mode="r") as file:
config = json.load(file)
for group_name, categorys in config["tables"].items():
group_obj = CategoryGroup(GroupName=group_name, GuildId=guild_id)
session.add(group_obj)
for category_name in categorys:
cat_obj = Category(
CategoryName=category_name,
Size=config["table_size"],
IsTimeRecord=config["categories"][category_name]["is_time_record"],
IsAscending=config["categories"][category_name]["ascending"],
)
session.add(cat_obj)
with Session(engine) as session:
with open(f"example_config/{config_str}.json", encoding="utf-8", mode="r") as file:
config = json.load(file)
session.commit()
for group_name, categorys in config["tables"].items():
group_obj = CategoryGroup(GroupName=group_name, GuildId=guild_id)
session.add(group_obj)
for category_name in categorys:
cat_obj = Category(
CategoryName=category_name,
Size=config["table_size"],
IsTimeRecord=config["categories"][category_name]["is_time_record"],
IsAscending=config["categories"][category_name]["ascending"],
)
session.add(cat_obj)
session.commit()