Skip to content

API: classes

classes.structs.Module

Module

Container for a loaded feature module.

Holds metadata (name, description, version, color), the module's interface returned by its setup() function, exported commands (text and slash), guild/user settings, and event listeners registered by the module.

Source code in classes/structs/Module.py
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
class Module:
    """Container for a loaded feature module.

    Holds metadata (name, description, version, color), the module's interface
    returned by its `setup()` function, exported commands (text and slash),
    guild/user settings, and event listeners registered by the module.
    """

    def __init__(
        self,
        name: str,
        path: str,
        description: str,
        version: str,
        color: str,
        logger: Logger,
        init_func: Callable[["ExtendedClient", Any, Logger], Any],
        data: Manifest,
        commands: Optional[Dict[str, Dict[str, Any]]] = None,
        interfacer: Optional[Any] = None,
        settings: Optional[List[Setting[Any]]] = None,
        user_settings: Optional[List[Setting[Any]]] = None,
    ):
        """Initialize the module container.

        Args:
            name: Human‑readable module name.
            path: Absolute/relative filesystem path to the module directory.
            description: Short description of the module purpose.
            version: Semantic version string.
            color: Hex color (used in embeds or UI).
            logger: Logger used for this module.
            init_func: Callable returned by the module's `setup()` (executed via `initialize`).
            data: Parsed manifest describing folders and metadata.
            commands: Maps of commands grouped by kind, e.g. {"text": {}, "slash": {}}.
            interfacer: Arbitrary interface object/dict exported by the module.
            settings: Guild‑scoped settings declared by the module.
            user_settings: Member‑scoped settings declared by the module.
        """

        self.name = name
        self.path = path
        self.description = description
        self.version = version
        self.color = color
        self.logger = logger
        self.init_func = init_func
        self.data = data
        self.commands = commands or {"text": {}, "slash": {}}
        self.interfacer = interfacer or {}
        self.settings = settings or []
        self.user_settings = user_settings or []
        self.events: List[Dict[str, Callable]] = []  # Store registered events


    async def unload(self, bot: commands.Bot, sync: Optional[str] = None, guild_id: Optional[str] = None):
        """Unload this module's commands and events from the bot.

        Removes all registered text and slash commands and detaches listeners
        previously recorded via `register_event`.

        Args:
            bot: Discord bot/client instance.
            sync: Optional post‑unload sync mode: `"global"` or `"guild"`.
            guild_id: Guild id to sync if `sync == "guild"`.
        """
        for command_name, command in self.commands["text"].items():
            bot.remove_command(command.name)
            self.logger.info(f"Removed text command '{command_name}' from module '{self.name}'.")

        for command_name, command in self.commands["slash"].items():
            bot.tree.remove_command(command.name)
            self.logger.info(f"Removed slash command '{command_name}' from module '{self.name}'.")

        for event in self.events:
            try:
                bot.remove_listener(event["func"], event["event"])
                self.logger.info(f"Removed event listener '{event['event']}' from module '{self.name}'.")
            except Exception as e:
                self.logger.error(f"Failed to remove event listener '{event['event']}': {e}")

        self.commands = {"text": {}, "slash": {}}
        self.events = []

        # Sincronização opcional dos comandos
        if sync == "global":
            await bot.tree.sync()
            self.logger.info("Commands synchronized globally after unload.")
        elif sync == "guild" and guild_id:
            guild = Object(id=int(guild_id))
            await bot.tree.sync(guild=guild)
            self.logger.info(f"Commands synchronized for guild ID {guild_id} after unload.")


    async def reload(self, bot: commands.Bot, sync: Optional[str] = None, guild_id: Optional[int] = None):
        """Reload the module by unloading then re‑wiring commands and events.

        Args:
            bot: Discord bot/client instance.
            sync: Post‑reload sync mode: `'none'`, `'global'`, or `'guild'`.
            guild_id: Guild id to sync if `sync == 'guild'`.
        """
        await self.unload(bot)

        commands_folder = Path(self.path) / self.data.commands_folder
        base_package = f"modules.{self.name}.commands"
        await self.bot.command_handler.load_commands_from_folder(commands_folder, base_package, self)

        events_folder = Path(self.path) / self.data.events_folder
        if events_folder.exists():
            await self.bot.event_handler.load_events_from_module(self.name, Path(self.path), [events_folder])

        if sync == "global":
            await self.bot.tree.sync()
            self.logger.info(f"Slash commands globally synced after reloading module '{self.name}'.")
        elif sync == "guild" and guild_id:
            guild = Object(id=guild_id)
            await self.bot.tree.sync(guild=guild)
            self.logger.info(f"Slash commands synced for guild {guild_id} after reloading module '{self.name}'.")
        elif sync == "none" or sync is None:
            self.logger.info(f"No slash command synchronization performed for module '{self.name}'.")



    def register_event(self, event: str, func: Callable):
        """Record an event listener belonging to this module.

        The handler is later removed during `unload`.

        Args:
            event: Discord.py event name, e.g. `"on_message"`.
            func: Listener callable.
        """
        self.events.append({"event": event, "func": func})

    def add_setting(self, setting: Setting[Any]):
        """Add a guild‑scoped setting declared by the module.

        Args:
            setting: A `Setting` instance to append.
        """
        self.settings.append(setting)

    def add_user_setting(self, setting: Setting[Any]):
        """Add a member‑scoped setting declared by the module.

        Args:
            setting: A `Setting` instance to append.
        """
        self.user_settings.append(setting)

    async def initialize(self, client: "ExtendedClient", module_data: Any):
        """Execute the module’s initialization function.

        The `init_func` is the callable returned by the module's `setup()` and is
        responsible for returning the `interfacer` (helpers the module exposes).

        Args:
            client: Extended bot client.
            module_data: Arbitrary data passed from the loader.

        Returns:
            None. The `interfacer` is stored on the instance.
        """
        self.interfacer = await self.init_func(client, module_data, self.logger)

__init__(name, path, description, version, color, logger, init_func, data, commands=None, interfacer=None, settings=None, user_settings=None)

Initialize the module container.

Parameters:

Name Type Description Default
name str

Human‑readable module name.

required
path str

Absolute/relative filesystem path to the module directory.

required
description str

Short description of the module purpose.

required
version str

Semantic version string.

required
color str

Hex color (used in embeds or UI).

required
logger Logger

Logger used for this module.

required
init_func Callable[[ExtendedClient, Any, Logger], Any]

Callable returned by the module's setup() (executed via initialize).

required
data Manifest

Parsed manifest describing folders and metadata.

required
commands Optional[Dict[str, Dict[str, Any]]]

Maps of commands grouped by kind, e.g. {"text": {}, "slash": {}}.

None
interfacer Optional[Any]

Arbitrary interface object/dict exported by the module.

None
settings Optional[List[Setting[Any]]]

Guild‑scoped settings declared by the module.

None
user_settings Optional[List[Setting[Any]]]

Member‑scoped settings declared by the module.

None
Source code in classes/structs/Module.py
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
def __init__(
    self,
    name: str,
    path: str,
    description: str,
    version: str,
    color: str,
    logger: Logger,
    init_func: Callable[["ExtendedClient", Any, Logger], Any],
    data: Manifest,
    commands: Optional[Dict[str, Dict[str, Any]]] = None,
    interfacer: Optional[Any] = None,
    settings: Optional[List[Setting[Any]]] = None,
    user_settings: Optional[List[Setting[Any]]] = None,
):
    """Initialize the module container.

    Args:
        name: Human‑readable module name.
        path: Absolute/relative filesystem path to the module directory.
        description: Short description of the module purpose.
        version: Semantic version string.
        color: Hex color (used in embeds or UI).
        logger: Logger used for this module.
        init_func: Callable returned by the module's `setup()` (executed via `initialize`).
        data: Parsed manifest describing folders and metadata.
        commands: Maps of commands grouped by kind, e.g. {"text": {}, "slash": {}}.
        interfacer: Arbitrary interface object/dict exported by the module.
        settings: Guild‑scoped settings declared by the module.
        user_settings: Member‑scoped settings declared by the module.
    """

    self.name = name
    self.path = path
    self.description = description
    self.version = version
    self.color = color
    self.logger = logger
    self.init_func = init_func
    self.data = data
    self.commands = commands or {"text": {}, "slash": {}}
    self.interfacer = interfacer or {}
    self.settings = settings or []
    self.user_settings = user_settings or []
    self.events: List[Dict[str, Callable]] = []  # Store registered events

