Compare commits

...

27 commits

Author SHA1 Message Date
4e09380351 Merge pull request 'Refactor Pterodactyl cog to use aiohttp' (#2) from aiohttp-refactor into main
Reviewed-on: https://git.seaswimmer.cc/GalacticFactory/GalacticCogs/pulls/2
2023-07-24 09:29:54 -04:00
ec5daee2de
cleanup: removed requests from imports 2023-07-24 09:25:09 -04:00
610e9902a9
fix: stop was using requests still and erroring because of it 2023-07-24 09:25:00 -04:00
6ec35134fd
fix: added a 10s delay to the power commands 2023-07-24 09:17:25 -04:00
db764b54e2
fix: fixed power_action_in_progress 2023-07-24 09:16:17 -04:00
3ed6cffe5d
fix: awaited some things inside power commands 2023-07-24 09:06:56 -04:00
dcd3560fbc
fix: fixed power and update commands' error checking 2023-07-24 09:04:58 -04:00
20a6d89f3d
feat: power commands now check if another power command is in progress and error if they are 2023-07-24 09:02:15 -04:00
7451a2e625
fix: power commands now use aiohttp instead of requests 2023-07-24 09:01:06 -04:00
72e7d83bd7
cleanup: removed obsolete method 2023-07-24 08:59:45 -04:00
ae4d794258
feat: added additional configuration option - used internally 2023-07-24 08:59:01 -04:00
d5b4ac3dbe
fix: hopefully fixed the broken update command 2023-07-24 08:45:53 -04:00
fb99f5ea33
misc: reduced sleep timer for server status checking 2023-07-23 23:09:34 -04:00
35e80fdbb3
misc: changed sleep duration on UpdateButtons to 1 second 2023-07-23 14:34:58 -04:00
ef662d81b1
fix: applied previous fix to UpdateButtons 2023-07-23 14:32:49 -04:00
1bf60cef81
fix: testing a fix for update 2023-07-23 14:29:07 -04:00
fa48b3a924
fix: changed something in the updatebuttons class 2023-07-23 14:13:35 -04:00
6079ccd371
fix: fixed a missing await 2023-07-23 14:11:26 -04:00
601a9642c7
fix: fixed update command again 2023-07-23 14:08:15 -04:00
5398fb77a8
fix: fixed update command 2023-07-23 14:05:03 -04:00
85fa243732
fix: hopefully made update work properly 2023-07-23 14:04:02 -04:00
7727f789f2
fix: fixed get_session trying to assign a kwarg that doesn't exist 2023-07-23 12:55:27 -04:00
0f73bbaabc
fix: fixed get_session 2023-07-23 12:52:59 -04:00
a2488a53bd
fix: and again! (configure commands this time) 2023-07-23 12:51:10 -04:00
45b6c94f06
fix: same thing as last commit, just with get_url 2023-07-23 12:50:44 -04:00
fed6790122
fix: fixed power commands failing to load 2023-07-23 12:49:58 -04:00
f10178e948
feat: update now uses aiohttp 2023-07-23 12:39:44 -04:00

View file

@ -1,10 +1,10 @@
import asyncio import asyncio
import aiohttp import aiohttp
import discord import discord
import requests
from discord import ui from discord import ui
from discord.ext import commands from discord.ext import commands
from redbot.core import commands, app_commands, Config from redbot.core import Config, app_commands, commands
class Pterodactyl(commands.Cog): class Pterodactyl(commands.Cog):
"""Pterodactyl allows you to manage your Pterodactyl Panel from Discord.""" """Pterodactyl allows you to manage your Pterodactyl Panel from Discord."""
@ -17,8 +17,16 @@ class Pterodactyl(commands.Cog):
api_key=None, api_key=None,
server_id=None, server_id=None,
startup_jar=None, startup_jar=None,
startup_arguments=None startup_arguments=None,
power_action_in_progress=False
) )
self.session: aiohttp.ClientSession = None
async def cog_load(self):
self.session = aiohttp.ClientSession()
async def cog_unload(self):
await self.session.close()
async def get_headers(self, guild: discord.Guild): async def get_headers(self, guild: discord.Guild):
"""Returns the headers used to access the Pterodactyl API.""" """Returns the headers used to access the Pterodactyl API."""
@ -44,22 +52,17 @@ class Pterodactyl(commands.Cog):
url += '/' + endpoint url += '/' + endpoint
return url return url
async def put(self, url: str, headers: dict, data: dict):
"""Sends an asyncio PUT request to the specified URL with the specified headers and data."""
async with aiohttp.ClientSession() as session:
async with session.put(url, headers=headers, json=data) as response:
return response
@app_commands.command(name="update", description="Updates the server.") @app_commands.command(name="update", description="Updates the server.")
@app_commands.guild_only() @app_commands.guild_only()
async def update(self, interaction: discord.Interaction): async def update(self, interaction: discord.Interaction):
"""Updates the server using the arguments provided in the server's configuration.""" """Updates the server using the arguments provided in the server's configuration."""
if await self.config.guild(interaction.guild).power_action_in_progress() is True:
await interaction.response.send_message(ephemeral=True, content="Power action already in progress!\nTry again later.")
return
session = self.session
await interaction.response.defer(ephemeral=True, thinking=True) await interaction.response.defer(ephemeral=True, thinking=True)
interaction_message = await interaction.original_response() interaction_message = await interaction.original_response()
if await self.config.guild(interaction.guild).api_key() is None: if await self.config.guild(interaction.guild).startup_jar() is None:
await interaction_message.edit(f"Something went wrong.\nError: `API Key not set.`", ephemeral=True)
raise LookupError("API Key not set.")
elif await self.config.guild(interaction.guild).startup_jar() is None:
await interaction_message.edit(f"Something went wrong.\nError: `Startup jar not set.`", ephemeral=True) await interaction_message.edit(f"Something went wrong.\nError: `Startup jar not set.`", ephemeral=True)
raise LookupError("Startup jar not set.") raise LookupError("Startup jar not set.")
elif await self.config.guild(interaction.guild).startup_arguments() is None: elif await self.config.guild(interaction.guild).startup_arguments() is None:
@ -68,11 +71,15 @@ class Pterodactyl(commands.Cog):
else: else:
startup_jar = await self.config.guild(interaction.guild).startup_jar() startup_jar = await self.config.guild(interaction.guild).startup_jar()
startup_commands = await self.config.guild(interaction.guild).startup_arguments() startup_commands = await self.config.guild(interaction.guild).startup_arguments()
try:
headers = await self.get_headers(interaction.guild) headers = await self.get_headers(interaction.guild)
response = requests.get(await self.get_url(interaction.guild, "resources"), headers=headers) except LookupError as e:
response_dict = response.json() await interaction_message.edit(f"Something went wrong.\nError: `{e}`", ephemeral=True)
list_var = requests.get(await self.get_url(interaction.guild, "startup"), headers=headers) return
list_var_response_dict = list_var.json() async with session.get(await self.get_url(interaction.guild, "resources"), headers=headers) as response:
response_dict = await response.json()
async with session.get(await self.get_url(interaction.guild, "startup"), headers=headers) as response:
list_var_response_dict = await response.json()
updater_startup_vars = [ updater_startup_vars = [
{ {
"key": "FLAGS", "key": "FLAGS",
@ -94,24 +101,25 @@ class Pterodactyl(commands.Cog):
} }
] ]
if response_dict['attributes']['current_state'] == "offline": if response_dict['attributes']['current_state'] == "offline":
await self.config.guild(interaction.guild).power_action_in_progress.set(True)
for data in updater_startup_vars: for data in updater_startup_vars:
await self.put(await self.get_url(interaction.guild, "startup/variable"), headers, data) await session.put(await self.get_url(interaction.guild, "startup/variable"), headers=headers, json=data)
requests.post(await self.get_url(interaction.guild, "power"), headers=headers, json={"signal": "start"}) await session.post(await self.get_url(interaction.guild, "power"), headers=headers, json={"signal": "start"})
await interaction_message.edit(content="Updater started...") await interaction_message.edit(content="Updater started...")
await asyncio.sleep(1) await asyncio.sleep(1)
while True: while True:
async with aiohttp.ClientSession() as session: async with session.get(await self.get_url(interaction.guild, "resources"), headers=headers) as response:
async with session.get(await self.get_url(interaction.guild, "resources"), headers=headers) as response: response_dict = await response.json()
response_dict = await response.json() if response_dict['attributes']['current_state'] == "offline":
if response_dict['attributes']['current_state'] == "offline": await interaction_message.edit(content="Updater finished.")
await interaction_message.edit(content="Updater finished.") break
break else:
else: await asyncio.sleep(0.5)
await asyncio.sleep(1) continue
continue
for data in old_startup_vars: for data in old_startup_vars:
await self.put(await self.get_url(interaction.guild, "startup/variable"), headers, data) await session.put(await self.get_url(interaction.guild, "startup/variable"), headers=headers, json=data)
await interaction_message.edit(content="Updater finished.\nUpdate process completed!") await interaction_message.edit(content="Updater finished.\nUpdate process completed!")
await self.config.guild(interaction.guild).power_action_in_progress.set(False)
elif response_dict['attributes']['current_state'] == "running" or response_dict['attributes']['current_state'] == "starting": elif response_dict['attributes']['current_state'] == "running" or response_dict['attributes']['current_state'] == "starting":
passed_info = { passed_info = {
"headers": headers, "headers": headers,
@ -120,20 +128,23 @@ class Pterodactyl(commands.Cog):
"interaction": interaction, "interaction": interaction,
"guild": interaction.guild, "guild": interaction.guild,
} }
await interaction_message.edit(content="The server is already running! Are you sure you'd like to stop the server for updates?", view=self.UpdateButtons(timeout=180, passed_info=passed_info)) await interaction_message.edit(content="The server is already running! Are you sure you'd like to stop the server for updates?", view=self.UpdateButtons(timeout=180, passed_info=passed_info, session=session))
power = app_commands.Group(name='power', description="Controls the server's power state.") power = app_commands.Group(name='power', description="Controls the server's power state.")
@power.command(name='start', description="Starts the server.") @power.command(name='start', description="Starts the server.")
@power.guild_only() @app_commands.guild_only()
async def start(self, interaction: discord.Interaction): async def start(self, interaction: discord.Interaction):
"""Starts the server.""" """Starts the server."""
if await self.config.guild(interaction.guild).power_action_in_progress() is True:
await interaction.response.send_message(ephemeral=True, content="Power action already in progress!\nTry again later.")
return
await interaction.response.defer(ephemeral=True, thinking=True) await interaction.response.defer(ephemeral=True, thinking=True)
interaction_message = await interaction.original_response() interaction_message = await interaction.original_response()
headers = await self.get_headers(interaction.guild) headers = await self.get_headers(interaction.guild)
response = requests.get(await self.get_url(interaction.guild, "resources"), headers=headers) async with self.session.get(await self.get_url(interaction.guild, "resources"), headers=headers) as response:
requests_json = response.json() response_json = await response.json()
current_status = requests_json['attributes']['current_state'] current_status = response_json['attributes']['current_state']
if current_status == "offline": if current_status == "offline":
passed_info = { passed_info = {
"headers": headers, "headers": headers,
@ -144,21 +155,24 @@ class Pterodactyl(commands.Cog):
"message": "Server starting...", "message": "Server starting...",
"completed_message": "Server started!" "completed_message": "Server started!"
} }
await interaction_message.edit(content="Are you sure you'd like to start the server?", view=self.PowerButtons(timeout=180, passed_info=passed_info)) await interaction_message.edit(content="Are you sure you'd like to start the server?", view=self.PowerButtons(timeout=180, passed_info=passed_info, session=self.session))
else: else:
message = await interaction_message.edit(content="The server is already running!") message = await interaction_message.edit(content="The server is already running!")
await message.delete(delay=3) await message.delete(delay=3)
@power.command(name='restart', description="Restarts the server.") @power.command(name='restart', description="Restarts the server.")
@power.guild_only() @app_commands.guild_only()
async def restart(self, interaction: discord.Interaction): async def restart(self, interaction: discord.Interaction):
"""Restarts the server.""" """Restarts the server."""
if await self.config.guild(interaction.guild).power_action_in_progress() is True:
await interaction.response.send_message(ephemeral=True, content="Power action already in progress!\nTry again later.")
return
await interaction.response.defer(ephemeral=True, thinking=True) await interaction.response.defer(ephemeral=True, thinking=True)
interaction_message = await interaction.original_response() interaction_message = await interaction.original_response()
headers = await self.get_headers(interaction.guild) headers = await self.get_headers(interaction.guild)
response = requests.get(await self.get_url(interaction.guild, "resources"), headers=headers) async with self.session.get(await self.get_url(interaction.guild, "resources"), headers=headers) as response:
requests_json = response.json() response_json = await response.json()
current_status = requests_json['attributes']['current_state'] current_status = response_json['attributes']['current_state']
if current_status == "running": if current_status == "running":
passed_info = { passed_info = {
"headers": headers, "headers": headers,
@ -169,7 +183,7 @@ class Pterodactyl(commands.Cog):
"message": "Server restarting...", "message": "Server restarting...",
"completed_message": "Server restarted!" "completed_message": "Server restarted!"
} }
await interaction_message.edit(content="Are you sure you'd like to restart the server?", view=self.PowerButtons(timeout=180, passed_info=passed_info)) await interaction_message.edit(content="Are you sure you'd like to restart the server?", view=self.PowerButtons(timeout=180, passed_info=passed_info, session=self.session))
elif current_status == "offline": elif current_status == "offline":
message = await interaction_message.edit(content="The server is offline!") message = await interaction_message.edit(content="The server is offline!")
await message.delete(delay=3) await message.delete(delay=3)
@ -178,15 +192,18 @@ class Pterodactyl(commands.Cog):
await message.delete(delay=3) await message.delete(delay=3)
@power.command(name='stop', description="Stops the server.") @power.command(name='stop', description="Stops the server.")
@power.guild_only() @app_commands.guild_only()
async def stop(self, interaction: discord.Interaction): async def stop(self, interaction: discord.Interaction):
"""Stops the server.""" """Stops the server."""
if await self.config.guild(interaction.guild).power_action_in_progress() is True:
await interaction.response.send_message(ephemeral=True, content="Power action already in progress!\nTry again later.")
return
await interaction.response.defer(ephemeral=True, thinking=True) await interaction.response.defer(ephemeral=True, thinking=True)
interaction_message = await interaction.original_response() interaction_message = await interaction.original_response()
headers = await self.get_headers(interaction.guild) headers = await self.get_headers(interaction.guild)
response = requests.get(await self.get_url(interaction.guild, "resources"), headers=headers) async with self.session.get(await self.get_url(interaction.guild, "resources"), headers=headers) as response:
requests_json = response.json() response_json = await response.json()
current_status = requests_json['attributes']['current_state'] current_status = response_json['attributes']['current_state']
if current_status == "running" or current_status == "starting": if current_status == "running" or current_status == "starting":
passed_info = { passed_info = {
"headers": headers, "headers": headers,
@ -197,62 +214,62 @@ class Pterodactyl(commands.Cog):
"message": "Server stopping...", "message": "Server stopping...",
"completed_message": "Server stopped!" "completed_message": "Server stopped!"
} }
await interaction_message.edit(content="Are you sure you'd like to stop the server?", view=self.PowerButtons(timeout=180, passed_info=passed_info)) await interaction_message.edit(content="Are you sure you'd like to stop the server?", view=self.PowerButtons(timeout=180, passed_info=passed_info, session=self.session))
elif current_status == "offline": elif current_status == "offline":
message = await interaction_message.edit(content="The server is already offline!") message = await interaction_message.edit(content="The server is already offline!")
await message.delete(delay=3) await message.delete(delay=3)
class UpdateButtons(ui.View): class UpdateButtons(ui.View):
def __init__(self, timeout, passed_info): def __init__(self, timeout, passed_info, session: aiohttp.ClientSession):
super().__init__() super().__init__()
self.passed_info = passed_info self.passed_info = passed_info
self.session = session
self.config = Config.get_conf(None, cog_name='Pterodactyl', identifier=457581387213637448123567) self.config = Config.get_conf(None, cog_name='Pterodactyl', identifier=457581387213637448123567)
@ui.button(label="Yes", style=discord.ButtonStyle.success) @ui.button(label="Yes", style=discord.ButtonStyle.success)
async def yes_button(self, button:ui.Button, interaction:discord.Interaction): async def yes_button(self, button:ui.Button, interaction:discord.Interaction):
headers = self.passed_info['headers'] await self.config.guild(self.passed_info['guild']).power_action_in_progress.set(True)
requests.post(await Pterodactyl.get_url(self, self.passed_info['guild'], "power"), headers=headers, json={"signal": "stop"}) session = self.session
await session.post(await Pterodactyl.get_url(self, self.passed_info['guild'], "power"), headers=self.passed_info['headers'], json={"signal": "stop"})
await self.passed_info['interaction'].edit_original_response(content="Server stopping...", view=None) await self.passed_info['interaction'].edit_original_response(content="Server stopping...", view=None)
while True: while True:
async with aiohttp.ClientSession() as session: async with session.get(await Pterodactyl.get_url(self, self.passed_info['guild'], "resources"), headers=self.passed_info['headers']) as response:
async with session.get(await Pterodactyl.get_url(self, self.passed_info['guild'], "resources"), headers=headers) as response: response_dict = await response.json()
response_dict = await response.json() if response_dict['attributes']['current_state'] == "offline":
if response_dict['attributes']['current_state'] == "offline": await self.passed_info['interaction'].edit_original_response(content="\nServer stopped!")
await self.passed_info['interaction'].edit_original_response(content="\nServer stopped!") break
break else:
else: await asyncio.sleep(0.5)
await asyncio.sleep(2) continue
continue
for data in self.passed_info['updater_startup_vars']: for data in self.passed_info['updater_startup_vars']:
await Pterodactyl.put(self, url=await Pterodactyl.get_url(self, self.passed_info['guild'], "startup/variable"), headers=headers, data=data) await session.put(url=await Pterodactyl.get_url(self, self.passed_info['guild'], "startup/variable"), headers=self.passed_info['headers'], json=data)
requests.post(url=await Pterodactyl.get_url(self, self.passed_info['guild'], "power"), headers=headers, json={"signal": "start"}) await session.post(url=await Pterodactyl.get_url(self, self.passed_info['guild'], "power"), headers=self.passed_info['headers'], json={"signal": "start"})
await self.passed_info['interaction'].edit_original_response(content="Updater started...") await self.passed_info['interaction'].edit_original_response(content="Updater started...")
await asyncio.sleep(2) await asyncio.sleep(2)
while True: while True:
async with aiohttp.ClientSession() as session: async with session.get(await Pterodactyl.get_url(self, self.passed_info['guild'], "resources"), headers=self.passed_info['headers']) as response:
async with session.get(await Pterodactyl.get_url(self, self.passed_info['guild'], "resources"), headers=headers) as response: response_dict = await response.json()
response_dict = await response.json() if response_dict['attributes']['current_state'] == "offline":
if response_dict['attributes']['current_state'] == "offline": await self.passed_info['interaction'].edit_original_response(content="Updater finished!")
await self.passed_info['interaction'].edit_original_response(content="Updater finished!") break
break else:
else: await asyncio.sleep(1)
await asyncio.sleep(1) continue
continue
for data in self.passed_info['old_startup_vars']: for data in self.passed_info['old_startup_vars']:
await Pterodactyl.put(self, await Pterodactyl.get_url(self, self.passed_info['guild'], "startup/variable"), headers, data) await session.put(await Pterodactyl.get_url(self, self.passed_info['guild'], "startup/variable"), headers=self.passed_info['headers'], json=data)
await asyncio.sleep(2) await asyncio.sleep(2)
requests.post(url=await Pterodactyl.get_url(self, self.passed_info['guild'], "power"), headers=headers, json={"signal": "start"}) await session.post(url=await Pterodactyl.get_url(self, self.passed_info['guild'], "power"), headers=self.passed_info['headers'], json={"signal": "start"})
await self.passed_info['interaction'].edit_original_response(content="Server starting...") await self.passed_info['interaction'].edit_original_response(content="Server starting...")
while True: while True:
async with aiohttp.ClientSession() as session: async with session.get(await Pterodactyl.get_url(self, self.passed_info['guild'], "resources"), headers=self.passed_info['headers']) as response:
async with session.get(await Pterodactyl.get_url(self, self.passed_info['guild'], "resources"), headers=headers) as response: response_dict = await response.json()
response_dict = await response.json() if response_dict['attributes']['current_state'] == "running":
if response_dict['attributes']['current_state'] == "running": await self.passed_info['interaction'].edit_original_response(content="Server started!\nUpdate process completed!")
await self.passed_info['interaction'].edit_original_response(content="Server started!\nUpdate process completed!") break
break else:
else: await asyncio.sleep(0.5)
await asyncio.sleep(1) continue
continue await self.config.guild(self.passed_info['guild']).power_action_in_progress.set(False)
@ui.button(label="No", style=discord.ButtonStyle.danger) @ui.button(label="No", style=discord.ButtonStyle.danger)
async def no_button(self, button:ui.Button, interaction:discord.Interaction): async def no_button(self, button:ui.Button, interaction:discord.Interaction):
@ -260,26 +277,29 @@ class Pterodactyl(commands.Cog):
await message.delete(delay=3) await message.delete(delay=3)
class PowerButtons(ui.View): class PowerButtons(ui.View):
def __init__(self, timeout, passed_info): def __init__(self, timeout, passed_info, session: aiohttp.ClientSession):
super().__init__() super().__init__()
self.passed_info = passed_info self.passed_info = passed_info
self.session = session
self.config = Config.get_conf(None, cog_name='Pterodactyl', identifier=457581387213637448123567) self.config = Config.get_conf(None, cog_name='Pterodactyl', identifier=457581387213637448123567)
@ui.button(label="Yes", style=discord.ButtonStyle.success) @ui.button(label="Yes", style=discord.ButtonStyle.success)
async def yes_button(self, button:ui.Button, interaction:discord.Interaction): async def yes_button(self, button:ui.Button, interaction:discord.Interaction):
await self.config.guild(self.passed_info['guild']).power_action_in_progress.set(True)
headers = self.passed_info['headers'] headers = self.passed_info['headers']
requests.post(await Pterodactyl.get_url(self, self.passed_info['guild'], "power"), headers=headers, json={"signal": self.passed_info['signal']}) await self.session.post(await Pterodactyl.get_url(self, self.passed_info['guild'], "power"), headers=headers, json={"signal": self.passed_info['signal']})
message = await self.passed_info['interaction'].edit_original_response(content=self.passed_info['message'], view=None) message = await self.passed_info['interaction'].edit_original_response(content=self.passed_info['message'], view=None)
await asyncio.sleep(10)
while True: while True:
async with aiohttp.ClientSession() as session: async with self.session.get(await Pterodactyl.get_url(self, self.passed_info['guild'], "resources"), headers=headers) as response:
async with session.get(await Pterodactyl.get_url(self, self.passed_info['guild'], "resources"), headers=headers) as response: response_dict = await response.json()
response_dict = await response.json() if response_dict['attributes']['current_state'] == self.passed_info['target_signal']:
if response_dict['attributes']['current_state'] == self.passed_info['target_signal']: await message.edit(content=self.passed_info['completed_message'])
await message.edit(content=self.passed_info['completed_message']) break
break else:
else: await asyncio.sleep(1)
await asyncio.sleep(1) continue
continue await self.config.guild(self.passed_info['guild']).power_action_in_progress.set(False)
@ui.button(label="No", style=discord.ButtonStyle.danger) @ui.button(label="No", style=discord.ButtonStyle.danger)
async def no_button(self, button:ui.Button, interaction:discord.Interaction): async def no_button(self, button:ui.Button, interaction:discord.Interaction):
@ -290,7 +310,7 @@ class Pterodactyl(commands.Cog):
get_group = app_commands.Group(name='get', description="Retrieves information from the Pterodactyl API.") get_group = app_commands.Group(name='get', description="Retrieves information from the Pterodactyl API.")
@get_group.command(name='url', description="Retrieves the URL for the specified endpoint.") @get_group.command(name='url', description="Retrieves the URL for the specified endpoint.")
@get_group.guild_only() @app_commands.guild_only()
async def retrieve_url(self, interaction: discord.Interaction, endpoint: str = None): async def retrieve_url(self, interaction: discord.Interaction, endpoint: str = None):
"""Retrieves the URL for the specified endpoint.""" """Retrieves the URL for the specified endpoint."""
try: try:
@ -306,13 +326,13 @@ class Pterodactyl(commands.Cog):
configure = app_commands.Group(name="config", description="Configures the Pterodactyl cog.") configure = app_commands.Group(name="config", description="Configures the Pterodactyl cog.")
@configure.command(name="api", description="Sets the information used to access the Pterodactyl API.") @configure.command(name="api", description="Sets the information used to access the Pterodactyl API.")
@configure.guild_only() @app_commands.guild_only()
async def configure_api(self, interaction: discord.Interaction): async def configure_api(self, interaction: discord.Interaction):
"""Sets the information used to access the Pterdoactyl API.""" """Sets the information used to access the Pterdoactyl API."""
await interaction.response.send_modal(self.APIConfigModal(self.config)) await interaction.response.send_modal(self.APIConfigModal(self.config))
@configure.command(name="update", description="Sets the startup arguments for the update command.") @configure.command(name="update", description="Sets the startup arguments for the update command.")
@configure.guild_only() @app_commands.guild_only()
async def configure_update(self, interaction: discord.Interaction): async def configure_update(self, interaction: discord.Interaction):
"""Sets the startup arguments for the update command.""" """Sets the startup arguments for the update command."""
await interaction.response.send_modal(self.StartupConfigModal(self.config)) await interaction.response.send_modal(self.StartupConfigModal(self.config))