Skip to content

Commit 4b7e77c

Browse files
committed
🧑‍💻 Dev. experience improvements
1 parent 8841437 commit 4b7e77c

File tree

6 files changed

+61
-46
lines changed

6 files changed

+61
-46
lines changed

src/__main__.py

Lines changed: 9 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,40 +7,18 @@
77
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
88
# the above line allows us to import from src without any issues whilst using src/__main__.py
99
import asyncio
10-
import importlib.util
11-
from glob import iglob
12-
13-
from src.config import config
14-
from src.log import logger
15-
from src.utils.setup_func import setup_func
16-
17-
18-
async def load_and_run_patches() -> None:
19-
for patch_file in iglob("src/extensions/*/patch.py"):
20-
extension = os.path.basename(os.path.dirname(patch_file))
21-
if (
22-
config["extensions"]
23-
.get(extension, config["extensions"].get(extension.replace("_", "-")))
24-
.get("enabled", False)
25-
):
26-
logger.info(f"Loading patch for extension {extension}")
27-
spec = importlib.util.spec_from_file_location(f"src.extensions.{extension}.patch", patch_file)
28-
if not spec or not spec.loader:
29-
continue
30-
patch_module = importlib.util.module_from_spec(spec)
31-
spec.loader.exec_module(patch_module)
32-
if hasattr(patch_module, "patch") and callable(patch_module.patch):
33-
await setup_func(patch_module.patch, config=config["extensions"][extension])
34-
35-
36-
async def pre_main() -> None:
10+
11+
from src.patcher import load_and_run_patches
12+
13+
14+
async def main() -> None:
3715
await load_and_run_patches()
38-
# we import main here to apply patches before importing the most things we can
16+
# we import main here to apply patches before importing as many things we can
3917
# and allow the patches to be applied to later imported modules
40-
from src.start import main
18+
from src.start import start
4119

42-
await main()
20+
await start()
4321

4422

4523
if __name__ == "__main__":
46-
asyncio.run(pre_main())
24+
asyncio.run(main())

src/config/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Copyright (c) NiceBots.xyz
22
# SPDX-License-Identifier: MIT
33

4-
from .bot_config import config, store_config
4+
from .bot_config import config
55

6-
__all__ = ["config", "store_config"]
6+
__all__ = ["config"]

src/config/bot_config.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,3 @@ def load_json_recursive(data: dict[str, Any]) -> dict[str, Any]:
6666
config = yaml.safe_load(f)
6767
else:
6868
config = load_from_env()
69-
70-
71-
def store_config() -> None:
72-
if path:
73-
# noinspection PyShadowingNames
74-
with open(path, "w", encoding="utf-8") as f:
75-
yaml.dump(config, f)

src/extensions/nice_errors/handlers/base.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,9 @@ def add_error_handler[E: Exception](self, error: None, handler: ErrorHandlerType
111111
def add_error_handler[E: Exception](self, error: type[E], handler: ErrorHandlerType[E]) -> None: ...
112112

113113
def add_error_handler[E: Exception](self, error: type[E] | None, handler: ErrorHandlerType[E | Exception]) -> None:
114-
logger.info(f"Adding error handler {handler} for {error if error is not None else 'Generic'}")
114+
logger.info(
115+
f"Adding error handler {handler.__class__.__qualname__} for {error.__qualname__ if error is not None else 'Generic'}" # noqa: E501
116+
)
115117
self.error_handlers[error] = handler
116118

117119

src/patcher.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Copyright (c) NiceBots.xyz
2+
# SPDX-License-Identifier: MIT
3+
4+
import os
5+
import sys
6+
from typing import Any
7+
8+
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
9+
# the above line allows us to import from src without any issues whilst using src/__main__.py
10+
import importlib.util
11+
from glob import iglob
12+
13+
from src.config import config
14+
from src.log import logger
15+
from src.utils.setup_func import setup_func
16+
17+
18+
async def load_and_run_patches() -> None:
19+
for patch_file in iglob("src/extensions/*/patch.py"):
20+
extension = os.path.basename(os.path.dirname(patch_file))
21+
its_config: dict[Any, Any] = {}
22+
if its_config := (
23+
config["extensions"].get(extension, config["extensions"].get(extension.replace("_", "-"), {}))
24+
) and its_config.get("enabled", False):
25+
logger.info(f"Loading patch for extension {extension}")
26+
spec = importlib.util.spec_from_file_location(f"src.extensions.{extension}.patch", patch_file)
27+
if not spec or not spec.loader:
28+
continue
29+
patch_module = importlib.util.module_from_spec(spec)
30+
spec.loader.exec_module(patch_module)
31+
if hasattr(patch_module, "patch") and callable(patch_module.patch):
32+
await setup_func(patch_module.patch, config=its_config)

src/start.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,12 @@
1010

1111
import discord
1212
import yaml
13+
from discord.errors import LoginFailure
1314
from discord.ext import commands
1415
from quart import Quart
1516

1617
from src import custom, i18n
17-
from src.config import config, store_config
18+
from src.config import config
1819
from src.i18n.classes import ExtensionTranslation
1920
from src.log import logger, patch
2021
from src.utils import setup_func, unzip_extensions, validate_module
@@ -31,7 +32,11 @@ class FunctionConfig(TypedDict):
3132

3233

3334
async def start_bot(bot: custom.Bot, token: str) -> None:
34-
await bot.start(token)
35+
try:
36+
await bot.start(token)
37+
except LoginFailure as e:
38+
logger.critical("Failed to log in, is the bot token valid?")
39+
logger.debug("", exc_info=e)
3540

3641

3742
async def start_backend(app: Quart, bot: discord.Bot, token: str) -> None:
@@ -72,6 +77,13 @@ def load_extensions() -> (
7277
"list[ExtensionTranslation]",
7378
]
7479
):
80+
"""Load extensions from the extensions directory.
81+
82+
Returns:
83+
tuple[FunctionlistType, FunctionlistType, FunctionlistType, list[ExtensionTranslation]]: A tuple containing
84+
the bot functions, backend functions, startup functions, and translations.
85+
86+
"""
7587
bot_functions: FunctionlistType = []
7688
back_functions: FunctionlistType = []
7789
startup_functions: FunctionlistType = []
@@ -157,7 +169,7 @@ async def run_startup_functions(
157169
await asyncio.gather(*startup_coros)
158170

159171

160-
async def main(run_bot: bool | None = None, run_backend: bool | None = None) -> None:
172+
async def start(run_bot: bool | None = None, run_backend: bool | None = None) -> None:
161173
if not config.get("bot", {}).get("token"):
162174
logger.critical("No bot token provided in config, exiting...")
163175
return
@@ -182,5 +194,3 @@ async def main(run_bot: bool | None = None, run_backend: bool | None = None) ->
182194
await run_startup_functions(startup_functions, app, back_bot)
183195

184196
await asyncio.gather(*coros)
185-
186-
store_config()

0 commit comments

Comments
 (0)