add_setting(setting)

Add a guild‑scoped setting declared by the module.

Parameters:

Name Type Description Default
setting Setting[Any]

A Setting instance to append.

required
Source code in classes/structs/Module.py
144
145
146
147
148
149
150
def add_setting(self, setting: Setting[Any]):
    """Add a guild‑scoped setting declared by the module.

    Args:
        setting: A `Setting` instance to append.
    """
    self.settings.append(setting)

add_user_setting(setting)

Add a member‑scoped setting declared by the module.

Parameters:

Name Type Description Default
setting Setting[Any]

A Setting instance to append.

required
Source code in classes/structs/Module.py
152
153
154
155
156
157
158
def add_user_setting(self, setting: Setting[Any]):
    """Add a member‑scoped setting declared by the module.

    Args:
        setting: A `Setting` instance to append.
    """
    self.user_settings.append(setting)

initialize(client, module_data) async

Execute the module’s initialization function.

The init_func is the callable returned by the module's setup() and is responsible for returning the interfacer (helpers the module exposes).

Parameters:

Name Type Description Default
client ExtendedClient

Extended bot client.

required
module_data Any

Arbitrary data passed from the loader.

required

Returns:

Type Description

None. The interfacer is stored on the instance.

Source code in classes/structs/Module.py
160
161
162
163
164
165
166
167
168
169
170
171
172
173
async def initialize(self, client: "ExtendedClient", module_data: Any):
    """Execute the module’s initialization function.

    The `init_func` is the callable returned by the module's `setup()` and is
    responsible for returning the `interfacer` (helpers the module exposes).

    Args:
        client: Extended bot client.
        module_data: Arbitrary data passed from the loader.

    Returns:
        None. The `interfacer` is stored on the instance.
    """
    self.interfacer = await self.init_func(client, module_data, self.logger)

register_event(event, func)

Record an event listener belonging to this module.

The handler is later removed during unload.

Parameters:

Name Type Description Default
event str

Discord.py event name, e.g. "on_message".

required
func Callable

Listener callable.

required
Source code in classes/structs/Module.py
133
134
135
136
137
138
139
140
141
142
def register_event(self, event: str, func: Callable):
    """Record an event listener belonging to this module.

    The handler is later removed during `unload`.

    Args:
        event: Discord.py event name, e.g. `"on_message"`.
        func: Listener callable.
    """
    self.events.append({"event": event, "func": func})

reload(bot, sync=None, guild_id=None) async

Reload the module by unloading then re‑wiring commands and events.

Parameters:

Name Type Description Default
bot Bot

Discord bot/client instance.

required
sync Optional[str]

Post‑reload sync mode: 'none', 'global', or 'guild'.

None
guild_id Optional[int]

Guild id to sync if sync == 'guild'.

None
Source code in classes/structs/Module.py
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
async def reload(self, bot: commands.Bot, sync: Optional[str] = None, guild_id: Optional[int] = None):
    """Reload the module by unloading then re‑wiring commands and events.

    Args:
        bot: Discord bot/client instance.
        sync: Post‑reload sync mode: `'none'`, `'global'`, or `'guild'`.
        guild_id: Guild id to sync if `sync == 'guild'`.
    """
    await self.unload(bot)

    commands_folder = Path(self.path) / self.data.commands_folder
    base_package = f"modules.{self.name}.commands"
    await self.bot.command_handler.load_commands_from_folder(commands_folder, base_package, self)

    events_folder = Path(self.path) / self.data.events_folder
    if events_folder.exists():
        await self.bot.event_handler.load_events_from_module(self.name, Path(self.path), [events_folder])

    if sync == "global":
        await self.bot.tree.sync()
        self.logger.info(f"Slash commands globally synced after reloading module '{self.name}'.")
    elif sync == "guild" and guild_id:
        guild = Object(id=guild_id)
        await self.bot.tree.sync(guild=guild)
        self.logger.info(f"Slash commands synced for guild {guild_id} after reloading module '{self.name}'.")
    elif sync == "none" or sync is None:
        self.logger.info(f"No slash command synchronization performed for module '{self.name}'.")

unload(bot, sync=None, guild_id=None) async

Unload this module's commands and events from the bot.

Removes all registered text and slash commands and detaches listeners previously recorded via register_event.

Parameters:

Name Type Description Default
bot Bot

Discord bot/client instance.

required
sync Optional[str]

Optional post‑unload sync mode: "global" or "guild".

None
guild_id Optional[str]

Guild id to sync if sync == "guild".

None
Source code in classes/structs/Module.py
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
async def unload(self, bot: commands.Bot, sync: Optional[str] = None, guild_id: Optional[str] = None):
    """Unload this module's commands and events from the bot.

    Removes all registered text and slash commands and detaches listeners
    previously recorded via `register_event`.

    Args:
        bot: Discord bot/client instance.
        sync: Optional post‑unload sync mode: `"global"` or `"guild"`.
        guild_id: Guild id to sync if `sync == "guild"`.
    """
    for command_name, command in self.commands["text"].items():
        bot.remove_command(command.name)
        self.logger.info(f"Removed text command '{command_name}' from module '{self.name}'.")

    for command_name, command in self.commands["slash"].items():
        bot.tree.remove_command(command.name)
        self.logger.info(f"Removed slash command '{command_name}' from module '{self.name}'.")

    for event in self.events:
        try:
            bot.remove_listener(event["func"], event["event"])
            self.logger.info(f"Removed event listener '{event['event']}' from module '{self.name}'.")
        except Exception as e:
            self.logger.error(f"Failed to remove event listener '{event['event']}': {e}")

    self.commands = {"text": {}, "slash": {}}
    self.events = []

    # Sincronização opcional dos comandos
    if sync == "global":
        await bot.tree.sync()
        self.logger.info("Commands synchronized globally after unload.")
    elif sync == "guild" and guild_id:
        guild = Object(id=int(guild_id))
        await bot.tree.sync(guild=guild)
        self.logger.info(f"Commands synchronized for guild ID {guild_id} after unload.")

classes.structs.Guild

Guild

Wrapper for a Discord guild with bot-specific data and settings.

Exposes
  • guild: the underlying Discord guild object
  • data: the backing database document
  • settings: resolved module settings for this guild
  • permission_overrides: parsed permission overrides
  • flags: feature/behavior flags for the guild
Source code in classes/structs/Guild.py
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
class Guild:
    """Wrapper for a Discord guild with bot-specific data and settings.

    Exposes:
      - `guild`: the underlying Discord guild object
      - `data`: the backing database document
      - `settings`: resolved module settings for this guild
      - `permission_overrides`: parsed permission overrides
      - `flags`: feature/behavior flags for the guild
    """

    def __init__(self, client: ExtendedClient, guild: DiscordGuild, guild_data: Dict[str, Any], settings: Dict[str, "Setting"]):
        """Create a hydrated Guild wrapper.

        Args:
            client: Extended bot client.
            guild: Discord guild object.
            guild_data: Backing DB document for this guild.
            settings: Map of resolved settings (id → `Setting`).
        """
        self.client = client
        self.guild = guild
        self.data = guild_data
        self.settings = settings
        self.permission_overrides = Permissions(client.logger, parse_from_database(guild_data.get("permissions_overrides", [])))
        self.id = guild.id
        self.flags = ObjectFlags(client, self)


    def get_setting(self, setting_id: str) -> Optional["Setting"]:
        """Return a setting by id for this guild.

        Args:
            setting_id: Identifier of the setting.

        Returns:
            The `Setting` instance or `None` if missing.
        """
        return self.settings.get(setting_id)

