from typing import Optional, Type, Callable from cpl_core.configuration import ConfigurationABC, ConfigurationModelABC from cpl_core.console import Console from cpl_core.dependency_injection import ServiceProviderABC from cpl_core.logging import LoggerABC from cpl_discord.application import DiscordBotApplicationABC from cpl_discord.configuration import DiscordBotSettings from cpl_discord.service import DiscordBotServiceABC, DiscordBotService from cpl_translation import TranslatePipe, TranslationServiceABC, TranslationSettings from bot_core.configuration.bot_logging_settings import BotLoggingSettings from bot_core.configuration.bot_settings import BotSettings from bot_core.configuration.server_settings import ServerSettings from bot_core.logging.command_logger import CommandLogger from bot_core.logging.event_logger import EventLogger from modules.base.configuration.base_server_settings import BaseServerSettings from modules.base.configuration.base_settings import BaseSettings from modules.boot_log.configuration.boot_log_server_settings import BootLogServerSettings from modules.boot_log.configuration.boot_log_settings import BootLogSettings from modules.permission.configuration.permission_server_settings import PermissionServerSettings from modules.permission.configuration.permission_settings import PermissionSettings class Application(DiscordBotApplicationABC): def __init__(self, config: ConfigurationABC, services: ServiceProviderABC): DiscordBotApplicationABC.__init__(self, config, services) self._services = services self._cmd_logger: Optional[LoggerABC] = None self._event_logger: Optional[LoggerABC] = None # cpl-core self._logger: LoggerABC = services.get_service(LoggerABC) # cpl-discord self._bot: DiscordBotServiceABC = services.get_service(DiscordBotServiceABC) self._bot_settings: DiscordBotSettings = config.get_configuration(DiscordBotSettings) # cpl-translation self._translation: TranslationServiceABC = services.get_service(TranslationServiceABC) self._translate: TranslatePipe = services.get_service(TranslatePipe) def _configure_settings_with_sub_settings(self, settings: Type, list_atr: Callable, atr: Callable): settings: Optional[settings] = self._configuration.get_configuration(settings) if settings is None: return for sub_settings in list_atr(settings): self._logger.trace(__name__, f'Saved config: {type(sub_settings).__name__}_{atr(sub_settings)}') self._configuration.add_configuration(f'{type(sub_settings).__name__}_{atr(sub_settings)}', sub_settings) async def configure(self): self._translation.load_by_settings(self._configuration.get_configuration(TranslationSettings)) self._configure_settings_with_sub_settings(BotSettings, lambda x: x.servers, lambda x: x.id) self._configure_settings_with_sub_settings(BaseSettings, lambda x: x.servers, lambda x: x.id) self._configure_settings_with_sub_settings(BootLogSettings, lambda x: x.servers, lambda x: x.id) self._configure_settings_with_sub_settings(PermissionSettings, lambda x: x.servers, lambda x: x.id) self._configure_settings_with_sub_settings(BotLoggingSettings, lambda x: x.files, lambda x: x.key) # custom loggers need to be loaded AFTER config is loaded correctly self._cmd_logger: LoggerABC = self._services.get_service(CommandLogger) self._event_logger: LoggerABC = self._services.get_service(EventLogger) async def main(self): try: self._logger.debug(__name__, f'Starting...\n') self._logger.trace(__name__, f'Try to start {DiscordBotService.__name__}') await self._bot.start_async() await self._bot.stop_async() except Exception as e: self._logger.error(__name__, 'Start failed', e) async def stop_async(self): try: self._logger.trace(__name__, f'Try to stop {DiscordBotService.__name__}') await self._bot.close() self._logger.trace(__name__, f'Stopped {DiscordBotService.__name__}') except Exception as e: self._logger.error(__name__, 'stop failed', e) Console.write_line() def is_restart(self): return True if self._configuration.get_configuration('IS_RESTART') == 'true' else False