Refractor command files into single command files.

This commit is contained in:
alwayscompiling
2022-12-07 21:46:04 -05:00
parent a9920db381
commit 6c5f40f788
4 changed files with 185 additions and 134 deletions
+6 -4
View File
@@ -5,9 +5,10 @@ Cog loader. Adds all command cogs to the bot.
from nextcord.ext import commands from nextcord.ext import commands
# Command classes # Command classes
from .data_management import DataManagementCog from .delete import DeleteCog
from .message_management import MessageManagementCog from .refresh import RefreshCog
from .set import SetCog from .set import SetCog
from .update import UpdateCog
# This function will be called when this extension is loaded. # This function will be called when this extension is loaded.
@@ -16,6 +17,7 @@ def setup(bot: commands.Bot):
""" """
Adds all command classes to bot. Adds all command classes to bot.
""" """
bot.add_cog(DataManagementCog(bot)) bot.add_cog(DeleteCog())
bot.add_cog(MessageManagementCog(bot)) bot.add_cog(RefreshCog(bot))
bot.add_cog(SetCog()) bot.add_cog(SetCog())
bot.add_cog(UpdateCog(bot))
@@ -1,5 +1,5 @@
""" """
Commands for managing the tables/categories/scores for a Guild. Commands for deleting groups/categories/scores in database and messages in discord..
""" """
from typing import Optional from typing import Optional
@@ -10,7 +10,7 @@ from sqlalchemy import distinct, select
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
# pylint: disable=import-error # pylint: disable=import-error
from utilities.sql_data_classes import Category, CategoryGroup, Guild, Score, engine from utilities.sql_data_classes import Category, CategoryGroup, Score, engine
from utilities.utils import ( from utilities.utils import (
autofill_categories, autofill_categories,
autofill_groups, autofill_groups,
@@ -19,26 +19,16 @@ from utilities.utils import (
send_highscore_message, send_highscore_message,
) )
from .views.update_username_verify import UpdateUsernameVerifyView
class DeleteCog(commands.Cog, name="Table Management"):
class DataManagementCog(commands.Cog, name="Table Management"):
""" """
Class holds commands for managing the data storage of the highscores. Class holds commands for deleting.
""" """
def __init__(self, bot: commands.Bot): def __init__(self) -> None:
""" """
Default constructor for DataManagement class. Sets internal bot variable. Default constructor for DeleteCog class. Sets internal bot variable.
""" """
self._bot: commands.Bot = bot
@commands.Cog.listener()
async def on_ready(self):
"""
Called when cog is loaded. Adds views required for DataManagement commands.
"""
self._bot.add_view(UpdateUsernameVerifyView())
@nextcord.slash_command(default_member_permissions=nextcord.Permissions(administrator=True)) @nextcord.slash_command(default_member_permissions=nextcord.Permissions(administrator=True))
async def delete(self, interaction: nextcord.Interaction): async def delete(self, interaction: nextcord.Interaction):
@@ -47,15 +37,60 @@ class DataManagementCog(commands.Cog, name="Table Management"):
""" """
@delete.subcommand() @delete.subcommand()
async def user(self, interaction: nextcord.Interaction): async def all(self, interaction: nextcord.Interaction):
""" """
Subcommand parent for deleting user information. Never called. Subcommand parent for deleting everything in a group. Never called.
""" """
@user.subcommand( @all.subcommand(description="Clears highscores channel of all table messages. Does not change data.")
async def channel_messages(
self,
interaction: nextcord.Interaction,
channel: Optional[nextcord.abc.GuildChannel] = nextcord.SlashOption(
description="Channel to clear of messages.",
required=False,
channel_types=[nextcord.ChannelType.text],
default=None,
),
) -> None:
"""
Deletes all group messages from channel. Does not change data.
Does not delete highscores channel id. Uses current channel if not supplied a channel.
Args:
interaction (nextcord.Interaction): Interaction that invoked the command
channel (Optional[nextcord.abc.GuildChannel]): Channel to clear of messages.
Is a SlashOption. Limited to text channels. Defaults to None.
"""
if not channel:
channel = interaction.channel
with Session(engine) as session:
stmt = (
select(CategoryGroup)
.where(CategoryGroup.GuildId == interaction.guild_id)
.where(CategoryGroup.ChannelId == channel.id)
)
# TODO test when nothing in channel
groups = session.scalars(stmt)
await interaction.response.defer(ephemeral=True)
for group in groups:
try:
table_message: nextcord.Message = await channel.fetch_message(group.MessageId)
await table_message.delete()
except nextcord.NotFound:
# silently ignore that messages are not found. They got deleted already.
pass
await interaction.send("Table messages deleted.", ephemeral=True)
@all.subcommand(
description="Removes all of a user's scores. Warning: data is destroyed, use with case.", description="Removes all of a user's scores. Warning: data is destroyed, use with case.",
) )
async def from_all( async def users(
self, self,
interaction: nextcord.Interaction, interaction: nextcord.Interaction,
user_name: str = nextcord.SlashOption( user_name: str = nextcord.SlashOption(
@@ -89,6 +124,12 @@ class DataManagementCog(commands.Cog, name="Table Management"):
await interaction.send(f'User "{user_name}" was removed from all tables.', ephemeral=True) await interaction.send(f'User "{user_name}" was removed from all tables.', ephemeral=True)
@delete.subcommand()
async def user(self, interaction: nextcord.Interaction):
"""
Subcommand parent for deleting user information. Never called.
"""
@user.subcommand(description="Deletes a user's scores from a category.") @user.subcommand(description="Deletes a user's scores from a category.")
async def from_category( async def from_category(
self, self,
@@ -205,39 +246,7 @@ class DataManagementCog(commands.Cog, name="Table Management"):
) )
) )
@nextcord.slash_command(description="Request a username update. Admins must approve.") @users.on_autocomplete("user_name")
async def update_username(
self,
interaction: nextcord.Interaction,
old_username: str = nextcord.SlashOption(description="Username currently stored in highscores.", required=True),
new_username: str = nextcord.SlashOption(description="Username to update to.", required=True),
):
"""
Creates a request to send to admins for changing a username. Uses
UpdateUsernameVerifyView to do the work.
Args:
interaction (nextcord.Interaction): Interaction that invoked the command
old_username (str): Username to replace.
new_username (str): Username to replace old with.
"""
with Session(engine) as session:
stmt = select(Guild.VerificationChannel).where(Guild.GuildId == interaction.guild_id)
verify_channel = interaction.guild.get_channel(session.scalar(stmt))
embed: nextcord.Embed = nextcord.Embed(title="Username change request.")
embed.add_field(name="Old Username", value=old_username)
embed.add_field(name="New Username", value=new_username)
await verify_channel.send(
content=f"Username change request from <@{interaction.user.id}>.",
embed=embed,
view=UpdateUsernameVerifyView(),
)
await interaction.send("Request sent to admins for verification.", ephemeral=True)
@update_username.on_autocomplete("old_username")
@from_all.on_autocomplete("user_name")
async def username_autofill(self, interaction: nextcord.Interaction, username: str): async def username_autofill(self, interaction: nextcord.Interaction, username: str):
""" """
Sends response from autofill_users_in_guild back to update_username for autocompletion of old_username. Sends response from autofill_users_in_guild back to update_username for autocompletion of old_username.
@@ -1,9 +1,7 @@
""" """
Commands for managing/displaying the highscores messages. Commands for refreshing highscore messages.
""" """
from typing import Optional
import nextcord import nextcord
from nextcord.ext import commands from nextcord.ext import commands
from sqlalchemy import select from sqlalchemy import select
@@ -15,73 +13,63 @@ from utilities.sql_data_classes import CategoryGroup, engine
from utilities.utils import autofill_groups, send_highscore_message from utilities.utils import autofill_groups, send_highscore_message
class MessageManagementCog(commands.Cog, name="Message Management"): class RefreshCog(commands.Cog, name="Refresh Cog"):
""" """
Class holds commands for managing the messages that display highscores. Class holds commands for refreshing.
""" """
def __init__(self, bot: commands.Bot) -> None: def __init__(self, bot: commands.Bot) -> None:
""" """
Default constructor for MessageManagement class Default constructor for RefreshCog class
Args: Args:
bot (commands.Bot): Bot object. Required to register submission button view. bot (commands.Bot): Bot object. Required to register submission button view.
""" """
self.bot = bot self._bot = bot
@nextcord.slash_command( @nextcord.slash_command(default_member_permissions=nextcord.Permissions(administrator=True))
description="Clears highscores channel of all table messages. Does not change data.", async def refresh(self, interaction: nextcord.Interaction):
default_member_permissions=nextcord.Permissions(administrator=True), """
) Parent slash command for refreshing things. Never called.
async def delete_channel_messages( """
@refresh.subcommand(description="Manually refresh a table. Use when changing settings or data manually changed.")
async def group(
self, self,
interaction: nextcord.Interaction, interaction: nextcord.Interaction,
channel: Optional[nextcord.abc.GuildChannel] = nextcord.SlashOption( group_id: str = nextcord.SlashOption(name="group", description="Name of Group.", required=True),
description="Channel to clear of messages.",
required=False,
channel_types=[nextcord.ChannelType.text],
default=None,
),
) -> None: ) -> None:
""" """
Deletes all group messages from channel. Does not change data. Refreshes a table given by user.
Does not delete highscores channel id. Uses current channel if not supplied a channel.
Args: Args:
interaction (nextcord.Interaction): Interaction that invoked the command interaction (nextcord.Interaction): Interaction that invoked the command.
channel (Optional[nextcord.abc.GuildChannel]): Channel to clear of messages. group_id (str): Str representation of Group id to refresh. Is SlashOption.
Is a SlashOption. Limited to text channels. Defaults to None.
""" """
if not channel:
channel = interaction.channel
with Session(engine) as session: with Session(engine) as session:
stmt = ( stmt = (
select(CategoryGroup) select(CategoryGroup)
.where(CategoryGroup.GuildId == interaction.guild_id) .where(CategoryGroup.GuildId == interaction.guild_id)
.where(CategoryGroup.ChannelId == channel.id) .where(CategoryGroup.GroupId == int(group_id))
) )
# TODO test when nothing in channel group = session.scalar(stmt)
groups = session.scalars(stmt)
await interaction.response.defer(ephemeral=True) channel = interaction.guild.get_channel(group.ChannelId)
for group in groups: message: nextcord.Message = await send_highscore_message(session, channel, group)
try: await message.edit(view=SubmissionCreateButton(self._bot))
table_message: nextcord.Message = await channel.fetch_message(group.MessageId)
await table_message.delete()
except nextcord.NotFound:
# silently ignore that messages are not found. They got deleted already.
pass
await interaction.send("Table messages deleted.", ephemeral=True) await interaction.response.send_message(f"Updated table {group.GroupName}!", ephemeral=True)
@nextcord.slash_command( @refresh.subcommand()
description="Triggers post/update of highscores to registered highscore channel.", async def all(self, interaction: nextcord.Interaction):
default_member_permissions=nextcord.Permissions(administrator=True), """
) Subcommand parent for refreshing all things. Never called.
async def post_highscore_groups(self, interaction: nextcord.Interaction) -> None: """
@all.subcommand(description="Triggers post/update of highscores to registered highscore channels.")
async def groups(self, interaction: nextcord.Interaction) -> None:
""" """
A command which posts the highscore in the registered channel. A command which posts the highscore in the registered channel.
Sends warning if no channel has been registered. Sends warning if no channel has been registered.
@@ -108,43 +96,11 @@ class MessageManagementCog(commands.Cog, name="Message Management"):
assert channel is not None, await interaction.response(error_response, ephemeral=True) assert channel is not None, await interaction.response(error_response, ephemeral=True)
message: nextcord.Message = await send_highscore_message(session, channel, group) message: nextcord.Message = await send_highscore_message(session, channel, group)
await message.edit(view=SubmissionCreateButton(self.bot)) await message.edit(view=SubmissionCreateButton(self._bot))
await interaction.send(f"Posted all groups in {interaction.guild.name}'s highscores.", ephemeral=True) await interaction.send(f"Posted all groups in {interaction.guild.name}'s highscores.", ephemeral=True)
@nextcord.slash_command( @group.on_autocomplete("group_id")
description="Manually refresh a table. Use when changing settings or data manually changed.",
default_member_permissions=nextcord.Permissions(administrator=True),
)
async def refresh_group(
self,
interaction: nextcord.Interaction,
group_id: str = nextcord.SlashOption(name="group", description="Name of Group.", required=True),
) -> None:
"""
Refreshes a table given by user.
Args:
interaction (nextcord.Interaction): Interaction that invoked the command.
group_id (str): Str representation of Group id to refresh. Is SlashOption.
"""
with Session(engine) as session:
stmt = (
select(CategoryGroup)
.where(CategoryGroup.GuildId == interaction.guild_id)
.where(CategoryGroup.GroupId == int(group_id))
)
group = session.scalar(stmt)
channel = interaction.guild.get_channel(group.ChannelId)
message: nextcord.Message = await send_highscore_message(session, channel, group)
await message.edit(view=SubmissionCreateButton(self.bot))
await interaction.response.send_message(f"Updated table {group.GroupName}!", ephemeral=True)
@refresh_group.on_autocomplete("group_id")
async def refresh_table_autofill(self, interaction: nextcord.Interaction, group_id: str): async def refresh_table_autofill(self, interaction: nextcord.Interaction, group_id: str):
""" """
Collects list of table names and compares to input table name for autocomplete assistance. Collects list of table names and compares to input table name for autocomplete assistance.
+84
View File
@@ -0,0 +1,84 @@
"""
Commands for updating information/variables held in database.
"""
import nextcord
from nextcord.ext import commands
from sqlalchemy import select
from sqlalchemy.orm import Session
# pylint: disable=import-error
from utilities.sql_data_classes import Guild, engine
from utilities.utils import autofill_users_in_guild
from .views.update_username_verify import UpdateUsernameVerifyView
class UpdateCog(commands.Cog, name="Update commands."):
"""
Class holds commands and views needed for updating things in bot.
"""
def __init__(self, bot: commands.Bot):
"""
Default constructor for Update class. Sets internal bot variable.
Args:
bot (commands.Bot): Bot object. Required to register update username button view.
"""
self._bot: commands.Bot = bot
@commands.Cog.listener()
async def on_ready(self):
"""
Called when cog is loaded. Adds views required for DataManagement commands.
"""
self._bot.add_view(UpdateUsernameVerifyView())
@nextcord.slash_command()
async def update(self, interaction: nextcord.Interaction):
"""
Parent slash command for updating things. Never called.
"""
@update.subcommand(description="Request a username update. Admins must approve.")
async def username(
self,
interaction: nextcord.Interaction,
old_username: str = nextcord.SlashOption(description="Username currently stored in highscores.", required=True),
new_username: str = nextcord.SlashOption(description="Username to update to.", required=True),
):
"""
Creates a request to send to admins for changing a username. Uses
UpdateUsernameVerifyView to do the work.
Args:
interaction (nextcord.Interaction): Interaction that invoked the command
old_username (str): Username to replace.
new_username (str): Username to replace old with.
"""
with Session(engine) as session:
stmt = select(Guild.VerificationChannel).where(Guild.GuildId == interaction.guild_id)
verify_channel = interaction.guild.get_channel(session.scalar(stmt))
embed: nextcord.Embed = nextcord.Embed(title="Username change request.")
embed.add_field(name="Old Username", value=old_username)
embed.add_field(name="New Username", value=new_username)
await verify_channel.send(
content=f"Username change request from <@{interaction.user.id}>.",
embed=embed,
view=UpdateUsernameVerifyView(),
)
await interaction.send("Request sent to admins for verification.", ephemeral=True)
@username.on_autocomplete("old_username")
async def username_autofill(self, interaction: nextcord.Interaction, username: str):
"""
Sends response from autofill_users_in_guild back to update_username for autocompletion of old_username.
Args:
interaction (nextcord.Interaction): Interaction with command.
old_username (str): String to run autocompletion against.
"""
await interaction.response.send_autocomplete(autofill_users_in_guild(interaction.guild_id, username))