__init__(client, guild, guild_data, settings)

Create a hydrated Guild wrapper.

Parameters:

Name Type Description Default
client ExtendedClient

Extended bot client.

required
guild Guild

Discord guild object.

required
guild_data Dict[str, Any]

Backing DB document for this guild.

required
settings Dict[str, Setting]

Map of resolved settings (id → Setting).

required
Source code in classes/structs/Guild.py
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
def __init__(self, client: ExtendedClient, guild: DiscordGuild, guild_data: Dict[str, Any], settings: Dict[str, "Setting"]):
    """Create a hydrated Guild wrapper.

    Args:
        client: Extended bot client.
        guild: Discord guild object.
        guild_data: Backing DB document for this guild.
        settings: Map of resolved settings (id → `Setting`).
    """
    self.client = client
    self.guild = guild
    self.data = guild_data
    self.settings = settings
    self.permission_overrides = Permissions(client.logger, parse_from_database(guild_data.get("permissions_overrides", [])))
    self.id = guild.id
    self.flags = ObjectFlags(client, self)

get_setting(setting_id)

Return a setting by id for this guild.

Parameters:

Name Type Description Default
setting_id str

Identifier of the setting.

required

Returns:

Type Description
Optional[Setting]

The Setting instance or None if missing.

Source code in classes/structs/Guild.py
44
45
46
47
48
49
50
51
52
53
def get_setting(self, setting_id: str) -> Optional["Setting"]:
    """Return a setting by id for this guild.

    Args:
        setting_id: Identifier of the setting.

    Returns:
        The `Setting` instance or `None` if missing.
    """
    return self.settings.get(setting_id)

classes.structs.Member

Member

Wrapper for a Discord member within a guild.

Holds
  • the Discord Member and User objects
  • the parent Guild wrapper
  • the member profile data from the database
  • resolved user-level settings (as declared by modules)
  • flags for feature toggles or state
Source code in classes/structs/Member.py
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
class Member:
    """Wrapper for a Discord member within a guild.

    Holds:
      - the Discord `Member` and `User` objects
      - the parent `Guild` wrapper
      - the member profile `data` from the database
      - resolved user-level `settings` (as declared by modules)
      - `flags` for feature toggles or state
    """

    def __init__(
        self,
        client: ExtendedClient,
        member: Member,
        guild: Guild,
        settings: Dict[str, Setting[Any]],
        data: Dict[str, Any],
    ):
        """Initialize the member wrapper.

        Args:
            client: Extended bot client.
            member: Discord member object.
            guild: Hydrated guild wrapper the member belongs to.
            settings: Resolved user settings (id → `Setting`).
            data: Backing DB document for this member.
        """
        self.id: int = member.id
        self.member: DiscordMember = member
        self.user: DiscordUser = member._user  # Access the Discord User object from Member
        self.client: ExtendedClient = client
        self.data: Dict[str, Any] = data
        self.guild: Guild = guild
        self.settings: Dict[str, Setting[Any]] = defaultdict(lambda: None, settings)
        self.flags: ObjectFlags = ObjectFlags(client, self)

    @property
    def display_name(self) -> str:
        """Return the preferred display name.

        Returns:
            The server nickname (`Member.display_name`) if present, otherwise the
            global username from the `User` object.
        """
        return self.member.display_name if self.member else self.user.name

    def get_setting(self, key: str) -> Optional[Any]:
        """Retrieve a user setting value by id.

        Args:
            key: Setting identifier.

        Returns:
            The `Setting` instance or `None` if missing.
        """
        return self.settings.get(key)

    def set_setting(self, key: str, value: Any) -> None:
        """Update or insert a user setting in-memory.

        Args:
            key: Setting identifier.
            value: New setting value (not persisted yet).
        """
        self.settings[key] = value

    def has_flag(self, flag: str) -> bool:
        """Return whether the member has a specific flag set.

        Args:
            flag: Flag key.

        Returns:
            True if the flag is set truthy, otherwise False.
        """
        return self.flags.has(flag)

    def set_flag(self, flag: str, value: Any) -> None:
        """Set or update a flag for this member (in-memory).

        Args:
            flag: Flag key.
            value: Value to assign.
        """
        self.flags.set(flag, value)

    def to_dict(self) -> Dict[str, Any]:
        """Serialize main member data for diagnostics or persistence.

        Returns:
            A dict with user id, name, serialized settings and flags.
        """
        return {
            "id": self.id,
            "name": self.user.name,
            "settings": {key: setting.to_dict() for key, setting in self.settings.items()},
            "flags": self.flags.to_dict(),
        }

    def __repr__(self) -> str:
        """
        Return a string representation of the Member object.
        """
        return f"<Member id={self.id} name={self.user.name} settings={len(self.settings)}>"

display_name property

Return the preferred display name.

Returns:

Type Description
str

The server nickname (Member.display_name) if present, otherwise the

str

global username from the User object.

__init__(client, member, guild, settings, data)

Initialize the member wrapper.

Parameters:

Name Type Description Default
client ExtendedClient

Extended bot client.

required
member Member

Discord member object.

required
guild Guild

Hydrated guild wrapper the member belongs to.

required
settings Dict[str, Setting[Any]]

Resolved user settings (id → Setting).

required
data Dict[str, Any]

Backing DB document for this member.

required
Source code in classes/structs/Member.py
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
def __init__(
    self,
    client: ExtendedClient,
    member: Member,
    guild: Guild,
    settings: Dict[str, Setting[Any]],
    data: Dict[str, Any],
):
    """Initialize the member wrapper.

    Args:
        client: Extended bot client.
        member: Discord member object.
        guild: Hydrated guild wrapper the member belongs to.
        settings: Resolved user settings (id → `Setting`).
        data: Backing DB document for this member.
    """
    self.id: int = member.id
    self.member: DiscordMember = member
    self.user: DiscordUser = member._user  # Access the Discord User object from Member
    self.client: ExtendedClient = client
    self.data: Dict[str, Any] = data
    self.guild: Guild = guild
    self.settings: Dict[str, Setting[Any]] = defaultdict(lambda: None, settings)
    self.flags: ObjectFlags = ObjectFlags(client, self)

__repr__()

Return a string representation of the Member object.

Source code in classes/structs/Member.py
115
116
117
118
119
def __repr__(self) -> str:
    """
    Return a string representation of the Member object.
    """
    return f"<Member id={self.id} name={self.user.name} settings={len(self.settings)}>"

get_setting(key)

Retrieve a user setting value by id.

Parameters:

Name Type Description Default
key str

Setting identifier.

required

Returns:

Type Description
Optional[Any]

The Setting instance or None if missing.

Source code in classes/structs/Member.py
62
63
64
65
66
67
68
69
70
71
def get_setting(self, key: str) -> Optional[Any]:
    """Retrieve a user setting value by id.

    Args:
        key: Setting identifier.

    Returns:
        The `Setting` instance or `None` if missing.
    """
    return self.settings.get(key)

has_flag(flag)

Return whether the member has a specific flag set.

Parameters:

Name Type Description Default
flag str

Flag key.

required

Returns:

Type Description
bool

True if the flag is set truthy, otherwise False.

Source code in classes/structs/Member.py
82
83
84
85
86
87
88
89
90
91
def has_flag(self, flag: str) -> bool:
    """Return whether the member has a specific flag set.

    Args:
        flag: Flag key.

    Returns:
        True if the flag is set truthy, otherwise False.
    """
    return self.flags.has(flag)

set_flag(flag, value)

Set or update a flag for this member (in-memory).

Parameters:

Name Type Description Default
flag str

Flag key.

required
value Any

Value to assign.

required
Source code in classes/structs/Member.py
 93
 94
 95
 96
 97
 98
 99
100
def set_flag(self, flag: str, value: Any) -> None:
    """Set or update a flag for this member (in-memory).

    Args:
        flag: Flag key.
        value: Value to assign.
    """
    self.flags.set(flag, value)

