Package aethersprite

Aethersprite Discord bot/framework

Sub-modules

aethersprite.authz

Authorization module

aethersprite.common

Common functions module

aethersprite.emotes

Emote constants

aethersprite.extensions

Aethersprite extensions

aethersprite.filters

Setting filters module

aethersprite.settings

Settings module; interfaced with via aethersprite.extensions.base.settings

aethersprite.webapp

Web application

Global variables

var activity

Activity on login

var bot

The bot itself

var config

Configuration

var log

Root logger instance

Functions

async def entrypoint()
Expand source code
async def entrypoint():
    token = config["bot"].get("token", environ.get("DISCORD_TOKEN", None))
    # need credentials
    assert token is not None, (
        "bot.token not in config and DISCORD_TOKEN not in env variables"
    )
    # for any commands or scheduled tasks, etc. that need random numbers
    seed()
    bot.remove_command("help")
    bot.add_command(help_proxy)

    # probe extensions for bot hooks
    for ext in config["bot"]["extensions"]:
        await _load_ext(ext)

    if log.level >= logging.DEBUG:
        for key, evs in bot.extra_events.items():
            out = []

            for f in evs:
                out.append(f"{f.__module__}:{f.__name__}")

            log.debug(f"{key} => {out!r}")

    # here we go!
    await bot.start(token=token)
def get_prefixes(bot: discord.ext.commands.bot.Bot, message: discord.message.Message)
Expand source code
def get_prefixes(bot: Bot, message: Message):
    from .settings import settings

    assert bot.user
    user_id = bot.user.id
    base = [f"<@!{user_id}> ", f"<@{user_id}> "]
    default = [config.get("bot", {}).get("prefix", "!")]

    if "prefix" not in settings:
        return base + default

    prefix = settings["prefix"].get(message)  # type: ignore

    if prefix is None:
        return base + default

    return base + [prefix]
async def on_command_error(ctx: discord.ext.commands.context.Context, error: Exception)
Expand source code
@bot.event
async def on_command_error(ctx: Context, error: Exception):
    """Suppress command check failures and invalid commands."""

    from .extensions.base.alias import Alias

    if isinstance(error, CheckFailure):
        return

    if isinstance(error, CommandNotFound):
        if isinstance(ctx.channel, DMChannel):
            return

        bot: Bot = ctx.bot
        cog: Alias | None = bot.get_cog("Alias")  # type: ignore

        if cog is None:
            return

        assert ctx.guild
        guild = str(ctx.guild.id)
        aliases = cog.aliases[guild] if guild in cog.aliases else None

        if aliases is None:
            return

        assert ctx.prefix
        name = ctx.message.content.replace(ctx.prefix, "").split(" ")[0].strip()

        if name not in aliases:
            return

        cmd = ctx.bot.get_command(aliases[name])

        if cmd is None:
            return

        ctx.command = cmd

        return await ctx.bot.invoke(ctx)

    raise error

Suppress command check failures and invalid commands.

async def on_connect()
Expand source code
@bot.event
async def on_connect():
    log.info("Connected to Discord")
async def on_disconnect()
Expand source code
@bot.event
async def on_disconnect():
    log.info("Disconnected")
async def on_error(method: str, *args, **kwargs)
Expand source code
@bot.event
async def on_error(method: str, *args, **kwargs):
    log.exception(f"Error in method {method}\nargs: {args}\nkwargs: {kwargs}\n")
async def on_ready()
Expand source code
@bot.event
async def on_ready():
    log.info(f"Logged in as {bot.user}")
    await bot.change_presence(activity=activity)
async def on_resumed()
Expand source code
@bot.event
async def on_resumed():
    log.info("Connection resumed")