Module aethersprite.settings
Settings module; interfaced with via aethersprite.extensions.base.settings
This provides methods by which extension authors can register and use settings
in their code, and end users can manipulate those settings via bot commands
(in the aforementioned settings
extension).
Examples for registering a setting and getting/changing/resetting its value:
There are commands for doing each of these things already in the base extension mentioned above that provide authorization checks, but these are just simple examples.
from discord.ext.commands import command
from aethersprite.settings import register, settings
register("my.setting", "default value", False, lambda x: True,
"There are many settings like it, but this one is mine.")
@command()
async def check(ctx):
await ctx.send(settings["my.setting"].get(ctx))
@command()
async def change(ctx):
settings["my.setting"].set(ctx, "new value")
@command()
async def reset(ctx):
settings["my.setting"].clear(ctx)
Global variables
var settings : dict[str, Setting]
-
Setting definitions
Functions
def register(name: str,
default: typing.Any | None,
validator: typing.Callable,
channel: bool = False,
description: str | None = None,
filter: "'SettingFilter | None'" = None)-
Expand source code
def register( name: str, default: typing.Any | None, validator: typing.Callable, channel: bool = False, description: str | None = None, filter: "SettingFilter | None" = None, ): """ Register a setting. Args: name: The name of the setting default: The default value if none is provided validator: The validation function for the setting's value channel: If this is a channel (and not a guild) setting filter: The filter to use for setting/getting values """ global settings if name in settings: raise Exception(f"Setting already exists: {name}") settings[name] = Setting( name, default, validator, channel, description, filter=filter )
Register a setting.
Args
name
- The name of the setting
default
- The default value if none is provided
validator
- The validation function for the setting's value
channel
- If this is a channel (and not a guild) setting
filter
- The filter to use for setting/getting values
Classes
class Setting (name: str,
default: typing.Any | None,
validate: typing.Callable,
channel: bool = False,
description: str | None = None,
filter: "'SettingFilter | None'" = None)-
Expand source code
class Setting(object): """Setting class; represents an individual setting definition""" # Setting values _values = SqliteDict( f"{data_folder}settings.sqlite3", tablename="values", autocommit=True ) def __init__( self, name: str, default: typing.Any | None, validate: typing.Callable, channel: bool = False, description: str | None = None, filter: "SettingFilter | None" = None, ): if name is None: raise ValueError("Name must not be None") self.name = name """The setting's name""" self.default = default """Default value""" self.validate = validate """Validator function""" self.channel = channel """If this is a channel (and not a guild) setting""" self.description = description """This setting's description""" self.filter = filter """The filter used to manipulate setting input/output""" def _ctxkey(self, ctx: Context, channel: int | None = None) -> str: """ Get the key to use when storing/accessing the setting. Args: ctx: The Discord connection context channel: The channel (if not the same as the context) Returns: The composite key """ assert ctx.guild key = str( ctx.guild["id"] if isinstance(ctx.guild, dict) else ctx.guild.id ) if self.channel: key += f"#{ctx.channel.id if channel is None else channel}" return key def set( self, ctx: Context, value: str | None, raw: bool = False, channel: int | None = None, ) -> bool: """ Change the setting's value. Args: ctx: The Discord connection context value: The value to assign (or ``None`` for the default) raw: Set to True to bypass filtering channel: The channel (if not the same as the context) Returns: Success """ key = self._ctxkey(ctx, channel) vals = self._values[key] if key in self._values else {} try: if not raw and self.filter is not None: filtered = self.filter.in_(ctx, value) if filtered is None: return False value = filtered except ValueError: return False if value is None: vals[self.name] = self.default else: if not self.validate(value): return False vals[self.name] = value self._values[key] = vals return True def get( self, ctx: Context, raw: bool = False, channel: int | None = None ) -> typing.Any | None: """ Get the setting's value. Args: ctx: The Discord connection context raw: Set to True to bypass filtering channel: The channel (if not the same as the context) Returns: The setting's value """ key = self._ctxkey(ctx, channel) val = ( self._values[key][self.name] if key in self._values and self.name in self._values[key] else None ) if not raw and self.filter is not None: val = self.filter.out(ctx, val) return self.default if val is None else val
Setting class; represents an individual setting definition
Instance variables
var channel
-
If this is a channel (and not a guild) setting
var default
-
Default value
var description
-
This setting's description
var filter
-
The filter used to manipulate setting input/output
var name
-
The setting's name
var validate
-
Validator function
Methods
def get(self, ctx: Context, raw: bool = False, channel: int | None = None) ‑> typing.Any | None
-
Expand source code
def get( self, ctx: Context, raw: bool = False, channel: int | None = None ) -> typing.Any | None: """ Get the setting's value. Args: ctx: The Discord connection context raw: Set to True to bypass filtering channel: The channel (if not the same as the context) Returns: The setting's value """ key = self._ctxkey(ctx, channel) val = ( self._values[key][self.name] if key in self._values and self.name in self._values[key] else None ) if not raw and self.filter is not None: val = self.filter.out(ctx, val) return self.default if val is None else val
Get the setting's value.
Args
ctx
- The Discord connection context
raw
- Set to True to bypass filtering
channel
- The channel (if not the same as the context)
Returns
The setting's value
def set(self,
ctx: Context,
value: str | None,
raw: bool = False,
channel: int | None = None) ‑> bool-
Expand source code
def set( self, ctx: Context, value: str | None, raw: bool = False, channel: int | None = None, ) -> bool: """ Change the setting's value. Args: ctx: The Discord connection context value: The value to assign (or ``None`` for the default) raw: Set to True to bypass filtering channel: The channel (if not the same as the context) Returns: Success """ key = self._ctxkey(ctx, channel) vals = self._values[key] if key in self._values else {} try: if not raw and self.filter is not None: filtered = self.filter.in_(ctx, value) if filtered is None: return False value = filtered except ValueError: return False if value is None: vals[self.name] = self.default else: if not self.validate(value): return False vals[self.name] = value self._values[key] = vals return True
Change the setting's value.
Args
ctx
- The Discord connection context
value
- The value to assign (or
None
for the default) raw
- Set to True to bypass filtering
channel
- The channel (if not the same as the context)
Returns
Success