set_setting(key, value)

Update or insert a user setting in-memory.

Parameters:

Name Type Description Default
key str

Setting identifier.

required
value Any

New setting value (not persisted yet).

required
Source code in classes/structs/Member.py
73
74
75
76
77
78
79
80
def set_setting(self, key: str, value: Any) -> None:
    """Update or insert a user setting in-memory.

    Args:
        key: Setting identifier.
        value: New setting value (not persisted yet).
    """
    self.settings[key] = value

to_dict()

Serialize main member data for diagnostics or persistence.

Returns:

Type Description
Dict[str, Any]

A dict with user id, name, serialized settings and flags.

Source code in classes/structs/Member.py
102
103
104
105
106
107
108
109
110
111
112
113
def to_dict(self) -> Dict[str, Any]:
    """Serialize main member data for diagnostics or persistence.

    Returns:
        A dict with user id, name, serialized settings and flags.
    """
    return {
        "id": self.id,
        "name": self.user.name,
        "settings": {key: setting.to_dict() for key, setting in self.settings.items()},
        "flags": self.flags.to_dict(),
    }

classes.structs.Command

Command

Decorator-style wrapper for a text (prefix) command.

Captures a function and registers it into discord.ext.commands using the provided metadata (name, description, aliases).

Source code in classes/structs/Command.py
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
class Command:
    """Decorator-style wrapper for a text (prefix) command.

    Captures a function and registers it into `discord.ext.commands` using the
    provided metadata (name, description, aliases).
    """

    def __init__(
        self,
        name: str,
        description: str,
        how_to_use: str,
        aliases: Optional[List[str]] = None,
        logger: Optional[logging.Logger] = None,
    ):
        """Create a command descriptor.

        Args:
            name: Command name (prefix-based).
            description: Short description for help.
            how_to_use: Usage string to display in help.
            aliases: Optional list of alternate names.
            logger: Optional logger; defaults to a logger named after `name`.
        """
        self.name = name
        self.description = description
        self.how_to_use = how_to_use
        self.aliases = aliases or []
        self.logger = logger or logging.getLogger(name)
        self.func: Optional[Callable] = None  # Placeholder for the decorated function

    def __call__(self, func: Callable) -> "Command":
        """Decorator entrypoint to bind the underlying function.

        Args:
            func: The implementation function.

        Returns:
            The same `Command` instance, now pointing to `func`.
        """
        self.func = func  # Capture the decorated function
        return self

    def get_command_function(self) -> Callable:
        """Return the bound implementation function.

        Raises:
            RuntimeError: If no function has been bound via the decorator.
        """
        if not self.func:
            raise RuntimeError(f"Command '{self.name}' has no associated function.")
        return self.func

    def register(self, bot: commands.Bot):
        """Register this command with the bot's command registry.

        Wraps the original function into a discord.py command callback and
        attaches it to the bot.

        Args:
            bot: The Discord bot to register against.
        """
        async def wrapped(ctx, *args, **kwargs):
            if self.func is None:
                raise RuntimeError(f"Command '{self.name}' has no associated function to call.")
            await self.func(
                client=bot,
                message=ctx.message,
                args=args,
                profile=None,
                logger=self.logger,
                guild=ctx.guild,
                interfacer=None,
                used_name=self.name,
            )

        bot.command(
            name=self.name,
            description=self.description,
            aliases=self.aliases,
        )(wrapped)

        print(f"Registered command '{self.name}' with the bot.")

__call__(func)

Decorator entrypoint to bind the underlying function.

Parameters:

Name Type Description Default
func Callable

The implementation function.

required

Returns:

Type Description
Command

The same Command instance, now pointing to func.

Source code in classes/structs/Command.py
36
37
38
39
40
41
42
43
44
45
46
def __call__(self, func: Callable) -> "Command":
    """Decorator entrypoint to bind the underlying function.

    Args:
        func: The implementation function.

    Returns:
        The same `Command` instance, now pointing to `func`.
    """
    self.func = func  # Capture the decorated function
    return self

__init__(name, description, how_to_use, aliases=None, logger=None)

Create a command descriptor.

Parameters:

Name Type Description Default
name str

Command name (prefix-based).

required
description str

Short description for help.

required
how_to_use str

Usage string to display in help.

required
aliases Optional[List[str]]

Optional list of alternate names.

None
logger Optional[Logger]

Optional logger; defaults to a logger named after name.

None
Source code in classes/structs/Command.py
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
def __init__(
    self,
    name: str,
    description: str,
    how_to_use: str,
    aliases: Optional[List[str]] = None,
    logger: Optional[logging.Logger] = None,
):
    """Create a command descriptor.

    Args:
        name: Command name (prefix-based).
        description: Short description for help.
        how_to_use: Usage string to display in help.
        aliases: Optional list of alternate names.
        logger: Optional logger; defaults to a logger named after `name`.
    """
    self.name = name
    self.description = description
    self.how_to_use = how_to_use
    self.aliases = aliases or []
    self.logger = logger or logging.getLogger(name)
    self.func: Optional[Callable] = None  # Placeholder for the decorated function

get_command_function()

Return the bound implementation function.

Raises:

Type Description
RuntimeError

If no function has been bound via the decorator.

Source code in classes/structs/Command.py
48
49
50
51
52
53
54
55
56
def get_command_function(self) -> Callable:
    """Return the bound implementation function.

    Raises:
        RuntimeError: If no function has been bound via the decorator.
    """
    if not self.func:
        raise RuntimeError(f"Command '{self.name}' has no associated function.")
    return self.func

register(bot)

Register this command with the bot's command registry.

Wraps the original function into a discord.py command callback and attaches it to the bot.

Parameters:

Name Type Description Default
bot Bot

The Discord bot to register against.

required
Source code in classes/structs/Command.py
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
def register(self, bot: commands.Bot):
    """Register this command with the bot's command registry.

    Wraps the original function into a discord.py command callback and
    attaches it to the bot.

    Args:
        bot: The Discord bot to register against.
    """
    async def wrapped(ctx, *args, **kwargs):
        if self.func is None:
            raise RuntimeError(f"Command '{self.name}' has no associated function to call.")
        await self.func(
            client=bot,
            message=ctx.message,
            args=args,
            profile=None,
            logger=self.logger,
            guild=ctx.guild,
            interfacer=None,
            used_name=self.name,
        )

    bot.command(
        name=self.name,
        description=self.description,
        aliases=self.aliases,
    )(wrapped)

    print(f"Registered command '{self.name}' with the bot.")

classes.structs.SlashCommand

SlashCommand

Descriptor for a Discord slash command.

Wraps an app_commands.Command, optional autocomplete function, and some visibility flags used by help/registration flows.

Source code in classes/structs/SlashCommand.py
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
class SlashCommand:
    """Descriptor for a Discord slash command.

    Wraps an `app_commands.Command`, optional autocomplete function, and some
    visibility flags used by help/registration flows.
    """

    def __init__(
        self,
        data: app_commands.Command,
        func: Optional[Callable[..., Any]] = None,
        global_cmd: bool = False,
        auto_complete_func: Optional[Callable[..., Any]] = None,
        logger: Optional[logging.Logger] = None,
        module: Optional[str] = None,
        disabled: bool = False
    ):
        """Create a slash command descriptor.

        Args:
            data: The `app_commands.Command` object.
            func: Optional explicit callback; defaults to `data.callback`.
            global_cmd: Whether it should be synced globally by default.
            auto_complete_func: Optional autocomplete callback.
            logger: Optional logger; defaults to a name derived from the command.
            module: Owning module name, if applicable.
            disabled: If True, the command should not appear or be registered.
        """
        self.data = data
        self.func = func or data.callback
        self.global_cmd = global_cmd
        self.auto_complete_func = auto_complete_func
        self.logger = logger or logging.getLogger(data.name)
        self.module = module
        self.disabled = disabled

        self.logger.debug(f"Initialized SlashCommand: {data.name}, func: {self.func.__name__}")

    def register_to_tree(self, bot_tree: app_commands.CommandTree):
        """Register the slash command into a command tree.

        Args:
            bot_tree: The bot's `CommandTree` to add the command to.
        """
        bot_tree.add_command(self.data)
        self.logger.debug(f"Registered slash command: {self.data.name}")


    @property
    def should_appear_in_help(self) -> bool:
        """Return whether the command should appear in help UIs."""
        return not self.disabled

