diff --git a/src/bot/application.py b/src/bot/application.py index aec07e03..14ce439d 100644 --- a/src/bot/application.py +++ b/src/bot/application.py @@ -1,5 +1,3 @@ -from typing import Optional, Type, Callable - from cpl_core.configuration import ConfigurationABC from cpl_core.console import Console from cpl_core.dependency_injection import ServiceProviderABC @@ -9,14 +7,6 @@ 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.logging.command_logger import CommandLogger -from bot_core.logging.database_logger import DatabaseLogger -from modules.base.configuration.base_settings import BaseSettings -from modules.boot_log.configuration.boot_log_settings import BootLogSettings -from modules.permission.configuration.permission_settings import PermissionSettings - class Application(DiscordBotApplicationABC): @@ -32,7 +22,7 @@ class Application(DiscordBotApplicationABC): self._bot_settings: DiscordBotSettings = config.get_configuration(DiscordBotSettings) # cpl-translation self._translation: TranslationServiceABC = services.get_service(TranslationServiceABC) - self._translate: TranslatePipe = services.get_service(TranslatePipe) + self._t: TranslatePipe = services.get_service(TranslatePipe) self._is_stopping = False @@ -41,7 +31,7 @@ class Application(DiscordBotApplicationABC): async def main(self): try: - self._logger.debug(__name__, f'Starting...\n') + self._logger.debug(__name__, f'Starting...') self._logger.trace(__name__, f'Try to start {DiscordBotService.__name__}') await self._bot.start_async() await self._bot.stop_async() @@ -63,4 +53,4 @@ class Application(DiscordBotApplicationABC): Console.write_line() def is_restart(self): - return True if self._configuration.get_configuration('IS_RESTART') == 'true' else False + return True if self._configuration.get_configuration('IS_RESTART') == 'true' else False# diff --git a/src/bot/bot.json b/src/bot/bot.json index 1ebf34f1..9554e15c 100644 --- a/src/bot/bot.json +++ b/src/bot/bot.json @@ -4,7 +4,7 @@ "Version": { "Major": "0", "Minor": "2", - "Micro": "0" + "Micro": "1" }, "Author": "Sven Heidemann", "AuthorEmail": "sven.heidemann@sh-edraft.de", diff --git a/src/bot/config/appsettings.development.json b/src/bot/config/appsettings.development.json index 3278dcd7..1b3dfa6d 100644 --- a/src/bot/config/appsettings.development.json +++ b/src/bot/config/appsettings.development.json @@ -57,7 +57,8 @@ 240160344557879316, 236592458664902657 ], - "DeployFilesPath": "../../deploy" + "WaitForRestart": 4, + "WaitForShutdown": 4 }, "Base": { "910199451145076828": { diff --git a/src/bot/config/appsettings.edrafts-pc-ubuntu.json b/src/bot/config/appsettings.edrafts-pc-ubuntu.json index 7afbf20d..62c82eaa 100644 --- a/src/bot/config/appsettings.edrafts-pc-ubuntu.json +++ b/src/bot/config/appsettings.edrafts-pc-ubuntu.json @@ -54,7 +54,8 @@ "Technicians": [ 240160344557879316 ], - "DeployFilesPath": "../../deploy" + "WaitForRestart": 4, + "WaitForShutdown": 4 }, "Base": { "910199451145076828": { diff --git a/src/bot/config/appsettings.production.json b/src/bot/config/appsettings.production.json index 4ee87356..8b195269 100644 --- a/src/bot/config/appsettings.production.json +++ b/src/bot/config/appsettings.production.json @@ -67,7 +67,8 @@ 240160344557879316, 236592458664902657 ], - "DeployFilesPath": "../../" + "WaitForRestart": 4, + "WaitForShutdown": 4 }, "Base": { "650366049023295514": { diff --git a/src/bot/config/appsettings.staging.json b/src/bot/config/appsettings.staging.json index 72fb76c1..7ccbbcb8 100644 --- a/src/bot/config/appsettings.staging.json +++ b/src/bot/config/appsettings.staging.json @@ -64,7 +64,8 @@ 240160344557879316, 236592458664902657 ], - "DeployFilesPath": "../../" + "WaitForRestart": 4, + "WaitForShutdown": 4 }, "Base": { "910199451145076828": { diff --git a/src/bot/module_list.py b/src/bot/module_list.py new file mode 100644 index 00000000..f7690033 --- /dev/null +++ b/src/bot/module_list.py @@ -0,0 +1,29 @@ +from cpl_query.extension import List + +from bot_core.core_extension.core_extension_module import CoreExtensionModule +from bot_core.core_module import CoreModule +from bot_data.data_module import DataModule +from modules.admin.admin_module import AdminModule +from modules.base.base_module import BaseModule +from modules.boot_log.boot_log_module import BootLogModule +from modules.database.database_module import DatabaseModule +from modules.moderator.moderator_module import ModeratorModule +from modules.permission.permission_module import PermissionModule + + +class ModuleList: + + @staticmethod + def get_modules(): + # core modules (modules out of modules folder) should be loaded first! + return List(type, [ + CoreModule, # has to be first! + DataModule, + AdminModule, + BaseModule, + DatabaseModule, + ModeratorModule, + PermissionModule, + CoreExtensionModule, + BootLogModule # has to be last! + ]) diff --git a/src/bot/startup.py b/src/bot/startup.py index 55df0788..6a1fa559 100644 --- a/src/bot/startup.py +++ b/src/bot/startup.py @@ -1,4 +1,3 @@ -import os from datetime import datetime from typing import Optional @@ -7,35 +6,8 @@ from cpl_core.configuration import ConfigurationABC from cpl_core.database import DatabaseSettings from cpl_core.dependency_injection import ServiceProviderABC, ServiceCollectionABC from cpl_core.environment import ApplicationEnvironment -from cpl_core.logging import LoggerABC -from cpl_discord import get_discord_collection -from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC -from bot_core.abc.custom_file_logger_abc import CustomFileLoggerABC -from bot_core.abc.message_service_abc import MessageServiceABC -from bot_core.logging.command_logger import CommandLogger -from bot_core.logging.database_logger import DatabaseLogger -from bot_core.logging.message_logger import MessageLogger -from bot_core.pipes.date_time_offset_pipe import DateTimeOffsetPipe -from bot_core.service.client_utils_service import ClientUtilsService -from bot_core.service.message_service import MessageService -from bot_data.abc.client_repository_abc import ClientRepositoryABC -from bot_data.abc.known_user_repository_abc import KnownUserRepositoryABC -from bot_data.abc.server_repository_abc import ServerRepositoryABC -from bot_data.abc.user_joined_server_repository_abc import UserJoinedServerRepositoryABC -from bot_data.abc.user_joined_voice_channel_abc import UserJoinedVoiceChannelRepositoryABC -from bot_data.abc.user_repository_abc import UserRepositoryABC from bot_data.db_context import DBContext -from bot_data.service.client_repository_service import ClientRepositoryService -from bot_data.service.known_user_repository_service import KnownUserRepositoryService -from bot_data.service.server_repository_service import ServerRepositoryService -from bot_data.service.user_joined_server_repository_service import UserJoinedServerRepositoryService -from bot_data.service.user_joined_voice_channel_service import UserJoinedVoiceChannelRepositoryService -from bot_data.service.user_repository_service import UserRepositoryService -from modules.base.abc.base_helper_abc import BaseHelperABC -from modules.base.service.base_helper_service import BaseHelperService -from modules.permission.abc.permission_service_abc import PermissionServiceABC -from modules.permission.service.permission_service import PermissionService class Startup(StartupABC): @@ -52,36 +24,8 @@ class Startup(StartupABC): def configure_services(self, services: ServiceCollectionABC, environment: ApplicationEnvironment) -> ServiceProviderABC: services.add_logging() - # custom logging - services.add_singleton(LoggerABC, CommandLogger) - services.add_singleton(LoggerABC, DatabaseLogger) - services.add_singleton(LoggerABC, MessageLogger) services.add_translation() services.add_db_context(DBContext, self._config.get_configuration(DatabaseSettings)) - # general services - services.add_transient(BaseHelperABC, BaseHelperService) - services.add_transient(MessageServiceABC, MessageService) - services.add_transient(ClientUtilsServiceABC, ClientUtilsService) - - # pipes - services.add_transient(DateTimeOffsetPipe) - - # module services - services.add_singleton(PermissionServiceABC, PermissionService) - - # data services - services.add_transient(ServerRepositoryABC, ServerRepositoryService) - services.add_transient(UserRepositoryABC, UserRepositoryService) - services.add_transient(ClientRepositoryABC, ClientRepositoryService) - services.add_transient(KnownUserRepositoryABC, KnownUserRepositoryService) - services.add_transient(UserJoinedServerRepositoryABC, UserJoinedServerRepositoryService) - services.add_transient(UserJoinedVoiceChannelRepositoryABC, UserJoinedVoiceChannelRepositoryService) - - provider = services.build_service_provider() - # instantiate custom logger - for c in CustomFileLoggerABC.__subclasses__(): - i: LoggerABC = provider.get_service(c) - - return provider + return services.build_service_provider() diff --git a/src/bot/startup_module_extension.py b/src/bot/startup_module_extension.py index c93ff29c..2bf73699 100644 --- a/src/bot/startup_module_extension.py +++ b/src/bot/startup_module_extension.py @@ -6,15 +6,9 @@ from cpl_core.console import Console, ForegroundColorEnum from cpl_core.dependency_injection import ServiceCollectionABC from cpl_core.environment import ApplicationEnvironmentABC from cpl_discord.service.discord_collection_abc import DiscordCollectionABC -from cpl_query.extension import List +from bot.module_list import ModuleList from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings -from modules.admin.admin_module import AdminModule -from modules.base.base_module import BaseModule -from modules.boot_log.boot_log_module import BootLogModule -from modules.database.database_module import DatabaseModule -from modules.moderator.moderator_module import ModeratorModule -from modules.permission.permission_module import PermissionModule class StartupModuleExtension(StartupExtensionABC): @@ -23,14 +17,7 @@ class StartupModuleExtension(StartupExtensionABC): self._config: Optional[ConfigurationABC] = None self._feature_flags: Optional[FeatureFlagsSettings] = None - self._modules = List(type, [ - AdminModule, - BaseModule, - DatabaseModule, - ModeratorModule, - PermissionModule, - BootLogModule # has to be last! - ]) + self._modules = ModuleList.get_modules() def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC): self._config = config diff --git a/src/bot/translation/de.json b/src/bot/translation/de.json index 655d5d67..02da2823 100644 --- a/src/bot/translation/de.json +++ b/src/bot/translation/de.json @@ -4,6 +4,12 @@ "bot_has_no_permission_message": "Ey!!!\nWas soll das?\nIch habe keine Berechtigungen :(\nScheiß System...", "no_permission_message": "Nein!\nIch höre nicht auf dich ¯\\_(ツ)_/¯", "not_implemented_yet": "Ey Alter, das kann ich noch nicht...", + "presence": { + "booting": "{} Ich fahre gerade hoch...", + "running": "{} Behalte Ruhe und iss Kekse :D", + "restart": "{} Muss neue Kekse holen...", + "shutdown": "{} Ich werde bestimmt wieder kommen..." + }, "errors": { "error": "Es gab einen Fehler. Meld dich bitte bei einem Admin.", "command_error": "Es gab einen Fehler beim bearbeiten des Befehls. Meld dich bitte bei einem Admin.", diff --git a/src/bot_core/abc/client_utils_service_abc.py b/src/bot_core/abc/client_utils_service_abc.py index 570e0431..0345ba36 100644 --- a/src/bot_core/abc/client_utils_service_abc.py +++ b/src/bot_core/abc/client_utils_service_abc.py @@ -19,3 +19,6 @@ class ClientUtilsServiceABC(ABC): @abstractmethod async def check_if_bot_is_ready_yet_and_respond(self, ctx: Context) -> bool: pass + + @abstractmethod + async def presence_game(self, t_key: str): pass diff --git a/src/bot_core/configuration/bot_settings.py b/src/bot_core/configuration/bot_settings.py index 21036f49..fbac1dfc 100644 --- a/src/bot_core/configuration/bot_settings.py +++ b/src/bot_core/configuration/bot_settings.py @@ -14,7 +14,6 @@ class BotSettings(ConfigurationModelABC): self._servers: List[ServerSettings] = List(ServerSettings) self._technicians: List[int] = List(int) - self._deploy_file_path = './' self._wait_for_restart = 2 self._wait_for_shutdown = 2 @@ -27,15 +26,21 @@ class BotSettings(ConfigurationModelABC): return self._technicians @property - def deploy_file_path(self) -> str: - return self._deploy_file_path + def wait_for_restart(self) -> int: + return self._wait_for_restart + + @property + def wait_for_shutdown(self) -> int: + return self._wait_for_shutdown def from_dict(self, settings: dict): try: self._technicians = settings["Technicians"] - self._deploy_file_path = settings["DeployFilesPath"] + self._wait_for_restart = settings["WaitForRestart"] + self._wait_for_shutdown = settings["WaitForShutdown"] settings.pop("Technicians") - settings.pop("DeployFilesPath") + settings.pop("WaitForRestart") + settings.pop("WaitForShutdown") servers = List(ServerSettings) for s in settings: st = ServerSettings() diff --git a/src/bot_core/core_extension/__init__.py b/src/bot_core/core_extension/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/bot_core/core_extension/core_extension_module.py b/src/bot_core/core_extension/core_extension_module.py new file mode 100644 index 00000000..198e0b33 --- /dev/null +++ b/src/bot_core/core_extension/core_extension_module.py @@ -0,0 +1,20 @@ +from cpl_core.configuration import ConfigurationABC +from cpl_core.dependency_injection import ServiceCollectionABC +from cpl_core.environment import ApplicationEnvironmentABC +from cpl_discord.discord_event_types_enum import DiscordEventTypesEnum +from cpl_discord.service.discord_collection_abc import DiscordCollectionABC + +from bot_core.abc.module_abc import ModuleABC +from bot_core.core_extension.core_extension_on_ready_event import CoreExtensionOnReadyEvent + + +class CoreExtensionModule(ModuleABC): + + def __init__(self, dc: DiscordCollectionABC): + ModuleABC.__init__(self, dc, lambda x: x.base_module) + + def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC): + pass + + def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC): + self._dc.add_event(DiscordEventTypesEnum.on_ready.value, CoreExtensionOnReadyEvent) diff --git a/src/bot_core/core_extension/core_extension_on_ready_event.py b/src/bot_core/core_extension/core_extension_on_ready_event.py new file mode 100644 index 00000000..fd1f42c6 --- /dev/null +++ b/src/bot_core/core_extension/core_extension_on_ready_event.py @@ -0,0 +1,32 @@ +import asyncio + +from cpl_core.logging import LoggerABC +from cpl_discord.events import OnReadyABC +from cpl_discord.service import DiscordBotServiceABC +from cpl_translation import TranslatePipe + +from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC + + +class CoreExtensionOnReadyEvent(OnReadyABC): + + def __init__( + self, + logger: LoggerABC, + bot: DiscordBotServiceABC, + client_utils: ClientUtilsServiceABC, + t: TranslatePipe + ): + OnReadyABC.__init__(self) + + self._logger = logger + self._bot = bot + self._client_utils = client_utils + self._t = t + + self._logger.info(__name__, f'Module {type(self)} loaded') + + async def on_ready(self): + self._logger.debug(__name__, f'Module {type(self)} started') + await self._client_utils.presence_game('common.presence.running') + self._logger.trace(__name__, f'Module {type(self)} stopped') diff --git a/src/bot_core/core_module.py b/src/bot_core/core_module.py new file mode 100644 index 00000000..f8320d6b --- /dev/null +++ b/src/bot_core/core_module.py @@ -0,0 +1,46 @@ +from cpl_core.configuration import ConfigurationABC +from cpl_core.dependency_injection import ServiceCollectionABC +from cpl_core.environment import ApplicationEnvironmentABC +from cpl_core.logging import LoggerABC +from cpl_discord.discord_event_types_enum import DiscordEventTypesEnum +from cpl_discord.service.discord_collection_abc import DiscordCollectionABC + +from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC +from bot_core.abc.custom_file_logger_abc import CustomFileLoggerABC +from bot_core.abc.message_service_abc import MessageServiceABC +from bot_core.abc.module_abc import ModuleABC +from bot_core.events.core_on_ready_event import CoreOnReadyEvent +from bot_core.logging.command_logger import CommandLogger +from bot_core.logging.database_logger import DatabaseLogger +from bot_core.logging.message_logger import MessageLogger +from bot_core.pipes.date_time_offset_pipe import DateTimeOffsetPipe +from bot_core.service.client_utils_service import ClientUtilsService +from bot_core.service.message_service import MessageService + + +class CoreModule(ModuleABC): + + def __init__(self, dc: DiscordCollectionABC): + ModuleABC.__init__(self, dc, lambda x: x.base_module) + + def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC): + pass + + def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC): + # custom logging + services.add_singleton(CustomFileLoggerABC, CommandLogger) + services.add_singleton(CustomFileLoggerABC, DatabaseLogger) + services.add_singleton(CustomFileLoggerABC, MessageLogger) + + services.add_transient(MessageServiceABC, MessageService) + services.add_transient(ClientUtilsServiceABC, ClientUtilsService) + + # pipes + services.add_transient(DateTimeOffsetPipe) + + self._dc.add_event(DiscordEventTypesEnum.on_ready.value, CoreOnReadyEvent) + + provider = services.build_service_provider() + # instantiate custom logger + for c in CustomFileLoggerABC.__subclasses__(): + i: LoggerABC = provider.get_service(c) diff --git a/src/bot_core/events/__init__.py b/src/bot_core/events/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/bot_core/events/core_on_ready_event.py b/src/bot_core/events/core_on_ready_event.py new file mode 100644 index 00000000..f438884f --- /dev/null +++ b/src/bot_core/events/core_on_ready_event.py @@ -0,0 +1,32 @@ +import asyncio + +from cpl_core.logging import LoggerABC +from cpl_discord.events import OnReadyABC +from cpl_discord.service import DiscordBotServiceABC +from cpl_translation import TranslatePipe + +from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC + + +class CoreOnReadyEvent(OnReadyABC): + + def __init__( + self, + logger: LoggerABC, + bot: DiscordBotServiceABC, + client_utils: ClientUtilsServiceABC, + t: TranslatePipe + ): + OnReadyABC.__init__(self) + + self._logger = logger + self._bot = bot + self._client_utils = client_utils + self._t = t + + self._logger.info(__name__, f'Module {type(self)} loaded') + + async def on_ready(self): + self._logger.debug(__name__, f'Module {type(self)} started') + await self._client_utils.presence_game('common.presence.booting') + self._logger.trace(__name__, f'Module {type(self)} stopped') diff --git a/src/bot_core/service/client_utils_service.py b/src/bot_core/service/client_utils_service.py index 1a0d9d79..2adfb289 100644 --- a/src/bot_core/service/client_utils_service.py +++ b/src/bot_core/service/client_utils_service.py @@ -1,3 +1,4 @@ +import discord from cpl_core.configuration import ConfigurationABC from cpl_core.database.context import DatabaseContextABC from cpl_core.logging import LoggerABC @@ -61,3 +62,9 @@ class ClientUtilsService(ClientUtilsServiceABC): self._logger.debug(__name__, f'Bot is not ready yet {self._t.transform("common.errors.bot_not_ready_yet")}') await self._message_service.send_ctx_msg(ctx, self._t.transform('common.errors.bot_not_ready_yet'), without_tracking=True) return False + + async def presence_game(self, t_key: str): + import bot + name = self._t.transform(t_key).format(bot.__version__) + await self._bot.change_presence(activity=discord.Game(name=name)) + self._logger.info(__name__, f'Set presence {name}') diff --git a/src/bot_data/data_module.py b/src/bot_data/data_module.py new file mode 100644 index 00000000..cbceaa4e --- /dev/null +++ b/src/bot_data/data_module.py @@ -0,0 +1,35 @@ +from cpl_core.configuration import ConfigurationABC +from cpl_core.dependency_injection import ServiceCollectionABC +from cpl_core.environment import ApplicationEnvironmentABC +from cpl_discord.service.discord_collection_abc import DiscordCollectionABC + +from bot_core.abc.module_abc import ModuleABC +from bot_data.abc.client_repository_abc import ClientRepositoryABC +from bot_data.abc.known_user_repository_abc import KnownUserRepositoryABC +from bot_data.abc.server_repository_abc import ServerRepositoryABC +from bot_data.abc.user_joined_server_repository_abc import UserJoinedServerRepositoryABC +from bot_data.abc.user_joined_voice_channel_abc import UserJoinedVoiceChannelRepositoryABC +from bot_data.abc.user_repository_abc import UserRepositoryABC +from bot_data.service.client_repository_service import ClientRepositoryService +from bot_data.service.known_user_repository_service import KnownUserRepositoryService +from bot_data.service.server_repository_service import ServerRepositoryService +from bot_data.service.user_joined_server_repository_service import UserJoinedServerRepositoryService +from bot_data.service.user_joined_voice_channel_service import UserJoinedVoiceChannelRepositoryService +from bot_data.service.user_repository_service import UserRepositoryService + + +class DataModule(ModuleABC): + + def __init__(self, dc: DiscordCollectionABC): + ModuleABC.__init__(self, dc, lambda x: x.base_module) + + def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC): + pass + + def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC): + services.add_transient(ServerRepositoryABC, ServerRepositoryService) + services.add_transient(UserRepositoryABC, UserRepositoryService) + services.add_transient(ClientRepositoryABC, ClientRepositoryService) + services.add_transient(KnownUserRepositoryABC, KnownUserRepositoryService) + services.add_transient(UserJoinedServerRepositoryABC, UserJoinedServerRepositoryService) + services.add_transient(UserJoinedVoiceChannelRepositoryABC, UserJoinedVoiceChannelRepositoryService) \ No newline at end of file diff --git a/src/modules/admin/admin_module.py b/src/modules/admin/admin_module.py index ae6c86a8..6df25d17 100644 --- a/src/modules/admin/admin_module.py +++ b/src/modules/admin/admin_module.py @@ -16,7 +16,7 @@ class AdminModule(ModuleABC): def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC): pass - def configure_services(self, service: ServiceCollectionABC, env: ApplicationEnvironmentABC): + def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC): # commands self._dc.add_command(RestartCommand) self._dc.add_command(ShutdownCommand) diff --git a/src/modules/admin/command/restart_command.py b/src/modules/admin/command/restart_command.py index 3cd78694..179eeceb 100644 --- a/src/modules/admin/command/restart_command.py +++ b/src/modules/admin/command/restart_command.py @@ -1,3 +1,6 @@ +import asyncio + +import discord from cpl_core.configuration import ConfigurationABC from cpl_discord.command import DiscordCommandABC from cpl_discord.service import DiscordBotServiceABC @@ -7,6 +10,7 @@ from discord.ext.commands import Context from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC from bot_core.abc.message_service_abc import MessageServiceABC +from bot_core.configuration.bot_settings import BotSettings from bot_core.logging.command_logger import CommandLogger from modules.permission.abc.permission_service_abc import PermissionServiceABC @@ -22,6 +26,7 @@ class RestartCommand(DiscordCommandABC): client_utils: ClientUtilsServiceABC, translate: TranslatePipe, permissions: PermissionServiceABC, + settings: BotSettings ): DiscordCommandABC.__init__(self) @@ -32,6 +37,7 @@ class RestartCommand(DiscordCommandABC): self._client_utils = client_utils self._t = translate self._permissions = permissions + self._settings = settings self._logger.trace(__name__, f'Loaded command service: {type(self).__name__}') @@ -50,6 +56,8 @@ class RestartCommand(DiscordCommandABC): return self._config.add_configuration('IS_RESTART', 'true') + await self._client_utils.presence_game('common.presence.restart') + await asyncio.sleep(self._settings.wait_for_restart) await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.admin.restart_message')) await self._bot.stop_async() diff --git a/src/modules/admin/command/shutdown_command.py b/src/modules/admin/command/shutdown_command.py index f63de698..b4177c54 100644 --- a/src/modules/admin/command/shutdown_command.py +++ b/src/modules/admin/command/shutdown_command.py @@ -1,3 +1,6 @@ +import asyncio + +import discord from cpl_core.configuration import ConfigurationABC from cpl_discord.command import DiscordCommandABC from cpl_discord.service import DiscordBotServiceABC @@ -7,6 +10,7 @@ from discord.ext.commands import Context from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC from bot_core.abc.message_service_abc import MessageServiceABC +from bot_core.configuration.bot_settings import BotSettings from bot_core.logging.command_logger import CommandLogger from modules.permission.abc.permission_service_abc import PermissionServiceABC @@ -22,6 +26,7 @@ class ShutdownCommand(DiscordCommandABC): client_utils: ClientUtilsServiceABC, translate: TranslatePipe, permissions: PermissionServiceABC, + settings: BotSettings ): DiscordCommandABC.__init__(self) @@ -32,6 +37,7 @@ class ShutdownCommand(DiscordCommandABC): self._client_utils = client_utils self._t = translate self._permissions = permissions + self._settings = settings self._logger.trace(__name__, f'Loaded command service: {type(self).__name__}') @@ -49,6 +55,8 @@ class ShutdownCommand(DiscordCommandABC): self._logger.trace(__name__, f'Finished shutdown command') return + await self._client_utils.presence_game('common.presence.shutdown') + await asyncio.sleep(self._settings.wait_for_shutdown) await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.admin.shutdown_message')) await self._bot.stop_async() diff --git a/src/modules/base/base_module.py b/src/modules/base/base_module.py index 08d43748..d666a823 100644 --- a/src/modules/base/base_module.py +++ b/src/modules/base/base_module.py @@ -5,6 +5,7 @@ from cpl_discord.discord_event_types_enum import DiscordEventTypesEnum from cpl_discord.service.discord_collection_abc import DiscordCollectionABC from bot_core.abc.module_abc import ModuleABC +from modules.base.abc.base_helper_abc import BaseHelperABC from modules.base.command.afk_command import AFKCommand from modules.base.command.help_command import HelpCommand from modules.base.command.info_command import InfoCommand @@ -16,6 +17,7 @@ from modules.base.events.base_on_member_join_event import BaseOnMemberJoinEvent from modules.base.events.base_on_member_remove_event import BaseOnMemberRemoveEvent from modules.base.events.base_on_message_event import BaseOnMessageEvent from modules.base.events.base_on_voice_state_update_event import BaseOnVoiceStateUpdateEvent +from modules.base.service.base_helper_service import BaseHelperService class BaseModule(ModuleABC): @@ -26,7 +28,8 @@ class BaseModule(ModuleABC): def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC): pass - def configure_services(self, service: ServiceCollectionABC, env: ApplicationEnvironmentABC): + def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC): + services.add_transient(BaseHelperABC, BaseHelperService) # commands self._dc.add_command(AFKCommand) self._dc.add_command(HelpCommand) diff --git a/src/modules/base/command/info_command.py b/src/modules/base/command/info_command.py index 2b517aa2..f7183cde 100644 --- a/src/modules/base/command/info_command.py +++ b/src/modules/base/command/info_command.py @@ -60,7 +60,9 @@ class InfoCommand(DiscordCommandABC): embed.add_field(name=self._t.transform('modules.base.info.fields.deleted_message_count'), value=client.deleted_message_count, inline=False) embed.add_field(name=self._t.transform('modules.base.info.fields.received_command_count'), value=client.received_command_count) embed.add_field(name=self._t.transform('modules.base.info.fields.moved_users_count'), value=client.moved_users_count) - modules = ['Admin', 'Base', 'BootLog', 'Database', 'Moderator', 'Permission'] + from bot.module_list import ModuleList + modules = ModuleList.get_modules() + modules = modules.select(lambda x: x.replace('Module', '')) embed.add_field(name=self._t.transform('modules.base.info.fields.modules'), value='\n'.join(modules), inline=False) await self._message_service.send_ctx_msg(ctx, embed, wait_before_delete=wait) diff --git a/src/modules/boot_log/boot_log_module.py b/src/modules/boot_log/boot_log_module.py index 7f533ce1..3ce3ca13 100644 --- a/src/modules/boot_log/boot_log_module.py +++ b/src/modules/boot_log/boot_log_module.py @@ -16,7 +16,7 @@ class BootLogModule(ModuleABC): def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC): pass - def configure_services(self, service: ServiceCollectionABC, env: ApplicationEnvironmentABC): + def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC): # commands # events self._dc.add_event(DiscordEventTypesEnum.on_ready.value, BootLogOnReadyEvent) diff --git a/src/modules/database/database_module.py b/src/modules/database/database_module.py index 4deedcbf..3234ab18 100644 --- a/src/modules/database/database_module.py +++ b/src/modules/database/database_module.py @@ -16,7 +16,7 @@ class DatabaseModule(ModuleABC): def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC): pass - def configure_services(self, service: ServiceCollectionABC, env: ApplicationEnvironmentABC): + def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC): # commands # events self._dc.add_event(DiscordEventTypesEnum.on_ready.value, DatabaseOnReadyEvent) diff --git a/src/modules/moderator/moderator_module.py b/src/modules/moderator/moderator_module.py index 6f0d6013..d5240ac1 100644 --- a/src/modules/moderator/moderator_module.py +++ b/src/modules/moderator/moderator_module.py @@ -15,7 +15,7 @@ class ModeratorModule(ModuleABC): def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC): pass - def configure_services(self, service: ServiceCollectionABC, env: ApplicationEnvironmentABC): + def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC): # commands self._dc.add_command(PurgeCommand) # events diff --git a/src/modules/permission/permission_module.py b/src/modules/permission/permission_module.py index a5f0b5a7..7284b99c 100644 --- a/src/modules/permission/permission_module.py +++ b/src/modules/permission/permission_module.py @@ -5,8 +5,10 @@ from cpl_discord.discord_event_types_enum import DiscordEventTypesEnum from cpl_discord.service.discord_collection_abc import DiscordCollectionABC from bot_core.abc.module_abc import ModuleABC +from modules.permission.abc.permission_service_abc import PermissionServiceABC from modules.permission.events.permission_on_member_update_event import PermissionOnMemberUpdateEvent from modules.permission.events.permission_on_ready_event import PermissionOnReadyEvent +from modules.permission.service.permission_service import PermissionService class PermissionModule(ModuleABC): @@ -17,7 +19,8 @@ class PermissionModule(ModuleABC): def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC): pass - def configure_services(self, service: ServiceCollectionABC, env: ApplicationEnvironmentABC): + def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC): + services.add_singleton(PermissionServiceABC, PermissionService) # commands # events self._dc.add_event(DiscordEventTypesEnum.on_ready.value, PermissionOnReadyEvent)