Skip to content

Commit 9275541

Browse files
committed
refactor(config): streamline configuration access and remove unused services
- Updated import paths for CONFIG across multiple modules to enhance consistency and maintainability. - Removed the IConfigService interface and its implementation, simplifying the configuration management. - Adjusted service registrations and dependency injections to reflect the new configuration structure. - Enhanced error handling and logging for better diagnostics related to configuration values and service registrations.
1 parent c51af54 commit 9275541

File tree

9 files changed

+287
-298
lines changed

9 files changed

+287
-298
lines changed

src/tux/core/__init__.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,16 @@
1616
ServiceRegistrationError,
1717
ServiceResolutionError,
1818
)
19-
from tux.core.interfaces import IBotService, IConfigService
19+
from tux.core.interfaces import IBotService
2020
from tux.core.service_registry import ServiceRegistry
21-
from tux.core.services import BotService, ConfigService
21+
from tux.core.services import BotService
2222
from tux.database.service import DatabaseService
2323

2424
__all__ = [
2525
"BaseCog",
2626
"BotService",
27-
"ConfigService",
2827
"DatabaseService",
2928
"IBotService",
30-
"IConfigService",
3129
"ServiceContainer",
3230
"ServiceDescriptor",
3331
"ServiceLifetime",

src/tux/core/app.py

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,18 @@
2222
from tux.database.utils import get_db_controller_from
2323
from tux.help import TuxHelp
2424
from tux.services.sentry_manager import SentryManager
25-
from tux.shared.config.settings import CONFIG
25+
from tux.shared.config import CONFIG
2626

2727

2828
async def get_prefix(bot: Tux, message: discord.Message) -> list[str]:
2929
"""Get the command prefix for a guild.
3030
3131
This function retrieves the guild-specific prefix from the database,
32-
falling back to `CONFIG.DEFAULT_PREFIX` when the guild is unavailable or the database
32+
falling back to `CONFIG.get_prefix()` when the guild is unavailable or the database
3333
cannot be resolved.
3434
"""
3535
if not message.guild:
36-
return [CONFIG.DEFAULT_PREFIX]
36+
return [CONFIG.get_prefix()]
3737

3838
prefix: str | None = None
3939

@@ -42,15 +42,22 @@ async def get_prefix(bot: Tux, message: discord.Message) -> list[str]:
4242
if controller is None:
4343
logger.warning("Database unavailable; using default prefix")
4444
else:
45-
# Get guild config and extract prefix
46-
guild_config = await controller.guild_config.get_config_by_guild_id(message.guild.id)
45+
# Ensure the guild exists in the database first
46+
await controller.guild.get_or_create_guild(message.guild.id)
47+
48+
# Get or create guild config with default prefix
49+
guild_config = await controller.guild_config.get_or_create_config(
50+
message.guild.id,
51+
prefix=CONFIG.get_prefix(), # Use the default prefix as the default value
52+
)
4753
if guild_config and hasattr(guild_config, "prefix"):
4854
prefix = guild_config.prefix
4955

5056
except Exception as e:
51-
logger.error(f"Error getting guild prefix: {e}")
57+
logger.error(f"❌ Error getting guild prefix: {type(e).__name__}")
58+
logger.info("💡 Using default prefix due to database or configuration error")
5259

53-
return [prefix or CONFIG.DEFAULT_PREFIX]
60+
return [prefix or CONFIG.get_prefix()]
5461

5562

5663
class TuxApp:
@@ -142,18 +149,18 @@ async def start(self) -> None:
142149
self.setup_signals(loop)
143150

144151
if not CONFIG.BOT_TOKEN:
145-
logger.critical("No bot token provided. Set DEV_BOT_TOKEN or PROD_BOT_TOKEN in your .env file.")
146-
return
152+
logger.critical("No bot token provided. Set BOT_TOKEN in your .env file.")
153+
sys.exit(1)
147154

148-
owner_ids = {CONFIG.BOT_OWNER_ID}
155+
owner_ids = {CONFIG.USER_IDS.BOT_OWNER_ID}
149156

150157
if CONFIG.ALLOW_SYSADMINS_EVAL:
151158
logger.warning(
152-
"⚠️ Eval is enabled for sysadmins, this is potentially dangerous; see settings.yml.example for more info.",
159+
"⚠️ Eval is enabled for sysadmins, this is potentially dangerous; see .env file for more info.",
153160
)
154-
owner_ids.update(CONFIG.SYSADMIN_IDS)
161+
owner_ids.update(CONFIG.USER_IDS.SYSADMINS)
155162
else:
156-
logger.warning("🔒️ Eval is disabled for sysadmins; see settings.yml.example for more info.")
163+
logger.warning("🔒️ Eval is disabled for sysadmins; see .env file for more info.")
157164

158165
self.bot = Tux(
159166
command_prefix=get_prefix,
@@ -176,7 +183,8 @@ async def start(self) -> None:
176183
except KeyboardInterrupt:
177184
logger.info("Shutdown requested (KeyboardInterrupt)")
178185
except Exception as e:
179-
logger.critical(f"Bot failed to start: {e}")
186+
logger.critical(f"❌ Bot failed to start: {type(e).__name__}")
187+
logger.info("💡 Check your configuration and ensure all services are properly set up")
180188
finally:
181189
await self.shutdown()
182190

src/tux/core/base_cog.py

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@
1616
from discord.ext import commands
1717
from loguru import logger
1818

19-
from tux.core.interfaces import IBotService, IConfigService, ILoggerService
19+
from tux.core.interfaces import IBotService, ILoggerService
20+
from tux.database.controllers import DatabaseCoordinator
2021
from tux.database.service import DatabaseService
22+
from tux.shared.config import CONFIG
2123
from tux.shared.functions import generate_usage as _generate_usage_shared
2224

2325
if TYPE_CHECKING:
@@ -51,9 +53,9 @@ def __init__(self, bot: Tux) -> None:
5153
# Initialize service properties first
5254
self.db_service: DatabaseService | None = None
5355
self.bot_service: IBotService | None = None
54-
self.config_service: IConfigService | None = None
56+
5557
self.logger_service: ILoggerService | None = None
56-
self._db_controller = None # legacy attribute removed; kept for type stability only
58+
self._db_coordinator: DatabaseCoordinator | None = None # Database coordinator for accessing controllers
5759

5860
# Get the bot instance
5961
self.bot = bot
@@ -79,24 +81,25 @@ def _inject_services(self) -> None:
7981
# Inject services in order of dependency
8082
self._inject_database_service()
8183
self._inject_bot_service()
82-
self._inject_config_service()
84+
8385
self._inject_logger_service()
8486

8587
# Single summary log for this cog's injection results
8688
logger.debug(
8789
f"[BaseCog] Injected services for {self.__class__.__name__} "
8890
f"(db={self.db_service is not None}, "
8991
f"bot={self.bot_service is not None}, "
90-
f"config={self.config_service is not None}, "
9192
f"logger={self.logger_service is not None})",
9293
)
9394

9495
def _inject_database_service(self) -> None:
95-
"""Inject the database service."""
96+
"""Inject the database service and create database coordinator."""
9697
try:
9798
self.db_service = self._container.get_optional(DatabaseService)
9899
if self.db_service:
99-
logger.trace(f"Injected database service into {self.__class__.__name__}")
100+
# Create the database coordinator for accessing controllers
101+
self._db_coordinator = DatabaseCoordinator(self.db_service)
102+
logger.trace(f"Injected database service and coordinator into {self.__class__.__name__}")
100103
else:
101104
logger.warning(f"Database service not available for {self.__class__.__name__}")
102105
except Exception as e:
@@ -113,17 +116,6 @@ def _inject_bot_service(self) -> None:
113116
except Exception as e:
114117
logger.error(f"[BaseCog] Bot service injection failed for {self.__class__.__name__}: {e}", exc_info=True)
115118

116-
def _inject_config_service(self) -> None:
117-
"""Inject the config service."""
118-
try:
119-
self.config_service = self._container.get_optional(IConfigService)
120-
if self.config_service:
121-
logger.trace(f"Injected config service into {self.__class__.__name__}")
122-
else:
123-
logger.warning(f"Config service not available for {self.__class__.__name__}")
124-
except Exception as e:
125-
logger.error(f"Config service injection failed for {self.__class__.__name__}: {e}")
126-
127119
def _inject_logger_service(self) -> None:
128120
"""Inject the logger service (optional)."""
129121
try:
@@ -190,36 +182,46 @@ def _generate_usage(self, command: commands.Command[Any, ..., Any]) -> str:
190182
# (Embed helpers and error handling intentionally omitted as requested.)
191183

192184
@property
193-
def db(self):
194-
"""Get the database controller from the injected database service.
185+
def db(self) -> DatabaseCoordinator:
186+
"""Get the database coordinator for accessing database controllers.
195187
196188
Returns:
197-
The database controller instance
189+
The database coordinator instance
198190
199191
Raises:
200-
RuntimeError: If the database service is not available
192+
RuntimeError: If the database coordinator is not available
201193
"""
202-
if self.db_service is None:
203-
error_msg = "Database service not injected. DI is required."
194+
if self._db_coordinator is None:
195+
error_msg = "Database coordinator not available. DI is required."
204196
raise RuntimeError(error_msg)
205-
return self.db_service
197+
return self._db_coordinator
206198

207199
def get_config(self, key: str, default: Any = None) -> Any:
208-
"""Get a configuration value with service injection support.
200+
"""Get a configuration value directly from CONFIG.
209201
210202
Args:
211203
key: The configuration key to retrieve
212204
default: Default value if key is not found
213205
214206
Returns:
215207
The configuration value or default
216-
217-
This method uses the injected config service only.
218208
"""
219-
if self.config_service is None:
220-
error_msg = "Config service not injected. DI is required."
221-
raise RuntimeError(error_msg)
222-
return self.config_service.get(key, default)
209+
210+
try:
211+
# Handle nested keys like "BOT_INFO.BOT_NAME"
212+
keys = key.split(".")
213+
value = CONFIG
214+
215+
for k in keys:
216+
if hasattr(value, k):
217+
value = getattr(value, k)
218+
else:
219+
return default
220+
except Exception as e:
221+
logger.error(f"Failed to get config value {key}: {e}")
222+
return default
223+
else:
224+
return value
223225

224226
def get_bot_latency(self) -> float:
225227
"""Get the bot's latency with service injection support.

0 commit comments

Comments
 (0)