should_appear_in_help property

Return whether the command should appear in help UIs.

__init__(data, func=None, global_cmd=False, auto_complete_func=None, logger=None, module=None, disabled=False)

Create a slash command descriptor.

Parameters:

Name Type Description Default
data Command

The app_commands.Command object.

required
func Optional[Callable[..., Any]]

Optional explicit callback; defaults to data.callback.

None
global_cmd bool

Whether it should be synced globally by default.

False
auto_complete_func Optional[Callable[..., Any]]

Optional autocomplete callback.

None
logger Optional[Logger]

Optional logger; defaults to a name derived from the command.

None
module Optional[str]

Owning module name, if applicable.

None
disabled bool

If True, the command should not appear or be registered.

False
Source code in classes/structs/SlashCommand.py
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
def __init__(
    self,
    data: app_commands.Command,
    func: Optional[Callable[..., Any]] = None,
    global_cmd: bool = False,
    auto_complete_func: Optional[Callable[..., Any]] = None,
    logger: Optional[logging.Logger] = None,
    module: Optional[str] = None,
    disabled: bool = False
):
    """Create a slash command descriptor.

    Args:
        data: The `app_commands.Command` object.
        func: Optional explicit callback; defaults to `data.callback`.
        global_cmd: Whether it should be synced globally by default.
        auto_complete_func: Optional autocomplete callback.
        logger: Optional logger; defaults to a name derived from the command.
        module: Owning module name, if applicable.
        disabled: If True, the command should not appear or be registered.
    """
    self.data = data
    self.func = func or data.callback
    self.global_cmd = global_cmd
    self.auto_complete_func = auto_complete_func
    self.logger = logger or logging.getLogger(data.name)
    self.module = module
    self.disabled = disabled

    self.logger.debug(f"Initialized SlashCommand: {data.name}, func: {self.func.__name__}")

register_to_tree(bot_tree)

Register the slash command into a command tree.

Parameters:

Name Type Description Default
bot_tree CommandTree

The bot's CommandTree to add the command to.

required
Source code in classes/structs/SlashCommand.py
45
46
47
48
49
50
51
52
def register_to_tree(self, bot_tree: app_commands.CommandTree):
    """Register the slash command into a command tree.

    Args:
        bot_tree: The bot's `CommandTree` to add the command to.
    """
    bot_tree.add_command(self.data)
    self.logger.debug(f"Registered slash command: {self.data.name}")

classes.structs.Subcommand

Subcommand

Lightweight descriptor for a dynamic subcommand.

