|
|
@@ -2,7 +2,7 @@
|
|
2
|
2
|
A guild configuration setting available for editing via bot commands.
|
|
3
|
3
|
"""
|
|
4
|
4
|
from datetime import timedelta
|
|
5
|
|
-from typing import Any, Optional, Type, TypeVar, Literal
|
|
|
5
|
+from typing import Any, Optional, Type, Literal
|
|
6
|
6
|
|
|
7
|
7
|
from discord import Interaction, Permissions
|
|
8
|
8
|
from discord.app_commands import Range, Transform, describe
|
|
|
@@ -11,7 +11,7 @@ from discord.ext.commands import Bot
|
|
11
|
11
|
|
|
12
|
12
|
from config import CONFIG
|
|
13
|
13
|
from rocketbot.storage import Storage
|
|
14
|
|
-from rocketbot.utils import bot_log, TimeDeltaTransformer, MOD_PERMISSIONS
|
|
|
14
|
+from rocketbot.utils import bot_log, TimeDeltaTransformer, MOD_PERMISSIONS, dump_stacktrace
|
|
15
|
15
|
|
|
16
|
16
|
# def _fix_command(command: Command) -> None:
|
|
17
|
17
|
# """
|
|
|
@@ -22,8 +22,6 @@ from rocketbot.utils import bot_log, TimeDeltaTransformer, MOD_PERMISSIONS
|
|
22
|
22
|
# del params['context']
|
|
23
|
23
|
# command.params = params
|
|
24
|
24
|
|
|
25
|
|
-BaseCog = TypeVar('BaseCog', bound='rocketbot.cogs.BaseCog')
|
|
26
|
|
-
|
|
27
|
25
|
class CogSetting:
|
|
28
|
26
|
"""
|
|
29
|
27
|
Describes a configuration setting for a guild that can be edited by the
|
|
|
@@ -97,7 +95,7 @@ class CogSetting:
|
|
97
|
95
|
allowed_values = '`' + ('`, `'.join(self.enum_values)) + '`'
|
|
98
|
96
|
raise ValueError(f'`{self.name}` must be one of {allowed_values}')
|
|
99
|
97
|
|
|
100
|
|
- def set_up(self, cog: BaseCog, bot: Bot) -> None:
|
|
|
98
|
+ def set_up(self, cog: 'BaseCog', bot: Bot) -> None:
|
|
101
|
99
|
"""
|
|
102
|
100
|
Sets up getter and setter commands for this setting. This should
|
|
103
|
101
|
usually only be called by BaseCog.
|
|
|
@@ -115,11 +113,11 @@ class CogSetting:
|
|
115
|
113
|
return native_value
|
|
116
|
114
|
|
|
117
|
115
|
def to_native_value(self, stored_value: Any) -> Any:
|
|
118
|
|
- if self.datatype is timedelta:
|
|
|
116
|
+ if self.datatype is timedelta and isinstance(stored_value, (int, float)):
|
|
119
|
117
|
return timedelta(seconds=stored_value)
|
|
120
|
118
|
return stored_value
|
|
121
|
119
|
|
|
122
|
|
- def __make_getter_command(self, cog: BaseCog) -> Command:
|
|
|
120
|
+ def __make_getter_command(self, cog: 'BaseCog') -> Command:
|
|
123
|
121
|
setting: CogSetting = self
|
|
124
|
122
|
setting_name = setting.name
|
|
125
|
123
|
if cog.config_prefix is not None:
|
|
|
@@ -161,12 +159,13 @@ class CogSetting:
|
|
161
|
159
|
)
|
|
162
|
160
|
return command
|
|
163
|
161
|
|
|
164
|
|
- def __make_setter_command(self, cog: BaseCog) -> Command:
|
|
|
162
|
+ def __make_setter_command(self, cog: 'BaseCog') -> Command:
|
|
|
163
|
+ from rocketbot.cogs.basecog import BaseCog
|
|
165
|
164
|
setting: CogSetting = self
|
|
166
|
165
|
setting_name = setting.name
|
|
167
|
166
|
if cog.config_prefix is not None:
|
|
168
|
167
|
setting_name = f'{cog.config_prefix}_{setting_name}'
|
|
169
|
|
- async def setter_general(self, interaction: Interaction, new_value) -> None:
|
|
|
168
|
+ async def setter_general(cog0: BaseCog, interaction: Interaction, new_value) -> None:
|
|
170
|
169
|
print(f"invoking setter for {setting_name} with value {new_value}")
|
|
171
|
170
|
try:
|
|
172
|
171
|
setting.validate_value(new_value)
|
|
|
@@ -176,14 +175,14 @@ class CogSetting:
|
|
176
|
175
|
ephemeral=True
|
|
177
|
176
|
)
|
|
178
|
177
|
return
|
|
179
|
|
- key = f'{self.__class__.__name__}.{setting.name}'
|
|
|
178
|
+ key = f'{cog0.__class__.__name__}.{setting.name}'
|
|
180
|
179
|
Storage.set_config_value(interaction.guild, key, setting.to_stored_value(new_value))
|
|
181
|
180
|
await interaction.response.send_message(
|
|
182
|
181
|
f'{CONFIG["success_emoji"]} `{setting_name}` is now set to `{new_value}`',
|
|
183
|
182
|
ephemeral=True
|
|
184
|
183
|
)
|
|
185
|
|
- await self.on_setting_updated(interaction.guild, setting)
|
|
186
|
|
- self.log(interaction.guild, f'{interaction.user.name} set {key} to {new_value}')
|
|
|
184
|
+ await cog0.on_setting_updated(interaction.guild, setting)
|
|
|
185
|
+ cog0.log(interaction.guild, f'{interaction.user.name} set {key} to {new_value}')
|
|
187
|
186
|
|
|
188
|
187
|
setter: CommandCallback = setter_general
|
|
189
|
188
|
if self.datatype == int:
|
|
|
@@ -254,7 +253,8 @@ class CogSetting:
|
|
254
|
253
|
)
|
|
255
|
254
|
return command
|
|
256
|
255
|
|
|
257
|
|
- def __make_enable_command(self, cog: BaseCog) -> Command:
|
|
|
256
|
+ def __make_enable_command(self, cog: 'BaseCog') -> Command:
|
|
|
257
|
+ from rocketbot.cogs.basecog import BaseCog
|
|
258
|
258
|
setting: CogSetting = self
|
|
259
|
259
|
async def enabler(cog0: BaseCog, interaction: Interaction) -> None:
|
|
260
|
260
|
print(f"invoking enable for {cog0.config_prefix}")
|
|
|
@@ -284,7 +284,8 @@ class CogSetting:
|
|
284
|
284
|
)
|
|
285
|
285
|
return command
|
|
286
|
286
|
|
|
287
|
|
- def __make_disable_command(self, cog: BaseCog) -> Command:
|
|
|
287
|
+ def __make_disable_command(self, cog: 'BaseCog') -> Command:
|
|
|
288
|
+ from rocketbot.cogs.basecog import BaseCog
|
|
288
|
289
|
setting: CogSetting = self
|
|
289
|
290
|
async def disabler(cog0: BaseCog, interaction: Interaction) -> None:
|
|
290
|
291
|
print(f"invoking disable for {cog0.config_prefix}")
|
|
|
@@ -321,7 +322,7 @@ class CogSetting:
|
|
321
|
322
|
__disable_group: Group
|
|
322
|
323
|
|
|
323
|
324
|
@classmethod
|
|
324
|
|
- def set_up_all(cls, cog: BaseCog, bot: Bot, settings: list['CogSetting']) -> None:
|
|
|
325
|
+ def set_up_all(cls, cog: 'BaseCog', bot: Bot, settings: list['CogSetting']) -> None:
|
|
325
|
326
|
"""
|
|
326
|
327
|
Sets up editing commands for a list of CogSettings and adds them to a
|
|
327
|
328
|
cog. If the cog has a command Group, commands will be added to it.
|
|
|
@@ -380,3 +381,50 @@ class CogSetting:
|
|
380
|
381
|
bot.tree.add_command(cls.__get_group)
|
|
381
|
382
|
bot.tree.add_command(cls.__enable_group)
|
|
382
|
383
|
bot.tree.add_command(cls.__disable_group)
|
|
|
384
|
+
|
|
|
385
|
+ from rocketbot.cogs.basecog import BaseCog
|
|
|
386
|
+ async def show_all(interaction: Interaction) -> None:
|
|
|
387
|
+ try:
|
|
|
388
|
+ guild = interaction.guild
|
|
|
389
|
+ if guild is None:
|
|
|
390
|
+ await interaction.response.send_message(
|
|
|
391
|
+ f'{CONFIG["error_emoji"]} No guild.',
|
|
|
392
|
+ ephemeral=True,
|
|
|
393
|
+ delete_after=10,
|
|
|
394
|
+ )
|
|
|
395
|
+ return
|
|
|
396
|
+ text = '## :information_source: Configuration'
|
|
|
397
|
+ for cog_name, cog in sorted(bot.cogs.items()):
|
|
|
398
|
+ if not isinstance(cog, BaseCog):
|
|
|
399
|
+ continue
|
|
|
400
|
+ bcog: BaseCog = cog
|
|
|
401
|
+ if len(bcog.settings) == 0:
|
|
|
402
|
+ continue
|
|
|
403
|
+ text += f'\n### {bcog.qualified_name} Module'
|
|
|
404
|
+ for setting in sorted(bcog.settings, key=lambda s: (s.name != 'enabled', s.name)):
|
|
|
405
|
+ key = f'{bcog.__class__.__name__}.{setting.name}'
|
|
|
406
|
+ value = setting.to_native_value(Storage.get_config_value(guild, key))
|
|
|
407
|
+ deflt = setting.to_native_value(bcog.get_cog_default(setting.name))
|
|
|
408
|
+ if setting.name == 'enabled':
|
|
|
409
|
+ text += f'\n- Module is '
|
|
|
410
|
+ if value is not None:
|
|
|
411
|
+ text += '**' + ('enabled' if value else 'disabled') + '**'
|
|
|
412
|
+ else:
|
|
|
413
|
+ text += ('enabled' if deflt else 'disabled') + ' _(using default)_'
|
|
|
414
|
+ else:
|
|
|
415
|
+ if value is not None:
|
|
|
416
|
+ text += f'\n- `{bcog.config_prefix}_{setting.name}` = **{value}**'
|
|
|
417
|
+ else:
|
|
|
418
|
+ text += f'\n- `{bcog.config_prefix}_{setting.name}` = {deflt} _(using default)_'
|
|
|
419
|
+ await interaction.response.send_message(
|
|
|
420
|
+ text,
|
|
|
421
|
+ ephemeral=True,
|
|
|
422
|
+ )
|
|
|
423
|
+ except BaseException as e:
|
|
|
424
|
+ dump_stacktrace(e)
|
|
|
425
|
+ show_all_command = Command(
|
|
|
426
|
+ name='all',
|
|
|
427
|
+ description='Shows all configuration for this guild.',
|
|
|
428
|
+ callback=show_all,
|
|
|
429
|
+ )
|
|
|
430
|
+ cls.__get_group.add_command(show_all_command)
|