Holds the metadata required to attach a subcommand under a parent group at a later time (via the CommandHandler's deferred processing).

Source code in classes/structs/Subcommand.py
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class Subcommand:
    """Lightweight descriptor for a dynamic subcommand.

    Holds the metadata required to attach a subcommand under a parent group
    at a later time (via the CommandHandler's deferred processing).
    """

    def __init__(self, name: str, description: str, callback: Callable, parent_name: str = None):
        """Create a subcommand descriptor.

        Args:
            name: Subcommand name (leaf).
            description: Short description for help/UX.
            callback: Async function that will execute the subcommand.
            parent_name: The parent slash group name this subcommand belongs to.
        """
        self.name = name
        self.description = description
        self.callback = callback
        self.parent_name = parent_name

    def to_app_command(self) -> app_commands.Command:
        """Convert this descriptor into a Discord app command.

        Returns:
            A constructed `app_commands.Command` using the stored metadata.
        """
        return app_commands.Command(
            name=self.name,
            description=self.description,
            callback=self.callback,
        )

__init__(name, description, callback, parent_name=None)

Create a subcommand descriptor.

Parameters:

Name Type Description Default
name str

Subcommand name (leaf).

required
description str

Short description for help/UX.

required
callback Callable

Async function that will execute the subcommand.

required
parent_name str

The parent slash group name this subcommand belongs to.

None
Source code in classes/structs/Subcommand.py
11
12
13
14
15
16
17
18
19
20
21
22
23
def __init__(self, name: str, description: str, callback: Callable, parent_name: str = None):
    """Create a subcommand descriptor.

    Args:
        name: Subcommand name (leaf).
        description: Short description for help/UX.
        callback: Async function that will execute the subcommand.
        parent_name: The parent slash group name this subcommand belongs to.
    """
    self.name = name
    self.description = description
    self.callback = callback
    self.parent_name = parent_name

to_app_command()

Convert this descriptor into a Discord app command.

Returns:

Type Description
Command

A constructed app_commands.Command using the stored metadata.

Source code in classes/structs/Subcommand.py
25
26
27
28
29
30
31
32
33
34
35
def to_app_command(self) -> app_commands.Command:
    """Convert this descriptor into a Discord app command.

    Returns:
        A constructed `app_commands.Command` using the stored metadata.
    """
    return app_commands.Command(
        name=self.name,
        description=self.description,
        callback=self.callback,
    )

classes.structs.CommandHelp

CommandHelp

Rich, localized help metadata for a command.

Stores per‑language dictionaries with keys such as description, usage, and examples. Retrieval is language‑aware with a safe fallback to English.

Source code in classes/structs/CommandHelp.py
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
class CommandHelp:
    """Rich, localized help metadata for a command.

    Stores per‑language dictionaries with keys such as `description`, `usage`,
    and `examples`. Retrieval is language‑aware with a safe fallback to English.
    """

    def __init__(
        self, 
        name: str, 
        translations: Dict[str, Dict[str, Optional[str]]]
    ):
        """Initialize a `CommandHelp` descriptor.

        Args:
            name: Command name this help refers to.
            translations: Mapping of language code → help fields. Expected keys
                include:
                  - "description": short explanation of what the command does
                  - "usage": usage string
                  - "examples": one or more example invocations
                Example::
                    {
                        "en": {
                            "description": "Shows the current XP and level of a user.",
                            "usage": "/xp [user]",
                            "examples": ["/xp", "/xp @User123"]
                        },
                        "pt": {
                            "description": "Mostra o XP atual e o nível de um usuário.",
                            "usage": "/xp [usuário]",
                            "examples": ["/xp", "/xp @Usuario123"]
                        }
                    }
        """
        self.name = name  
        self.translations = translations 

    def get_translation(self, language: str) -> Dict[str, Optional[str]]:
        """Return the help metadata for the requested language.

        Falls back to English ("en") if the requested language is not available.
        Returns an empty dict if neither is present.

        Args:
            language: BCP‑47/ISO language code (e.g., "en", "pt-BR").

        Returns:
            A dict including keys such as "description", "usage", and "examples".
        """
        return self.translations.get(language, self.translations.get("en", {}))

__init__(name, translations)

Initialize a CommandHelp descriptor.

Parameters:

Name Type Description Default
name str

Command name this help refers to.

required
translations Dict[str, Dict[str, Optional[str]]]

Mapping of language code → help fields. Expected keys include: - "description": short explanation of what the command does - "usage": usage string - "examples": one or more example invocations Example:: { "en": { "description": "Shows the current XP and level of a user.", "usage": "/xp [user]", "examples": ["/xp", "/xp @User123"] }, "pt": { "description": "Mostra o XP atual e o nível de um usuário.", "usage": "/xp [usuário]", "examples": ["/xp", "/xp @Usuario123"] } }

required
Source code in classes/structs/CommandHelp.py
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
def __init__(
    self, 
    name: str, 
    translations: Dict[str, Dict[str, Optional[str]]]
):
    """Initialize a `CommandHelp` descriptor.

    Args:
        name: Command name this help refers to.
        translations: Mapping of language code → help fields. Expected keys
            include:
              - "description": short explanation of what the command does
              - "usage": usage string
              - "examples": one or more example invocations
            Example::
                {
                    "en": {
                        "description": "Shows the current XP and level of a user.",
                        "usage": "/xp [user]",
                        "examples": ["/xp", "/xp @User123"]
                    },
                    "pt": {
                        "description": "Mostra o XP atual e o nível de um usuário.",
                        "usage": "/xp [usuário]",
                        "examples": ["/xp", "/xp @Usuario123"]
                    }
                }
    """
    self.name = name  
    self.translations = translations 

get_translation(language)

Return the help metadata for the requested language.

Falls back to English ("en") if the requested language is not available. Returns an empty dict if neither is present.

Parameters:

Name Type Description Default
language str

BCP‑47/ISO language code (e.g., "en", "pt-BR").

required

Returns:

Type Description
Dict[str, Optional[str]]

A dict including keys such as "description", "usage", and "examples".

Source code in classes/structs/CommandHelp.py
41
42
43
44
45
46
47
48
49
50
51
52
53
def get_translation(self, language: str) -> Dict[str, Optional[str]]:
    """Return the help metadata for the requested language.

    Falls back to English ("en") if the requested language is not available.
    Returns an empty dict if neither is present.

    Args:
        language: BCP‑47/ISO language code (e.g., "en", "pt-BR").

    Returns:
        A dict including keys such as "description", "usage", and "examples".
    """
    return self.translations.get(language, self.translations.get("en", {}))

classes.structs.ObjectFlags

ObjectFlags

In‑memory flags for a Guild or Member domain object.

Provides a thin wrapper to read/write boolean or arbitrary values inside the object's backing data["flags"] and to consult defaults from client.flags.flags when unset on the object.

Source code in classes/structs/ObjectFlags.py
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
class ObjectFlags:
    """In‑memory flags for a Guild or Member domain object.

    Provides a thin wrapper to read/write boolean or arbitrary values inside
    the object's backing `data["flags"]` and to consult defaults from
    `client.flags.flags` when unset on the object.
    """

    def __init__(self, client: Bot, obj: Any):
        """Initialize a flags manager bound to a specific object.

        Args:
            client: Discord bot client. Expected to expose `client.flags.flags`
                with default values for known flag keys.
            obj: The domain object (e.g., Guild or Member) holding `data`.
        """
        self.client = client
        self.obj = obj  # Pode ser uma instância de Guild ou outra classe
        self.logger = logging.getLogger(f"{self.obj.id} Flags")  # Use o atributo id diretamente


    def _default_flags(self) -> Dict[str, Any]:
        """Return the global defaults from the client, or an empty mapping."""
        fm = getattr(self.client, "flags_manager", None)
        return getattr(fm, "flags", {}) if fm else {}

    def _ensure_flags_dict(self) -> Dict[str, Any]:
        """Ensure `obj.data['flags']` exists and return it (or an empty dict)."""
        if hasattr(self.obj, "data") and isinstance(self.obj.data, dict):
            return self.obj.data.setdefault("flags", {})
        return {}

    def set(self, flag: str, value: Any) -> bool:
        """Set a custom flag on the object (synchronous).

        Returns False if the flag key is unknown or if the object data is invalid.

        Args:
            flag: Flag key to set.
            value: Arbitrary value to assign.

        Returns:
            True if the flag was set, False otherwise.
        """
        defaults = self._default_flags()
        if defaults and flag not in defaults:
            self.logger.warning(f"Flag '{flag}' is not registered, ignoring.")
            return False

        flags = self._ensure_flags_dict()
        if flags is not None:
            flags[flag] = value
            return True

        self.logger.error(f"Object '{self.obj}' does not have a valid data attribute.")
        return False

    async def awaitable_set(self, flag: str, value: Any) -> bool:
        """Set a custom flag on the object (async signature convenience).

        Same semantics as `set()`, but with an awaitable signature for call sites
        that are already async.

        Args:
            flag: Flag key to set.
            value: Arbitrary value to assign.

        Returns:
            True if the flag was set, False otherwise.
        """
        return self.set(flag, value)

    def delete(self, flag: str) -> bool:
        """Delete a custom flag from the object if present.

        Args:
            flag: Flag key to remove.

        Returns:
            True if the flag existed and was removed, False otherwise.
        """
        if hasattr(self.obj, "data") and isinstance(self.obj.data, dict):
            self.obj.data.setdefault("flags", {}).pop(flag, None)
            return True
        return False

    def get(self, flag: str) -> Any:
        """Return the effective value for a flag.

        Looks first at the object's `data["flags"]`, then falls back to
        the global default in `client.flags.flags`.

        Args:
            flag: Flag key to read.

        Returns:
            The value set on the object or the default if unset.
        """
        defaults = self._default_flags()
        if hasattr(self.obj, "data") and isinstance(self.obj.data, dict):
            obj_val = self.obj.data.get("flags", {}).get(flag, None)
            return obj_val if obj_val is not None else defaults.get(flag)
        return defaults.get(flag)

    def has(self, flag: str) -> bool:
        """Return whether a flag key is recognized by the client.

        Note:
            This checks registration (existence in client defaults), not whether
            a truthy value is set on the object.

        Args:
            flag: Flag key to verify.

        Returns:
            True if the flag key is registered, otherwise False.
        """
        defaults = self._default_flags()
        return flag in defaults

    @property
    def all(self) -> Dict[str, Any]:
        """Return the full flag map stored on the object (without defaults).

        Returns:
            A dict of object‑level flags, or `{}` if no flags were persisted.
        """
        if hasattr(self.obj, "data") and isinstance(self.obj.data, dict):
            return self.obj.data.get("flags", {})
        return {}

all property

Return the full flag map stored on the object (without defaults).

Returns:

Type Description
Dict[str, Any]

A dict of object‑level flags, or {} if no flags were persisted.

__init__(client, obj)

Initialize a flags manager bound to a specific object.

Parameters:

Name Type Description Default
client Bot

Discord bot client. Expected to expose client.flags.flags with default values for known flag keys.

required
obj Any

The domain object (e.g., Guild or Member) holding data.

required
Source code in classes/structs/ObjectFlags.py
14
15
16
17
18
19
20
21
22
23
24
def __init__(self, client: Bot, obj: Any):
    """Initialize a flags manager bound to a specific object.

    Args:
        client: Discord bot client. Expected to expose `client.flags.flags`
            with default values for known flag keys.
        obj: The domain object (e.g., Guild or Member) holding `data`.
    """
    self.client = client
    self.obj = obj  # Pode ser uma instância de Guild ou outra classe
    self.logger = logging.getLogger(f"{self.obj.id} Flags")  # Use o atributo id diretamente

awaitable_set(flag, value) async

Set a custom flag on the object (async signature convenience).

Same semantics as set(), but with an awaitable signature for call sites that are already async.

Parameters:

Name Type Description Default
flag str

Flag key to set.

required
value Any

Arbitrary value to assign.

required

Returns:

Type Description
bool

True if the flag was set, False otherwise.

Source code in classes/structs/ObjectFlags.py
63
64
65
66
67
68
69
70
71
72
73
74
75
76
async def awaitable_set(self, flag: str, value: Any) -> bool:
    """Set a custom flag on the object (async signature convenience).

    Same semantics as `set()`, but with an awaitable signature for call sites
    that are already async.

    Args:
        flag: Flag key to set.
        value: Arbitrary value to assign.

    Returns:
        True if the flag was set, False otherwise.
    """
    return self.set(flag, value)

delete(flag)

Delete a custom flag from the object if present.

Parameters:

Name Type Description Default
flag str

Flag key to remove.

required

Returns:

Type Description
bool

True if the flag existed and was removed, False otherwise.

Source code in classes/structs/ObjectFlags.py
78
79
80
81
82
83
84
85
86
87
88
89
90
def delete(self, flag: str) -> bool:
    """Delete a custom flag from the object if present.

    Args:
        flag: Flag key to remove.

    Returns:
        True if the flag existed and was removed, False otherwise.
    """
    if hasattr(self.obj, "data") and isinstance(self.obj.data, dict):
        self.obj.data.setdefault("flags", {}).pop(flag, None)
        return True
    return False

get(flag)

Return the effective value for a flag.

Looks first at the object's data["flags"], then falls back to the global default in client.flags.flags.

Parameters:

Name Type Description Default
flag str

Flag key to read.

required

Returns:

Type Description
Any

The value set on the object or the default if unset.

Source code in classes/structs/ObjectFlags.py
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
def get(self, flag: str) -> Any:
    """Return the effective value for a flag.

    Looks first at the object's `data["flags"]`, then falls back to
    the global default in `client.flags.flags`.

    Args:
        flag: Flag key to read.

    Returns:
        The value set on the object or the default if unset.
    """
    defaults = self._default_flags()
    if hasattr(self.obj, "data") and isinstance(self.obj.data, dict):
        obj_val = self.obj.data.get("flags", {}).get(flag, None)
        return obj_val if obj_val is not None else defaults.get(flag)
    return defaults.get(flag)

has(flag)

Return whether a flag key is recognized by the client.

Note

This checks registration (existence in client defaults), not whether a truthy value is set on the object.

Parameters:

Name Type Description Default
flag str

Flag key to verify.

required

Returns:

Type Description
bool

True if the flag key is registered, otherwise False.

Source code in classes/structs/ObjectFlags.py
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
def has(self, flag: str) -> bool:
    """Return whether a flag key is recognized by the client.

    Note:
        This checks registration (existence in client defaults), not whether
        a truthy value is set on the object.

    Args:
        flag: Flag key to verify.

    Returns:
        True if the flag key is registered, otherwise False.
    """
    defaults = self._default_flags()
    return flag in defaults

set(flag, value)

Set a custom flag on the object (synchronous).

Returns False if the flag key is unknown or if the object data is invalid.

Parameters:

Name Type Description Default
flag str

Flag key to set.

required
value Any

Arbitrary value to assign.

required

Returns:

Type Description
bool

True if the flag was set, False otherwise.

Source code in classes/structs/ObjectFlags.py
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
def set(self, flag: str, value: Any) -> bool:
    """Set a custom flag on the object (synchronous).

    Returns False if the flag key is unknown or if the object data is invalid.

    Args:
        flag: Flag key to set.
        value: Arbitrary value to assign.

    Returns:
        True if the flag was set, False otherwise.
    """
    defaults = self._default_flags()
    if defaults and flag not in defaults:
        self.logger.warning(f"Flag '{flag}' is not registered, ignoring.")
        return False

    flags = self._ensure_flags_dict()
    if flags is not None:
        flags[flag] = value
        return True

    self.logger.error(f"Object '{self.obj}' does not have a valid data attribute.")
    return False

classes.structs.Permissions

Permissions

Hierarchical permission override tree with wildcard support.

Stores overrides under dot‑separated paths (e.g., "Role.*", "User.123"). Provides helpers to set nodes, resolve nodes (with optional strict mode), and ensure that intermediate paths exist.

Source code in classes/structs/Permissions.py
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
class Permissions:
    """Hierarchical permission override tree with wildcard support.

    Stores overrides under dot‑separated paths (e.g., "Role.*", "User.123").
    Provides helpers to set nodes, resolve nodes (with optional strict mode),
    and ensure that intermediate paths exist.
    """
    def __init__(self, logger: logging.Logger, permissions: PermissionOverrideTree):
        """Initialize a permission tree wrapper.

        Args:
            logger: Logger for diagnostic messages.
            permissions: Root permission tree mapping.
        """
        self.logger = logger
        self.permissions = permissions

    def set(self, permission: str, result: OverrideNode):
        """Insert or replace a terminal override node at a given path.

        Creates intermediate namespaces as needed. If a path segment already
        points to a terminal node, the operation fails and is logged.

        Args:
            permission: Dot‑separated path (e.g., "Feature.Admin.Purge").
            result: Terminal override node with `allow` / `deny` lists.
        """
        namespaces = permission.split(".")
        current = self.permissions
        last = namespaces.pop()

        if not last:
            self.logger.warning("No namespaces provided.")
            return

        for namespace in namespaces:
            if namespace not in current:
                current[namespace] = {}
            elif is_end_node(current[namespace]):
                self.logger.error(f"Cannot create namespace '{namespace}' as it's already an end node.")
                return
            current = current[namespace]

        current[last] = result

    def get(self, permission: str, strict: bool = False) -> Optional[Union[OverrideNode, PermissionOverrideTree]]:
        """Resolve a path to either a terminal node or subtree.

        Supports a literal '*' at any level as a wildcard fallback.

        Args:
            permission: Dot‑separated path to resolve.
            strict: If True, do not return wildcard fallbacks; only exact matches.

        Returns:
            An `OverrideNode` (terminal), a `PermissionOverrideTree` (subtree),
            or `None` if no match is found (strict mode) / no wildcard fallback.
        """
        namespaces = permission.split(".")
        current = self.permissions
        last_global: Optional[OverrideNode] = None

        for namespace in namespaces:
            if namespace in current:
                node = current[namespace]
                if is_end_node(node):
                    return node
                current = node
            elif '*' in current:
                wildcard_node = current['*']
                if is_end_node(wildcard_node):
                    last_global = wildcard_node  # type: ignore
            else:
                return last_global if not strict else None

        return current if is_end_node(current) else last_global

    def get_end_node(self, permission: str, strict: bool = False) -> Optional[OverrideNode]:
        """Resolve to a terminal node only.

        Args:
            permission: Path to resolve.
            strict: If True, require exact path (ignore wildcard fallback).

        Returns:
            The terminal `OverrideNode` or `None`.
        """
        node = self.get(permission, strict)
        if node is not None and is_end_node(node):
            return node  # type: ignore
        return None

    def get_or_create_path(self, permission: str) -> PermissionOverrideTree:
        """Ensure a subtree exists for the provided path and return it.

        Creates intermediate namespaces as needed and always returns the dict
        that represents the final segment (which may then be populated).

        Args:
            permission: Dot‑separated path for the subtree.

        Returns:
            The mutable mapping for the last segment.
        """
        namespaces = permission.split(".")
        current = self.permissions

        for namespace in namespaces:
            if namespace not in current:
                current[namespace] = {}
            elif is_end_node(current[namespace]):
                self.logger.error(f"Cannot create or traverse namespace '{namespace}' as it's already an end node.")
                raise TypeError(f"Path segment '{namespace}' is a terminal node, not a namespace.")
            current = current[namespace]

        if is_end_node(current):
            self.logger.error("Final path segment is a terminal node, not a namespace.")
            raise TypeError("Final path segment is a terminal node, not a namespace.")
        return current  # type: ignore[return-value]

__init__(logger, permissions)

Initialize a permission tree wrapper.

Parameters:

Name Type Description Default
logger Logger

Logger for diagnostic messages.

required
permissions PermissionOverrideTree

Root permission tree mapping.

required
Source code in classes/structs/Permissions.py
26
27
28
29
30
31
32
33
34
def __init__(self, logger: logging.Logger, permissions: PermissionOverrideTree):
    """Initialize a permission tree wrapper.

    Args:
        logger: Logger for diagnostic messages.
        permissions: Root permission tree mapping.
    """
    self.logger = logger
    self.permissions = permissions

get(permission, strict=False)

Resolve a path to either a terminal node or subtree.

Supports a literal '*' at any level as a wildcard fallback.

Parameters:

Name Type Description Default
permission str

Dot‑separated path to resolve.

required
strict bool

If True, do not return wildcard fallbacks; only exact matches.

False

Returns:

Type Description
Optional[Union[OverrideNode, PermissionOverrideTree]]

An OverrideNode (terminal), a PermissionOverrideTree (subtree),

Optional[Union[OverrideNode, PermissionOverrideTree]]

or None if no match is found (strict mode) / no wildcard fallback.

Source code in classes/structs/Permissions.py
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
def get(self, permission: str, strict: bool = False) -> Optional[Union[OverrideNode, PermissionOverrideTree]]:
    """Resolve a path to either a terminal node or subtree.

    Supports a literal '*' at any level as a wildcard fallback.

    Args:
        permission: Dot‑separated path to resolve.
        strict: If True, do not return wildcard fallbacks; only exact matches.

    Returns:
        An `OverrideNode` (terminal), a `PermissionOverrideTree` (subtree),
        or `None` if no match is found (strict mode) / no wildcard fallback.
    """
    namespaces = permission.split(".")
    current = self.permissions
    last_global: Optional[OverrideNode] = None

    for namespace in namespaces:
        if namespace in current:
            node = current[namespace]
            if is_end_node(node):
                return node
            current = node
        elif '*' in current:
            wildcard_node = current['*']
            if is_end_node(wildcard_node):
                last_global = wildcard_node  # type: ignore
        else:
            return last_global if not strict else None

    return current if is_end_node(current) else last_global

get_end_node(permission, strict=False)

Resolve to a terminal node only.

Parameters:

Name Type Description Default
permission str

Path to resolve.

required
strict bool

If True, require exact path (ignore wildcard fallback).

False

Returns:

Type Description
Optional[OverrideNode]

The terminal OverrideNode or None.

Source code in classes/structs/Permissions.py
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
def get_end_node(self, permission: str, strict: bool = False) -> Optional[OverrideNode]:
    """Resolve to a terminal node only.

    Args:
        permission: Path to resolve.
        strict: If True, require exact path (ignore wildcard fallback).

    Returns:
        The terminal `OverrideNode` or `None`.
    """
    node = self.get(permission, strict)
    if node is not None and is_end_node(node):
        return node  # type: ignore
    return None

get_or_create_path(permission)

Ensure a subtree exists for the provided path and return it.

Creates intermediate namespaces as needed and always returns the dict that represents the final segment (which may then be populated).

Parameters:

Name Type Description Default
permission str

Dot‑separated path for the subtree.

required

Returns:

Type Description
PermissionOverrideTree

The mutable mapping for the last segment.

Source code in classes/structs/Permissions.py
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
def get_or_create_path(self, permission: str) -> PermissionOverrideTree:
    """Ensure a subtree exists for the provided path and return it.

    Creates intermediate namespaces as needed and always returns the dict
    that represents the final segment (which may then be populated).

    Args:
        permission: Dot‑separated path for the subtree.

    Returns:
        The mutable mapping for the last segment.
    """
    namespaces = permission.split(".")
    current = self.permissions

    for namespace in namespaces:
        if namespace not in current:
            current[namespace] = {}
        elif is_end_node(current[namespace]):
            self.logger.error(f"Cannot create or traverse namespace '{namespace}' as it's already an end node.")
            raise TypeError(f"Path segment '{namespace}' is a terminal node, not a namespace.")
        current = current[namespace]

    if is_end_node(current):
        self.logger.error("Final path segment is a terminal node, not a namespace.")
        raise TypeError("Final path segment is a terminal node, not a namespace.")
    return current  # type: ignore[return-value]

set(permission, result)

Insert or replace a terminal override node at a given path.

Creates intermediate namespaces as needed. If a path segment already points to a terminal node, the operation fails and is logged.

Parameters:

Name Type Description Default
permission str

Dot‑separated path (e.g., "Feature.Admin.Purge").

required
result OverrideNode

Terminal override node with allow / deny lists.

required
Source code in classes/structs/Permissions.py
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
def set(self, permission: str, result: OverrideNode):
    """Insert or replace a terminal override node at a given path.

    Creates intermediate namespaces as needed. If a path segment already
    points to a terminal node, the operation fails and is logged.

    Args:
        permission: Dot‑separated path (e.g., "Feature.Admin.Purge").
        result: Terminal override node with `allow` / `deny` lists.
    """
    namespaces = permission.split(".")
    current = self.permissions
    last = namespaces.pop()

    if not last:
        self.logger.warning("No namespaces provided.")
        return

    for namespace in namespaces:
        if namespace not in current:
            current[namespace] = {}
        elif is_end_node(current[namespace]):
            self.logger.error(f"Cannot create namespace '{namespace}' as it's already an end node.")
            return
        current = current[namespace]

    current[last] = result

is_end_node(node)

Return True if a permissions tree node is a terminal OverrideNode.

A terminal node carries the concrete allow/deny lists; an internal node is a nested mapping (another PermissionOverrideTree).

Source code in classes/structs/Permissions.py
10
11
12
13
14
15
16
def is_end_node(node: Union[OverrideNode, PermissionOverrideTree]) -> bool:
    """Return True if a permissions tree node is a terminal `OverrideNode`.

    A terminal node carries the concrete `allow`/`deny` lists; an internal node
    is a nested mapping (another `PermissionOverrideTree`).
    """
    return not isinstance(node, dict)

classes.structs.Setting

Setting dataclass

Represents a setting with metadata and value.

Source code in classes/structs/Setting.py
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
@dataclass
class Setting:
    """
    Represents a setting with metadata and value.
    """
    name: str
    description: str
    id: str
    type: str
    permission: Optional[int] = None
    color: Optional[str] = None
    run: Optional[Callable[[Any], Awaitable[Any]]] = None
    save: Optional[Callable[['Bot', int, 'Setting'], Awaitable[bool]]] = None
    load: Optional[Callable[['Bot', Any, Any], Awaitable[Any]]] = None
    value: Any = None

    def clone(self) -> 'Setting':
        """
        Creates a copy of the setting.
        """
        return Setting(
            name=self.name,
            description=self.description,
            id=self.id,
            type=self.type,
            permission=self.permission,
            color=self.color,
            run=self.run,
            save=self.save,
            load=self.load,
            value=self.value
        )

    def to_dict(self) -> Dict[str, Any]:
        """
        Converts the setting to a dictionary.
        """
        return {
            "name": self.name,
            "description": self.description,
            "id": self.id,
            "type": self.type,
            "permission": self.permission,
            "value": self.value,
            "color": self.color,
        }

clone()

Creates a copy of the setting.

Source code in classes/structs/Setting.py
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
def clone(self) -> 'Setting':
    """
    Creates a copy of the setting.
    """
    return Setting(
        name=self.name,
        description=self.description,
        id=self.id,
        type=self.type,
        permission=self.permission,
        color=self.color,
        run=self.run,
        save=self.save,
        load=self.load,
        value=self.value
    )

to_dict()

Converts the setting to a dictionary.

Source code in classes/structs/Setting.py
40
41
42
43
44
45
46
47
48
49
50
51
52
def to_dict(self) -> Dict[str, Any]:
    """
    Converts the setting to a dictionary.
    """
    return {
        "name": self.name,
        "description": self.description,
        "id": self.id,
        "type": self.type,
        "permission": self.permission,
        "value": self.value,
        "color": self.color,
    }

default_save_method(bot, entity_id, setting) async

Default method to save the value of a setting to the database.

Source code in classes/structs/Setting.py
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
async def default_save_method(bot: 'Bot', entity_id: int, setting: Setting) -> bool:
    """
    Default method to save the value of a setting to the database.
    """
    try:
        if hasattr(bot, 'logger'):
            bot.logger.debug(f"Saving setting '{setting.id}' with value '{setting.value}' for entity {entity_id}.")

        if hasattr(bot, 'db'):
            collection = "guilds" if isinstance(entity_id, int) else "users"
            key = "guild_id" if isinstance(entity_id, int) else "user_id"
            await bot.db.update_one(
                collection,
                {key: str(entity_id)},
                {"$set": {f"settings.{setting.id}.value": setting.value}},
                upsert=True,
            )
            return True
        raise ValueError("Database connection not available.")
    except Exception as e:
        if hasattr(bot, "logger"):
            bot.logger.error(f"Error saving setting '{setting.id}': {e}")
        return False