diff --git a/kdb-bot/cpl-workspace.json b/kdb-bot/cpl-workspace.json index 5c606705..5a5654f3 100644 --- a/kdb-bot/cpl-workspace.json +++ b/kdb-bot/cpl-workspace.json @@ -19,14 +19,16 @@ "set-version": "tools/set_version/set-version.json" }, "Scripts": { + "format": "black ./", + "sv": "cpl set-version $ARGS", "set-version": "cpl run set-version $ARGS --dev; echo '';", "gv": "cpl get-version", "get-version": "export VERSION=$(cpl run get-version --dev); echo $VERSION;", - "pre-build": "cpl set-version $ARGS", - "post-build": "cpl run post-build --dev", + "pre-build": "cpl set-version $ARGS; black ./;", + "post-build": "cpl run post-build --dev; black ./;", "pre-prod": "cpl build", "prod": "export KDB_ENVIRONMENT=production; export KDB_NAME=KDB-Prod; cpl start;", diff --git a/kdb-bot/docker b/kdb-bot/docker index 48c26839..6b25cc87 160000 --- a/kdb-bot/docker +++ b/kdb-bot/docker @@ -1 +1 @@ -Subproject commit 48c2683965611c9a96ebbb908f8dcb4d0d7d71f2 +Subproject commit 6b25cc87fced30b5846505d95f20285a3e4d7adf diff --git a/kdb-bot/dockerfile b/kdb-bot/dockerfile index d428fb90..282eb8c6 100644 --- a/kdb-bot/dockerfile +++ b/kdb-bot/dockerfile @@ -1,5 +1,5 @@ # syntax=docker/dockerfile:1 -FROM python:3.10.6-alpine +FROM python:3.10.4-alpine WORKDIR /app COPY ./dist/bot/build/kdb-bot/ . diff --git a/kdb-bot/pyproject.toml b/kdb-bot/pyproject.toml new file mode 100644 index 00000000..e34796ec --- /dev/null +++ b/kdb-bot/pyproject.toml @@ -0,0 +1,2 @@ +[tool.black] +line-length = 120 \ No newline at end of file diff --git a/kdb-bot/src/bot/__init__.py b/kdb-bot/src/bot/__init__.py index bec166fa..687db4c3 100644 --- a/kdb-bot/src/bot/__init__.py +++ b/kdb-bot/src/bot/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'bot' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "bot" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple -# imports: +# imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/bot/application.py b/kdb-bot/src/bot/application.py index 1cfa2caa..34872d59 100644 --- a/kdb-bot/src/bot/application.py +++ b/kdb-bot/src/bot/application.py @@ -13,7 +13,6 @@ from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings class Application(DiscordBotApplicationABC): - def __init__(self, config: ConfigurationABC, services: ServiceProviderABC): DiscordBotApplicationABC.__init__(self, config, services) @@ -42,18 +41,22 @@ class Application(DiscordBotApplicationABC): async def main(self): try: - self._logger.debug(__name__, f'Starting...') + self._logger.debug(__name__, f"Starting...") - if self._feature_flags.get_flag(FeatureFlagsEnum.api_module) and self._feature_flags.get_flag(FeatureFlagsEnum.api_only) and self._environment.environment_name == 'development': + if ( + self._feature_flags.get_flag(FeatureFlagsEnum.api_module) + and self._feature_flags.get_flag(FeatureFlagsEnum.api_only) + and self._environment.environment_name == "development" + ): self._api.start() self._api.join() return - self._logger.trace(__name__, f'Try to start {DiscordBotService.__name__}') + 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) + self._logger.error(__name__, "Start failed", e) async def stop_async(self): if self._is_stopping: @@ -61,13 +64,13 @@ class Application(DiscordBotApplicationABC): self._is_stopping = True try: - self._logger.trace(__name__, f'Try to stop {DiscordBotService.__name__}') + self._logger.trace(__name__, f"Try to stop {DiscordBotService.__name__}") await self._bot.close() - self._logger.trace(__name__, f'Stopped {DiscordBotService.__name__}') + self._logger.trace(__name__, f"Stopped {DiscordBotService.__name__}") except Exception as e: - self._logger.error(__name__, 'stop failed', 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 # + return True if self._configuration.get_configuration("IS_RESTART") == "true" else False # diff --git a/kdb-bot/src/bot/bot.json b/kdb-bot/src/bot/bot.json index 84dbac92..8d20c966 100644 --- a/kdb-bot/src/bot/bot.json +++ b/kdb-bot/src/bot/bot.json @@ -4,22 +4,22 @@ "Version": { "Major": "0", "Minor": "3", - "Micro": "0" + "Micro": "1" }, "Author": "Sven Heidemann", "AuthorEmail": "sven.heidemann@sh-edraft.de", "Description": "Keksdose bot", "LongDescription": "Discord bot for the Keksdose discord Server", "URL": "https://www.sh-edraft.de", - "CopyrightDate": "2022", + "CopyrightDate": "2022 - 2023", "CopyrightName": "sh-edraft.de", "LicenseName": "MIT", "LicenseDescription": "MIT, see LICENSE for more details.", "Dependencies": [ - "cpl-core==2022.12.0", - "cpl-translation==2022.10.0.post2", - "cpl-query==2022.12.2", - "cpl-discord==2022.12.0", + "cpl-core==2022.12.1.post2", + "cpl-translation==2022.12.1", + "cpl-query==2022.12.2.post1", + "cpl-discord==2022.12.1.post2", "Flask==2.2.2", "Flask-Classful==0.14.2", "Flask-Cors==3.0.10", @@ -31,7 +31,7 @@ "icmplib==3.0.3" ], "DevDependencies": [ - "cpl-cli==2022.12.0" + "cpl-cli==2022.12.1.post2" ], "PythonVersion": ">=3.10.4", "PythonPath": {}, diff --git a/kdb-bot/src/bot/config b/kdb-bot/src/bot/config index e6faabbd..54b1b386 160000 --- a/kdb-bot/src/bot/config +++ b/kdb-bot/src/bot/config @@ -1 +1 @@ -Subproject commit e6faabbd8b9fe0dbd00533ea1647e7094ea8b19e +Subproject commit 54b1b3860cb570d29c8ba2590dd082a1fa744265 diff --git a/kdb-bot/src/bot/extension/__init__.py b/kdb-bot/src/bot/extension/__init__.py new file mode 100644 index 00000000..04fcb1e5 --- /dev/null +++ b/kdb-bot/src/bot/extension/__init__.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- + +""" +bot Keksdose bot +~~~~~~~~~~~~~~~~~~~ + +Discord bot for the Keksdose discord Server + +:copyright: (c) 2022 - 2023 sh-edraft.de +:license: MIT, see LICENSE for more details. + +""" + +__title__ = "bot.extension" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" + +from collections import namedtuple + + +# imports: + +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/bot/extension/init_bot_extension.py b/kdb-bot/src/bot/extension/init_bot_extension.py new file mode 100644 index 00000000..a4e0732a --- /dev/null +++ b/kdb-bot/src/bot/extension/init_bot_extension.py @@ -0,0 +1,16 @@ +from cpl_core.application import ApplicationExtensionABC +from cpl_core.configuration import ConfigurationABC +from cpl_core.dependency_injection import ServiceProviderABC +from cpl_discord.service import DiscordBotServiceABC + +from bot_core.configuration.bot_settings import BotSettings + + +class InitBotExtension(ApplicationExtensionABC): + def __init__(self): + ApplicationExtensionABC.__init__(self) + + async def run(self, config: ConfigurationABC, services: ServiceProviderABC): + settings = config.get_configuration(BotSettings) + + bot: DiscordBotServiceABC = services.get_service(DiscordBotServiceABC, max_messages=settings.cache_max_messages) diff --git a/kdb-bot/src/bot/main.py b/kdb-bot/src/bot/main.py index b5e2a6c2..ed03af25 100644 --- a/kdb-bot/src/bot/main.py +++ b/kdb-bot/src/bot/main.py @@ -6,6 +6,7 @@ from cpl_core.application import ApplicationBuilder from cpl_core.console import Console from bot.application import Application +from bot.extension.init_bot_extension import InitBotExtension from bot.startup import Startup from bot.startup_discord_extension import StartupDiscordExtension from bot.startup_migration_extension import StartupMigrationExtension @@ -18,22 +19,24 @@ from modules.database.database_extension import DatabaseExtension class Program: - def __init__(self): self.app: Optional[Application] = None async def start(self): # discord extension has to be loaded before modules (modules depends on discord stuff) - app_builder = ApplicationBuilder(Application) \ - .use_extension(StartupSettingsExtension) \ - .use_extension(StartupDiscordExtension) \ - .use_extension(StartupModuleExtension) \ - .use_extension(StartupMigrationExtension) \ - .use_extension(BootLogExtension) \ - .use_extension(DatabaseExtension) \ - .use_extension(AppApiExtension) \ - .use_extension(CoreExtension) \ + app_builder = ( + ApplicationBuilder(Application) + .use_extension(StartupSettingsExtension) + .use_extension(StartupDiscordExtension) + .use_extension(StartupModuleExtension) + .use_extension(StartupMigrationExtension) + .use_extension(InitBotExtension) + .use_extension(BootLogExtension) + .use_extension(DatabaseExtension) + .use_extension(AppApiExtension) + .use_extension(CoreExtension) .use_startup(Startup) + ) self.app: Application = await app_builder.build_async() await self.app.run_async() @@ -50,19 +53,25 @@ def main(): except KeyboardInterrupt: asyncio.run(program.stop()) except Exception as e: - Console.error(f'[ ERROR ] [ {__name__} ]: Cannot start the bot', f'{e} -> {traceback.format_exc()}') + Console.error( + f"[ ERROR ] [ {__name__} ]: Cannot start the bot", + f"{e} -> {traceback.format_exc()}", + ) finally: try: asyncio.run(program.stop()) except Exception as e: - Console.error(f'[ ERROR ] [ {__name__} ]: Cannot stop the bot', f'{e} -> {traceback.format_exc()}') + Console.error( + f"[ ERROR ] [ {__name__} ]: Cannot stop the bot", + f"{e} -> {traceback.format_exc()}", + ) if program.app is not None and program.app.is_restart(): del program main() -if __name__ == '__main__': +if __name__ == "__main__": main() # (( diff --git a/kdb-bot/src/bot/module_list.py b/kdb-bot/src/bot/module_list.py index ba6be127..a48a2e39 100644 --- a/kdb-bot/src/bot/module_list.py +++ b/kdb-bot/src/bot/module_list.py @@ -15,22 +15,24 @@ from modules.technician.technician_module import TechnicianModule 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, - PermissionModule, - DatabaseModule, - AutoRoleModule, - BaseModule, - LevelModule, - ApiModule, - StatsModule, - TechnicianModule, - # has to be last! - BootLogModule, - CoreExtensionModule, - ]) + return List( + type, + [ + CoreModule, # has to be first! + DataModule, + PermissionModule, + DatabaseModule, + AutoRoleModule, + BaseModule, + LevelModule, + ApiModule, + StatsModule, + TechnicianModule, + # has to be last! + BootLogModule, + CoreExtensionModule, + ], + ) diff --git a/kdb-bot/src/bot/startup.py b/kdb-bot/src/bot/startup.py index 1384fbd9..6895ddc8 100644 --- a/kdb-bot/src/bot/startup.py +++ b/kdb-bot/src/bot/startup.py @@ -20,7 +20,6 @@ from bot_data.db_context import DBContext class Startup(StartupABC): - def __init__(self): StartupABC.__init__(self) self._start_time = datetime.now() @@ -28,12 +27,16 @@ class Startup(StartupABC): self._config: Optional[ConfigurationABC] = None self._feature_flags: Optional[FeatureFlagsSettings] = None - def configure_configuration(self, configuration: ConfigurationABC, environment: ApplicationEnvironment) -> ConfigurationABC: + def configure_configuration( + self, configuration: ConfigurationABC, environment: ApplicationEnvironment + ) -> ConfigurationABC: self._config = configuration self._feature_flags = configuration.get_configuration(FeatureFlagsSettings) return configuration - def configure_services(self, services: ServiceCollectionABC, environment: ApplicationEnvironment) -> ServiceProviderABC: + def configure_services( + self, services: ServiceCollectionABC, environment: ApplicationEnvironment + ) -> ServiceProviderABC: services.add_logging() if self._feature_flags.get_flag(FeatureFlagsEnum.core_module): # custom logging @@ -52,9 +55,11 @@ class Startup(StartupABC): for c in CustomFileLoggerABC.__subclasses__(): i: LoggerABC = provider.get_service(c) - logger: LoggerABC = provider.get_service(LoggerABC) for flag in [f for f in FeatureFlagsEnum]: - logger.debug(__name__, f'Loaded feature-flag: {flag} = {self._feature_flags.get_flag(flag)}') + logger.debug( + __name__, + f"Loaded feature-flag: {flag} = {self._feature_flags.get_flag(flag)}", + ) return provider diff --git a/kdb-bot/src/bot/startup_discord_extension.py b/kdb-bot/src/bot/startup_discord_extension.py index de665b1a..196017dc 100644 --- a/kdb-bot/src/bot/startup_discord_extension.py +++ b/kdb-bot/src/bot/startup_discord_extension.py @@ -6,7 +6,6 @@ from cpl_discord import get_discord_collection class StartupDiscordExtension(StartupExtensionABC): - def __init__(self): pass diff --git a/kdb-bot/src/bot/startup_migration_extension.py b/kdb-bot/src/bot/startup_migration_extension.py index a4bd452c..4f149463 100644 --- a/kdb-bot/src/bot/startup_migration_extension.py +++ b/kdb-bot/src/bot/startup_migration_extension.py @@ -10,11 +10,13 @@ from bot_data.migration.auto_role_migration import AutoRoleMigration from bot_data.migration.initial_migration import InitialMigration from bot_data.migration.level_migration import LevelMigration from bot_data.migration.stats_migration import StatsMigration +from bot_data.migration.user_message_count_per_hour_migration import ( + UserMessageCountPerHourMigration, +) from bot_data.service.migration_service import MigrationService class StartupMigrationExtension(StartupExtensionABC): - def __init__(self): pass @@ -29,3 +31,4 @@ class StartupMigrationExtension(StartupExtensionABC): services.add_transient(MigrationABC, LevelMigration) # 06.11.2022 #25 - 0.3.0 services.add_transient(MigrationABC, StatsMigration) # 09.11.2022 #46 - 0.3.0 services.add_transient(MigrationABC, AutoRoleFix1Migration) # 30.12.2022 #151 - 0.3.0 + services.add_transient(MigrationABC, UserMessageCountPerHourMigration) # 11.01.2023 #168 - 0.3.1 diff --git a/kdb-bot/src/bot/startup_module_extension.py b/kdb-bot/src/bot/startup_module_extension.py index 70f1b184..2d87319d 100644 --- a/kdb-bot/src/bot/startup_module_extension.py +++ b/kdb-bot/src/bot/startup_module_extension.py @@ -12,7 +12,6 @@ from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings class StartupModuleExtension(StartupExtensionABC): - def __init__(self): self._config: Optional[ConfigurationABC] = None self._feature_flags: Optional[FeatureFlagsSettings] = None @@ -33,7 +32,7 @@ class StartupModuleExtension(StartupExtensionABC): continue Console.set_foreground_color(ForegroundColorEnum.green) - Console.write_line(f'[{__name__}] Loaded module: {module_type}') + Console.write_line(f"[{__name__}] Loaded module: {module_type}") Console.color_reset() module.configure_configuration(self._config, env) module.configure_services(services, env) diff --git a/kdb-bot/src/bot/startup_settings_extension.py b/kdb-bot/src/bot/startup_settings_extension.py index 655ccd7b..008ebd10 100644 --- a/kdb-bot/src/bot/startup_settings_extension.py +++ b/kdb-bot/src/bot/startup_settings_extension.py @@ -16,38 +16,45 @@ from modules.permission.configuration.permission_settings import PermissionSetti class StartupSettingsExtension(StartupExtensionABC): - def __init__(self): self._start_time = datetime.now() def configure_configuration(self, configuration: ConfigurationABC, environment: ApplicationEnvironmentABC): # this shit has to be done here because we need settings in subsequent startup extensions environment.set_working_directory(os.path.dirname(os.path.realpath(__file__))) - configuration.add_environment_variables('KDB_') - configuration.add_environment_variables('DISCORD_') + configuration.add_environment_variables("KDB_") + configuration.add_environment_variables("DISCORD_") - configuration.add_json_file(f'config/appsettings.json', optional=False) - configuration.add_json_file(f'config/appsettings.{environment.environment_name}.json', optional=True) - configuration.add_json_file(f'config/appsettings.{environment.host_name}.json', optional=True) + configuration.add_json_file(f"config/appsettings.json", optional=False) + configuration.add_json_file(f"config/appsettings.{environment.environment_name}.json", optional=True) + configuration.add_json_file(f"config/appsettings.{environment.host_name}.json", optional=True) # load feature-flags - configuration.add_json_file(f'config/feature-flags.json', optional=False) + configuration.add_json_file(f"config/feature-flags.json", optional=False) + configuration.add_json_file(f"config/feature-flags.{environment.environment_name}.json", optional=True) + configuration.add_json_file(f"config/feature-flags.{environment.host_name}.json", optional=True) - configuration.add_configuration('Startup_StartTime', str(self._start_time)) + configuration.add_configuration("Startup_StartTime", str(self._start_time)) self._configure_settings_with_sub_settings(configuration, BotSettings, lambda x: x.servers, lambda x: x.id) self._configure_settings_with_sub_settings(configuration, BaseSettings, lambda x: x.servers, lambda x: x.id) self._configure_settings_with_sub_settings(configuration, BootLogSettings, lambda x: x.servers, lambda x: x.id) self._configure_settings_with_sub_settings(configuration, LevelSettings, lambda x: x.servers, lambda x: x.id) - self._configure_settings_with_sub_settings(configuration, PermissionSettings, lambda x: x.servers, lambda x: x.id) - self._configure_settings_with_sub_settings(configuration, BotLoggingSettings, lambda x: x.files, lambda x: x.key) + self._configure_settings_with_sub_settings( + configuration, PermissionSettings, lambda x: x.servers, lambda x: x.id + ) + self._configure_settings_with_sub_settings( + configuration, BotLoggingSettings, lambda x: x.files, lambda x: x.key + ) def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC): pass @staticmethod - def _configure_settings_with_sub_settings(config: ConfigurationABC, settings: Type, list_atr: Callable, atr: Callable): + def _configure_settings_with_sub_settings( + config: ConfigurationABC, settings: Type, list_atr: Callable, atr: Callable + ): settings: Optional[settings] = config.get_configuration(settings) if settings is None: return for sub_settings in list_atr(settings): - config.add_configuration(f'{type(sub_settings).__name__}_{atr(sub_settings)}', sub_settings) + config.add_configuration(f"{type(sub_settings).__name__}_{atr(sub_settings)}", sub_settings) diff --git a/kdb-bot/src/bot/translation/de.json b/kdb-bot/src/bot/translation/de.json index f62a3422..17524fc7 100644 --- a/kdb-bot/src/bot/translation/de.json +++ b/kdb-bot/src/bot/translation/de.json @@ -187,7 +187,13 @@ "type_error": "Der angegebene Wert ist keine Zahl! :(" } }, + "add": { + "xp": "Die {} von {} wurden um {} erhöht" + }, "remove": { + "xp": "Die {} von {} wurden um {} verringert" + }, + "reset": { "xp": "Die {} von {} wurden entfernt", "ontime": "Die {} von {} wurden entfernt" }, diff --git a/kdb-bot/src/bot_api/__init__.py b/kdb-bot/src/bot_api/__init__.py index 6029ae84..00db07e4 100644 --- a/kdb-bot/src/bot_api/__init__.py +++ b/kdb-bot/src/bot_api/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'bot_api' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "bot_api" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple -# imports: +# imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/bot_api/abc/__init__.py b/kdb-bot/src/bot_api/abc/__init__.py index 25aa13fe..24fd1765 100644 --- a/kdb-bot/src/bot_api/abc/__init__.py +++ b/kdb-bot/src/bot_api/abc/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'bot_api.abc' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "bot_api.abc" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/bot_api/abc/auth_service_abc.py b/kdb-bot/src/bot_api/abc/auth_service_abc.py index a444cbc4..34c1b5f2 100644 --- a/kdb-bot/src/bot_api/abc/auth_service_abc.py +++ b/kdb-bot/src/bot_api/abc/auth_service_abc.py @@ -15,78 +15,102 @@ from bot_data.model.auth_user import AuthUser class AuthServiceABC(ABC): + @abstractmethod + def __init__(self): + pass @abstractmethod - def __init__(self): pass + def generate_token(self, user: AuthUser) -> str: + pass @abstractmethod - def generate_token(self, user: AuthUser) -> str: pass + def decode_token(self, token: str) -> dict: + pass @abstractmethod - def decode_token(self, token: str) -> dict: pass + def get_decoded_token_from_request(self) -> dict: + pass @abstractmethod - def get_decoded_token_from_request(self) -> dict: pass + def find_decoded_token_from_request(self) -> Optional[dict]: + pass @abstractmethod - def find_decoded_token_from_request(self) -> Optional[dict]: pass + async def get_all_auth_users_async(self) -> List[AuthUserDTO]: + pass @abstractmethod - async def get_all_auth_users_async(self) -> List[AuthUserDTO]: pass + async def get_filtered_auth_users_async(self, criteria: AuthUserSelectCriteria) -> AuthUserFilteredResultDTO: + pass @abstractmethod - async def get_filtered_auth_users_async(self, criteria: AuthUserSelectCriteria) -> AuthUserFilteredResultDTO: pass + async def get_auth_user_by_email_async(self, email: str, with_password: bool = False) -> AuthUserDTO: + pass @abstractmethod - async def get_auth_user_by_email_async(self, email: str, with_password: bool = False) -> AuthUserDTO: pass + async def find_auth_user_by_email_async(self, email: str) -> AuthUserDTO: + pass @abstractmethod - async def find_auth_user_by_email_async(self, email: str) -> AuthUserDTO: pass + async def add_auth_user_async(self, user_dto: AuthUserDTO): + pass @abstractmethod - async def add_auth_user_async(self, user_dto: AuthUserDTO): pass + async def add_auth_user_by_oauth_async(self, dto: OAuthDTO): + pass @abstractmethod - async def add_auth_user_by_oauth_async(self, dto: OAuthDTO): pass + async def add_auth_user_by_discord_async(self, user_dto: AuthUserDTO, dc_id: int) -> OAuthDTO: + pass @abstractmethod - async def add_auth_user_by_discord_async(self, user_dto: AuthUserDTO, dc_id: int) -> OAuthDTO: pass + async def update_user_async(self, update_user_dto: UpdateAuthUserDTO): + pass @abstractmethod - async def update_user_async(self, update_user_dto: UpdateAuthUserDTO): pass + async def update_user_as_admin_async(self, update_user_dto: UpdateAuthUserDTO): + pass @abstractmethod - async def update_user_as_admin_async(self, update_user_dto: UpdateAuthUserDTO): pass + async def delete_auth_user_by_email_async(self, email: str): + pass @abstractmethod - async def delete_auth_user_by_email_async(self, email: str): pass + async def delete_auth_user_async(self, user_dto: AuthUserDTO): + pass @abstractmethod - async def delete_auth_user_async(self, user_dto: AuthUserDTO): pass + async def verify_login(self, token_str: str) -> bool: + pass @abstractmethod - async def verify_login(self, token_str: str) -> bool: pass + async def login_async(self, user_dto: AuthUserDTO) -> TokenDTO: + pass @abstractmethod - async def login_async(self, user_dto: AuthUserDTO) -> TokenDTO: pass + async def login_discord_async(self, oauth_dto: AuthUserDTO) -> TokenDTO: + pass @abstractmethod - async def login_discord_async(self, oauth_dto: AuthUserDTO) -> TokenDTO: pass + async def refresh_async(self, token_dto: TokenDTO) -> TokenDTO: + pass @abstractmethod - async def refresh_async(self, token_dto: TokenDTO) -> TokenDTO: pass + async def revoke_async(self, token_dto: TokenDTO): + pass @abstractmethod - async def revoke_async(self, token_dto: TokenDTO): pass + async def confirm_email_async(self, id: str) -> bool: + pass @abstractmethod - async def confirm_email_async(self, id: str) -> bool: pass + async def forgot_password_async(self, email: str): + pass @abstractmethod - async def forgot_password_async(self, email: str): pass + async def confirm_forgot_password_async(self, id: str) -> EMailStringDTO: + pass @abstractmethod - async def confirm_forgot_password_async(self, id: str) -> EMailStringDTO: pass - - @abstractmethod - async def reset_password_async(self, rp_dto: ResetPasswordDTO): pass + async def reset_password_async(self, rp_dto: ResetPasswordDTO): + pass diff --git a/kdb-bot/src/bot_api/abc/dto_abc.py b/kdb-bot/src/bot_api/abc/dto_abc.py index 58b458ad..eb7d818e 100644 --- a/kdb-bot/src/bot_api/abc/dto_abc.py +++ b/kdb-bot/src/bot_api/abc/dto_abc.py @@ -2,12 +2,14 @@ from abc import ABC, abstractmethod class DtoABC(ABC): + @abstractmethod + def __init__(self): + pass @abstractmethod - def __init__(self): pass + def from_dict(self, values: dict): + pass @abstractmethod - def from_dict(self, values: dict): pass - - @abstractmethod - def to_dict(self) -> dict: pass + def to_dict(self) -> dict: + pass diff --git a/kdb-bot/src/bot_api/abc/select_criteria_abc.py b/kdb-bot/src/bot_api/abc/select_criteria_abc.py index 234f7865..950b5203 100644 --- a/kdb-bot/src/bot_api/abc/select_criteria_abc.py +++ b/kdb-bot/src/bot_api/abc/select_criteria_abc.py @@ -2,15 +2,8 @@ from abc import ABC, abstractmethod class SelectCriteriaABC(ABC): - @abstractmethod - def __init__( - self, - page_index: int, - page_size: int, - sort_direction: str, - sort_column: str - ): + def __init__(self, page_index: int, page_size: int, sort_direction: str, sort_column: str): self.page_index = page_index self.page_size = page_size self.sort_direction = sort_direction diff --git a/kdb-bot/src/bot_api/abc/transformer_abc.py b/kdb-bot/src/bot_api/abc/transformer_abc.py index 6ff2f676..3be930ab 100644 --- a/kdb-bot/src/bot_api/abc/transformer_abc.py +++ b/kdb-bot/src/bot_api/abc/transformer_abc.py @@ -6,11 +6,12 @@ from bot_api.abc.dto_abc import DtoABC class TransformerABC: + @staticmethod + @abstractmethod + def to_db(dto: DtoABC) -> TableABC: + pass @staticmethod @abstractmethod - def to_db(dto: DtoABC) -> TableABC: pass - - @staticmethod - @abstractmethod - def to_dto(db: TableABC) -> DtoABC: pass + def to_dto(db: TableABC) -> DtoABC: + pass diff --git a/kdb-bot/src/bot_api/api.py b/kdb-bot/src/bot_api/api.py index b31eee19..e8872a5c 100644 --- a/kdb-bot/src/bot_api/api.py +++ b/kdb-bot/src/bot_api/api.py @@ -25,18 +25,18 @@ from bot_api.route.route import Route class Api(Flask): - def __init__( - self, - logger: ApiLogger, - services: ServiceProviderABC, - api_settings: ApiSettings, - frontend_settings: FrontendSettings, - auth_settings: AuthenticationSettings, - *args, **kwargs + self, + logger: ApiLogger, + services: ServiceProviderABC, + api_settings: ApiSettings, + frontend_settings: FrontendSettings, + auth_settings: AuthenticationSettings, + *args, + **kwargs, ): if not args: - kwargs.setdefault('import_name', __name__) + kwargs.setdefault("import_name", __name__) Flask.__init__(self, *args, **kwargs) @@ -56,17 +56,21 @@ class Api(Flask): self.register_error_handler(exc_class, self.handle_exception) # websockets - self._socketio = SocketIO(self, cors_allowed_origins='*', path='/api/socket.io') - self._socketio.on_event('connect', self.on_connect) - self._socketio.on_event('disconnect', self.on_disconnect) + self._socketio = SocketIO(self, cors_allowed_origins="*", path="/api/socket.io") + self._socketio.on_event("connect", self.on_connect) + self._socketio.on_event("disconnect", self.on_disconnect) self._requests = {} @staticmethod def _get_methods_from_registered_route() -> Union[list[str], str]: - methods = ['Unknown'] - if request.path in Route.registered_routes and len(Route.registered_routes[request.path]) >= 1 and 'methods' in Route.registered_routes[request.path][1]: - methods = Route.registered_routes[request.path][1]['methods'] + methods = ["Unknown"] + if ( + request.path in Route.registered_routes + and len(Route.registered_routes[request.path]) >= 1 + and "methods" in Route.registered_routes[request.path][1] + ): + methods = Route.registered_routes[request.path][1]["methods"] if len(methods) == 1: return methods[0] @@ -77,7 +81,7 @@ class Api(Flask): route = f[0] kwargs = f[1] cls = None - qual_name_split = route.__qualname__.split('.') + qual_name_split = route.__qualname__.split(".") if len(qual_name_split) > 0: cls_type = vars(sys.modules[route.__module__])[qual_name_split[0]] cls = self._services.get_service(cls_type) @@ -87,7 +91,7 @@ class Api(Flask): self.route(path, **kwargs)(partial_f) def handle_exception(self, e: Exception): - self._logger.error(__name__, f'Caught error', e) + self._logger.error(__name__, f"Caught error", e) if isinstance(e, ServiceException): ex: ServiceException = e @@ -100,7 +104,7 @@ class Api(Flask): return jsonify(error.to_dict()), 404 else: tracking_id = uuid.uuid4() - user_message = f'Tracking Id: {tracking_id}' + user_message = f"Tracking Id: {tracking_id}" self._logger.error(__name__, user_message, e) error = ErrorDTO(None, user_message) return jsonify(error.to_dict()), 400 @@ -110,34 +114,42 @@ class Api(Flask): self._requests[request] = request_id method = request.access_control_request_method - self._logger.info(__name__, f'Received {request_id} @ {self._get_methods_from_registered_route() if method is None else method} {request.url} from {request.remote_addr}') + self._logger.info( + __name__, + f"Received {request_id} @ {self._get_methods_from_registered_route() if method is None else method} {request.url} from {request.remote_addr}", + ) - headers = str(request.headers).replace('\n', '\n\t\t') + headers = str(request.headers).replace("\n", "\n\t\t") data = request.get_data() - data = '' if len(data) == 0 else str(data.decode(encoding="utf-8")) + data = "" if len(data) == 0 else str(data.decode(encoding="utf-8")) - text = textwrap.dedent(f'Request: {request_id}:\n\tHeader:\n\t\t{headers}\n\tUser-Agent: {request.user_agent.string}\n\tBody: {data}') + text = textwrap.dedent( + f"Request: {request_id}:\n\tHeader:\n\t\t{headers}\n\tUser-Agent: {request.user_agent.string}\n\tBody: {data}" + ) self._logger.trace(__name__, text) def after_request_hook(self, response: Response): method = request.access_control_request_method - request_id = f'{self._get_methods_from_registered_route() if method is None else method} {request.url} from {request.remote_addr}' + request_id = f"{self._get_methods_from_registered_route() if method is None else method} {request.url} from {request.remote_addr}" if request in self._requests: request_id = self._requests[request] - self._logger.info(__name__, f'Answered {request_id}') + self._logger.info(__name__, f"Answered {request_id}") - headers = str(request.headers).replace('\n', '\n\t\t') + headers = str(request.headers).replace("\n", "\n\t\t") data = request.get_data() - data = '' if len(data) == 0 else str(data.decode(encoding="utf-8")) + data = "" if len(data) == 0 else str(data.decode(encoding="utf-8")) - text = textwrap.dedent(f'Request: {request_id}:\n\tHeader:\n\t\t{headers}\n\tResponse: {data}') + text = textwrap.dedent(f"Request: {request_id}:\n\tHeader:\n\t\t{headers}\n\tResponse: {data}") self._logger.trace(__name__, text) return response def start(self): - self._logger.info(__name__, f'Starting API {self._api_settings.host}:{self._api_settings.port}') + self._logger.info( + __name__, + f"Starting API {self._api_settings.host}:{self._api_settings.port}", + ) self._register_routes() self.secret_key = CredentialManager.decrypt(self._auth_settings.secret_key) # from waitress import serve @@ -146,11 +158,11 @@ class Api(Flask): wsgi.server( eventlet.listen((self._api_settings.host, self._api_settings.port)), self, - log_output=False + log_output=False, ) def on_connect(self): - self._logger.info(__name__, f'Client connected') + self._logger.info(__name__, f"Client connected") def on_disconnect(self): - self._logger.info(__name__, f'Client disconnected') + self._logger.info(__name__, f"Client disconnected") diff --git a/kdb-bot/src/bot_api/api_module.py b/kdb-bot/src/bot_api/api_module.py index b4c1735a..81030d51 100644 --- a/kdb-bot/src/bot_api/api_module.py +++ b/kdb-bot/src/bot_api/api_module.py @@ -23,16 +23,15 @@ from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum class ApiModule(ModuleABC): - def __init__(self, dc: DiscordCollectionABC): ModuleABC.__init__(self, dc, FeatureFlagsEnum.api_module) def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC): cwd = env.working_directory env.set_working_directory(os.path.dirname(os.path.realpath(__file__))) - config.add_json_file(f'config/apisettings.json', optional=False) - config.add_json_file(f'config/apisettings.{env.environment_name}.json', optional=True) - config.add_json_file(f'config/apisettings.{env.host_name}.json', optional=True) + config.add_json_file(f"config/apisettings.json", optional=False) + config.add_json_file(f"config/apisettings.{env.environment_name}.json", optional=True) + config.add_json_file(f"config/apisettings.{env.host_name}.json", optional=True) env.set_working_directory(cwd) def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC): diff --git a/kdb-bot/src/bot_api/api_thread.py b/kdb-bot/src/bot_api/api_thread.py index f437d140..d49c0467 100644 --- a/kdb-bot/src/bot_api/api_thread.py +++ b/kdb-bot/src/bot_api/api_thread.py @@ -5,12 +5,7 @@ from bot_api.logging.api_logger import ApiLogger class ApiThread(threading.Thread): - - def __init__( - self, - logger: ApiLogger, - api: Api - ): + def __init__(self, logger: ApiLogger, api: Api): threading.Thread.__init__(self, daemon=True) self._logger = logger @@ -18,7 +13,7 @@ class ApiThread(threading.Thread): def run(self) -> None: try: - self._logger.trace(__name__, f'Try to start {type(self._api).__name__}') + self._logger.trace(__name__, f"Try to start {type(self._api).__name__}") self._api.start() except Exception as e: - self._logger.error(__name__, 'Start failed', e) + self._logger.error(__name__, "Start failed", e) diff --git a/kdb-bot/src/bot_api/app_api_extension.py b/kdb-bot/src/bot_api/app_api_extension.py index c0b5fd12..91075b3d 100644 --- a/kdb-bot/src/bot_api/app_api_extension.py +++ b/kdb-bot/src/bot_api/app_api_extension.py @@ -11,7 +11,6 @@ from bot_data.abc.auth_user_repository_abc import AuthUserRepositoryABC class AppApiExtension(ApplicationExtensionABC): - def __init__(self): ApplicationExtensionABC.__init__(self) diff --git a/kdb-bot/src/bot_api/bot-api.json b/kdb-bot/src/bot_api/bot-api.json index 3e92148b..320bb331 100644 --- a/kdb-bot/src/bot_api/bot-api.json +++ b/kdb-bot/src/bot_api/bot-api.json @@ -4,7 +4,7 @@ "Version": { "Major": "0", "Minor": "3", - "Micro": "0" + "Micro": "1" }, "Author": "", "AuthorEmail": "", diff --git a/kdb-bot/src/bot_api/configuration/__init__.py b/kdb-bot/src/bot_api/configuration/__init__.py index 823f5a2b..93d26788 100644 --- a/kdb-bot/src/bot_api/configuration/__init__.py +++ b/kdb-bot/src/bot_api/configuration/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'bot_api.configuration' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "bot_api.configuration" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/bot_api/configuration/api_settings.py b/kdb-bot/src/bot_api/configuration/api_settings.py index 237a272e..eb136f3b 100644 --- a/kdb-bot/src/bot_api/configuration/api_settings.py +++ b/kdb-bot/src/bot_api/configuration/api_settings.py @@ -5,12 +5,11 @@ from cpl_core.console import Console class ApiSettings(ConfigurationModelABC): - def __init__(self): ConfigurationModelABC.__init__(self) self._port = 80 - self._host = '' + self._host = "" self._redirect_to_https = False @property @@ -27,9 +26,9 @@ class ApiSettings(ConfigurationModelABC): def from_dict(self, settings: dict): try: - self._port = int(settings['Port']) - self._host = settings['Host'] - self._redirect_to_https = bool(settings['RedirectToHTTPS']) + self._port = int(settings["Port"]) + self._host = settings["Host"] + self._redirect_to_https = bool(settings["RedirectToHTTPS"]) except Exception as e: - Console.error(f'[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings') - Console.error(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}') + Console.error(f"[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings") + Console.error(f"[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}") diff --git a/kdb-bot/src/bot_api/configuration/authentication_settings.py b/kdb-bot/src/bot_api/configuration/authentication_settings.py index 9a573a8b..72f00c99 100644 --- a/kdb-bot/src/bot_api/configuration/authentication_settings.py +++ b/kdb-bot/src/bot_api/configuration/authentication_settings.py @@ -6,13 +6,12 @@ from cpl_core.console import Console class AuthenticationSettings(ConfigurationModelABC): - def __init__(self): ConfigurationModelABC.__init__(self) - self._secret_key = '' - self._issuer = '' - self._audience = '' + self._secret_key = "" + self._issuer = "" + self._audience = "" self._token_expire_time = 0 self._refresh_token_expire_time = 0 @@ -38,11 +37,11 @@ class AuthenticationSettings(ConfigurationModelABC): def from_dict(self, settings: dict): try: - self._secret_key = settings['SecretKey'] - self._issuer = settings['Issuer'] - self._audience = settings['Audience'] - self._token_expire_time = int(settings['TokenExpireTime']) - self._refresh_token_expire_time = int(settings['RefreshTokenExpireTime']) + self._secret_key = settings["SecretKey"] + self._issuer = settings["Issuer"] + self._audience = settings["Audience"] + self._token_expire_time = int(settings["TokenExpireTime"]) + self._refresh_token_expire_time = int(settings["RefreshTokenExpireTime"]) except Exception as e: - Console.error(f'[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings') - Console.error(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}') + Console.error(f"[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings") + Console.error(f"[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}") diff --git a/kdb-bot/src/bot_api/configuration/discord_authentication_settings.py b/kdb-bot/src/bot_api/configuration/discord_authentication_settings.py index e13c20ba..eaf76eec 100644 --- a/kdb-bot/src/bot_api/configuration/discord_authentication_settings.py +++ b/kdb-bot/src/bot_api/configuration/discord_authentication_settings.py @@ -6,15 +6,14 @@ from cpl_query.extension import List class DiscordAuthenticationSettings(ConfigurationModelABC): - def __init__(self): ConfigurationModelABC.__init__(self) - self._client_secret = '' - self._redirect_url = '' + self._client_secret = "" + self._redirect_url = "" self._scope = List() - self._token_url = '' - self._auth_url = '' + self._token_url = "" + self._auth_url = "" @property def client_secret(self) -> str: @@ -38,11 +37,11 @@ class DiscordAuthenticationSettings(ConfigurationModelABC): def from_dict(self, settings: dict): try: - self._client_secret = settings['ClientSecret'] - self._redirect_url = settings['RedirectURL'] - self._scope = List(str, settings['Scope']) - self._token_url = settings['TokenURL'] - self._auth_url = settings['AuthURL'] + self._client_secret = settings["ClientSecret"] + self._redirect_url = settings["RedirectURL"] + self._scope = List(str, settings["Scope"]) + self._token_url = settings["TokenURL"] + self._auth_url = settings["AuthURL"] except Exception as e: - Console.error(f'[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings') - Console.error(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}') + Console.error(f"[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings") + Console.error(f"[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}") diff --git a/kdb-bot/src/bot_api/configuration/frontend_settings.py b/kdb-bot/src/bot_api/configuration/frontend_settings.py index 2090f5a2..da80ab6c 100644 --- a/kdb-bot/src/bot_api/configuration/frontend_settings.py +++ b/kdb-bot/src/bot_api/configuration/frontend_settings.py @@ -5,11 +5,10 @@ from cpl_core.console import Console class FrontendSettings(ConfigurationModelABC): - def __init__(self): ConfigurationModelABC.__init__(self) - self._url = '' + self._url = "" @property def url(self) -> str: @@ -17,7 +16,7 @@ class FrontendSettings(ConfigurationModelABC): def from_dict(self, settings: dict): try: - self._url = settings['URL'] + self._url = settings["URL"] except Exception as e: - Console.error(f'[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings') - Console.error(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}') + Console.error(f"[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings") + Console.error(f"[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}") diff --git a/kdb-bot/src/bot_api/configuration/version_settings.py b/kdb-bot/src/bot_api/configuration/version_settings.py index ef1af9b6..c1439673 100644 --- a/kdb-bot/src/bot_api/configuration/version_settings.py +++ b/kdb-bot/src/bot_api/configuration/version_settings.py @@ -5,13 +5,7 @@ from cpl_cli.configuration.version_settings_name_enum import VersionSettingsName class VersionSettings(ConfigurationModelABC): - - def __init__( - self, - major: str = None, - minor: str = None, - micro: str = None - ): + def __init__(self, major: str = None, minor: str = None, micro: str = None): ConfigurationModelABC.__init__(self) self._major: Optional[str] = major @@ -32,15 +26,15 @@ class VersionSettings(ConfigurationModelABC): def to_str(self) -> str: if self._micro is None: - return f'{self._major}.{self._minor}' + return f"{self._major}.{self._minor}" else: - return f'{self._major}.{self._minor}.{self._micro}' + return f"{self._major}.{self._minor}.{self._micro}" def from_dict(self, settings: dict): self._major = settings[VersionSettingsNameEnum.major.value] self._minor = settings[VersionSettingsNameEnum.minor.value] micro = settings[VersionSettingsNameEnum.micro.value] - if micro != '': + if micro != "": self._micro = micro def to_dict(self) -> dict: diff --git a/kdb-bot/src/bot_api/controller/__init__.py b/kdb-bot/src/bot_api/controller/__init__.py index e7085405..1f2ea8f7 100644 --- a/kdb-bot/src/bot_api/controller/__init__.py +++ b/kdb-bot/src/bot_api/controller/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'bot_api.controller' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "bot_api.controller" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/bot_api/controller/auth_controller.py b/kdb-bot/src/bot_api/controller/auth_controller.py index 89eaa38b..f47bf75e 100644 --- a/kdb-bot/src/bot_api/controller/auth_controller.py +++ b/kdb-bot/src/bot_api/controller/auth_controller.py @@ -20,18 +20,18 @@ from bot_data.model.auth_role_enum import AuthRoleEnum class AuthController: - BasePath = '/api/auth' + BasePath = "/api/auth" def __init__( - self, - config: ConfigurationABC, - env: ApplicationEnvironmentABC, - logger: ApiLogger, - t: TranslatePipe, - api: Api, - mail_settings: EMailClientSettings, - mailer: EMailClientABC, - auth_service: AuthServiceABC + self, + config: ConfigurationABC, + env: ApplicationEnvironmentABC, + logger: ApiLogger, + t: TranslatePipe, + api: Api, + mail_settings: EMailClientSettings, + mailer: EMailClientABC, + auth_service: AuthServiceABC, ): self._config = config self._env = env @@ -42,55 +42,57 @@ class AuthController: self._mailer = mailer self._auth_service = auth_service - @Route.get(f'{BasePath}/users') + @Route.get(f"{BasePath}/users") @Route.authorize(role=AuthRoleEnum.admin) async def get_all_users(self) -> Response: result = await self._auth_service.get_all_auth_users_async() return jsonify(result.select(lambda x: x.to_dict()).to_list()) - @Route.post(f'{BasePath}/users/get/filtered') + @Route.post(f"{BasePath}/users/get/filtered") @Route.authorize(role=AuthRoleEnum.admin) async def get_filtered_users(self) -> Response: - dto: AuthUserSelectCriteria = JSONProcessor.process(AuthUserSelectCriteria, request.get_json(force=True, silent=True)) + dto: AuthUserSelectCriteria = JSONProcessor.process( + AuthUserSelectCriteria, request.get_json(force=True, silent=True) + ) result = await self._auth_service.get_filtered_auth_users_async(dto) result.result = result.result.select(lambda x: x.to_dict()).to_list() return jsonify(result.to_dict()) - @Route.get(f'{BasePath}/users/get/') + @Route.get(f"{BasePath}/users/get/") @Route.authorize async def get_user_from_email(self, email: str) -> Response: result = await self._auth_service.get_auth_user_by_email_async(email) return jsonify(result.to_dict()) - @Route.get(f'{BasePath}/users/find/') + @Route.get(f"{BasePath}/users/find/") @Route.authorize async def find_user_from_email(self, email: str) -> Response: result = await self._auth_service.find_auth_user_by_email_async(email) return jsonify(result.to_dict()) - @Route.post(f'{BasePath}/register') + @Route.post(f"{BasePath}/register") async def register(self): dto: AuthUserDTO = JSONProcessor.process(AuthUserDTO, request.get_json(force=True, silent=True)) await self._auth_service.add_auth_user_async(dto) - return '', 200 + return "", 200 - @Route.post(f'{BasePath}/register-by-id/') + @Route.post(f"{BasePath}/register-by-id/") async def register_id(self, id: str): result = await self._auth_service.confirm_email_async(id) return jsonify(result) - @Route.post(f'{BasePath}/login') + @Route.post(f"{BasePath}/login") async def login(self) -> Response: dto: AuthUserDTO = JSONProcessor.process(AuthUserDTO, request.get_json(force=True, silent=True)) result = await self._auth_service.login_async(dto) return jsonify(result.to_dict()) - @Route.get(f'{BasePath}/verify-login') + @Route.get(f"{BasePath}/verify-login") async def verify_login(self): token = None result = False - if 'Authorization' in request.headers: - bearer = request.headers.get('Authorization') + if "Authorization" in request.headers: + bearer = request.headers.get("Authorization") token = bearer.split()[1] if token is not None: @@ -98,58 +100,58 @@ class AuthController: return jsonify(result) - @Route.post(f'{BasePath}/forgot-password/') + @Route.post(f"{BasePath}/forgot-password/") async def forgot_password(self, email: str): await self._auth_service.forgot_password_async(email) - return '', 200 + return "", 200 - @Route.post(f'{BasePath}/confirm-forgot-password/') + @Route.post(f"{BasePath}/confirm-forgot-password/") async def confirm_forgot_password(self, id: str): result = await self._auth_service.confirm_forgot_password_async(id) return jsonify(result.to_dict()) - @Route.post(f'{BasePath}/reset-password') + @Route.post(f"{BasePath}/reset-password") async def reset_password(self): dto: ResetPasswordDTO = JSONProcessor.process(ResetPasswordDTO, request.get_json(force=True, silent=True)) await self._auth_service.reset_password_async(dto) - return '', 200 + return "", 200 - @Route.post(f'{BasePath}/update-user') + @Route.post(f"{BasePath}/update-user") @Route.authorize async def update_user(self): dto: UpdateAuthUserDTO = JSONProcessor.process(UpdateAuthUserDTO, request.get_json(force=True, silent=True)) await self._auth_service.update_user_async(dto) - return '', 200 + return "", 200 - @Route.post(f'{BasePath}/update-user-as-admin') + @Route.post(f"{BasePath}/update-user-as-admin") @Route.authorize(role=AuthRoleEnum.admin) async def update_user_as_admin(self): dto: UpdateAuthUserDTO = JSONProcessor.process(UpdateAuthUserDTO, request.get_json(force=True, silent=True)) await self._auth_service.update_user_as_admin_async(dto) - return '', 200 + return "", 200 - @Route.post(f'{BasePath}/refresh') + @Route.post(f"{BasePath}/refresh") @Route.authorize async def refresh(self) -> Response: dto: TokenDTO = JSONProcessor.process(TokenDTO, request.get_json(force=True, silent=True)) result = await self._auth_service.refresh_async(dto) return jsonify(result.to_dict()) - @Route.post(f'{BasePath}/revoke') + @Route.post(f"{BasePath}/revoke") async def revoke(self): dto: TokenDTO = JSONProcessor.process(TokenDTO, request.get_json(force=True, silent=True)) await self._auth_service.revoke_async(dto) - return '', 200 + return "", 200 - @Route.post(f'{BasePath}/delete-user') + @Route.post(f"{BasePath}/delete-user") @Route.authorize(role=AuthRoleEnum.admin) async def delete_user(self): dto: AuthUserDTO = JSONProcessor.process(AuthUserDTO, request.get_json(force=True, silent=True)) await self._auth_service.delete_auth_user_async(dto) - return '', 200 + return "", 200 - @Route.post(f'{BasePath}/delete-user-by-mail/') + @Route.post(f"{BasePath}/delete-user-by-mail/") @Route.authorize(role=AuthRoleEnum.admin) async def delete_user_by_mail(self, email: str): await self._auth_service.delete_auth_user_by_email_async(email) - return '', 200 + return "", 200 diff --git a/kdb-bot/src/bot_api/controller/auth_discord_controller.py b/kdb-bot/src/bot_api/controller/auth_discord_controller.py index 900552b8..322e186c 100644 --- a/kdb-bot/src/bot_api/controller/auth_discord_controller.py +++ b/kdb-bot/src/bot_api/controller/auth_discord_controller.py @@ -13,7 +13,9 @@ from requests_oauthlib import OAuth2Session from bot_api.abc.auth_service_abc import AuthServiceABC from bot_api.api import Api -from bot_api.configuration.discord_authentication_settings import DiscordAuthenticationSettings +from bot_api.configuration.discord_authentication_settings import ( + DiscordAuthenticationSettings, +) from bot_api.json_processor import JSONProcessor from bot_api.logging.api_logger import ApiLogger from bot_api.model.auth_user_dto import AuthUserDTO @@ -22,24 +24,24 @@ from bot_api.route.route import Route from bot_data.model.auth_role_enum import AuthRoleEnum # Disable SSL requirement -os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1' +os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1" class AuthDiscordController: - BasePath = '/api/auth/discord' + BasePath = "/api/auth/discord" def __init__( - self, - auth_settings: DiscordAuthenticationSettings, - config: ConfigurationABC, - env: ApplicationEnvironmentABC, - logger: ApiLogger, - bot: DiscordBotServiceABC, - t: TranslatePipe, - api: Api, - mail_settings: EMailClientSettings, - mailer: EMailClientABC, - auth_service: AuthServiceABC + self, + auth_settings: DiscordAuthenticationSettings, + config: ConfigurationABC, + env: ApplicationEnvironmentABC, + logger: ApiLogger, + bot: DiscordBotServiceABC, + t: TranslatePipe, + api: Api, + mail_settings: EMailClientSettings, + mailer: EMailClientABC, + auth_service: AuthServiceABC, ): self._auth_settings = auth_settings self._config = config @@ -53,46 +55,58 @@ class AuthDiscordController: self._auth_service = auth_service def _get_user_from_discord_response(self) -> dict: - discord = OAuth2Session(self._bot.user.id, redirect_uri=self._auth_settings.redirect_url, state=request.args.get('state'), scope=self._auth_settings.scope) + discord = OAuth2Session( + self._bot.user.id, + redirect_uri=self._auth_settings.redirect_url, + state=request.args.get("state"), + scope=self._auth_settings.scope, + ) token = discord.fetch_token( self._auth_settings.token_url, client_secret=CredentialManager.decrypt(self._auth_settings.client_secret), authorization_response=request.url, ) discord = OAuth2Session(self._bot.user.id, token=token) - return discord.get('https://discordapp.com/api' + '/users/@me').json() + return discord.get("https://discordapp.com/api" + "/users/@me").json() - @Route.get(f'{BasePath}/get-url') + @Route.get(f"{BasePath}/get-url") async def get_url(self): - oauth = OAuth2Session(self._bot.user.id, redirect_uri=self._auth_settings.redirect_url, scope=self._auth_settings.scope) + oauth = OAuth2Session( + self._bot.user.id, + redirect_uri=self._auth_settings.redirect_url, + scope=self._auth_settings.scope, + ) login_url, state = oauth.authorization_url(self._auth_settings.auth_url) - return jsonify({'loginUrl': login_url}) + return jsonify({"loginUrl": login_url}) - @Route.get(f'{BasePath}/create-user') + @Route.get(f"{BasePath}/create-user") async def discord_create_user(self) -> Response: response = self._get_user_from_discord_response() - result = await self._auth_service.add_auth_user_by_discord_async(AuthUserDTO( - 0, - response['username'], - response['discriminator'], - response['email'], - str(uuid.uuid4()), - None, - AuthRoleEnum.normal - ), response['id']) + result = await self._auth_service.add_auth_user_by_discord_async( + AuthUserDTO( + 0, + response["username"], + response["discriminator"], + response["email"], + str(uuid.uuid4()), + None, + AuthRoleEnum.normal, + ), + response["id"], + ) return jsonify(result.to_dict()) - @Route.get(f'{BasePath}/login') + @Route.get(f"{BasePath}/login") async def discord_login(self) -> Response: response = self._get_user_from_discord_response() dto = AuthUserDTO( 0, - response['username'], - response['discriminator'], - response['email'], + response["username"], + response["discriminator"], + response["email"], str(uuid.uuid4()), None, - AuthRoleEnum.normal + AuthRoleEnum.normal, ) result = await self._auth_service.login_discord_async(dto) diff --git a/kdb-bot/src/bot_api/controller/discord/__init__.py b/kdb-bot/src/bot_api/controller/discord/__init__.py index 48cb2fcc..8d647bc4 100644 --- a/kdb-bot/src/bot_api/controller/discord/__init__.py +++ b/kdb-bot/src/bot_api/controller/discord/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'bot_api.controller.discord' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "bot_api.controller.discord" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/bot_api/controller/discord/server_controller.py b/kdb-bot/src/bot_api/controller/discord/server_controller.py index 2a6f7c1d..a9f0efe1 100644 --- a/kdb-bot/src/bot_api/controller/discord/server_controller.py +++ b/kdb-bot/src/bot_api/controller/discord/server_controller.py @@ -14,18 +14,18 @@ from bot_data.model.auth_role_enum import AuthRoleEnum class ServerController: - BasePath = f'/api/discord/server' + BasePath = f"/api/discord/server" def __init__( - self, - config: ConfigurationABC, - env: ApplicationEnvironmentABC, - logger: ApiLogger, - t: TranslatePipe, - api: Api, - mail_settings: EMailClientSettings, - mailer: EMailClientABC, - discord_service: DiscordService + self, + config: ConfigurationABC, + env: ApplicationEnvironmentABC, + logger: ApiLogger, + t: TranslatePipe, + api: Api, + mail_settings: EMailClientSettings, + mailer: EMailClientABC, + discord_service: DiscordService, ): self._config = config self._env = env @@ -36,29 +36,31 @@ class ServerController: self._mailer = mailer self._discord_service = discord_service - @Route.get(f'{BasePath}/get/servers') + @Route.get(f"{BasePath}/get/servers") @Route.authorize(role=AuthRoleEnum.admin) async def get_all_servers(self) -> Response: result = await self._discord_service.get_all_servers() result = result.select(lambda x: x.to_dict()).to_list() return jsonify(result) - @Route.get(f'{BasePath}/get/servers-by-user') + @Route.get(f"{BasePath}/get/servers-by-user") @Route.authorize async def get_all_servers_by_user(self) -> Response: result = await self._discord_service.get_all_servers_by_user() result = result.select(lambda x: x.to_dict()).to_list() return jsonify(result) - @Route.post(f'{BasePath}/get/filtered') + @Route.post(f"{BasePath}/get/filtered") @Route.authorize async def get_filtered_servers(self) -> Response: - dto: ServerSelectCriteria = JSONProcessor.process(ServerSelectCriteria, request.get_json(force=True, silent=True)) + dto: ServerSelectCriteria = JSONProcessor.process( + ServerSelectCriteria, request.get_json(force=True, silent=True) + ) result = await self._discord_service.get_filtered_servers_async(dto) result.result = result.result.select(lambda x: x.to_dict()).to_list() return jsonify(result.to_dict()) - @Route.get(f'{BasePath}/get/') + @Route.get(f"{BasePath}/get/") @Route.authorize async def get_server_by_id(self, id: int) -> Response: result = await self._discord_service.get_server_by_id_async(id).to_list() diff --git a/kdb-bot/src/bot_api/controller/gui_controller.py b/kdb-bot/src/bot_api/controller/gui_controller.py index d956e900..c047b0e3 100644 --- a/kdb-bot/src/bot_api/controller/gui_controller.py +++ b/kdb-bot/src/bot_api/controller/gui_controller.py @@ -15,18 +15,18 @@ from bot_api.route.route import Route class GuiController: - BasePath = f'/api/gui' + BasePath = f"/api/gui" def __init__( - self, - config: ConfigurationABC, - env: ApplicationEnvironmentABC, - logger: ApiLogger, - t: TranslatePipe, - api: Api, - mail_settings: EMailClientSettings, - mailer: EMailClientABC, - auth_settings: AuthenticationSettings + self, + config: ConfigurationABC, + env: ApplicationEnvironmentABC, + logger: ApiLogger, + t: TranslatePipe, + api: Api, + mail_settings: EMailClientSettings, + mailer: EMailClientABC, + auth_settings: AuthenticationSettings, ): self._config = config self._env = env @@ -37,42 +37,48 @@ class GuiController: self._mailer = mailer self._auth_settings = auth_settings - @Route.get(f'{BasePath}/api-version') + @Route.get(f"{BasePath}/api-version") async def api_version(self): import bot_api + version = bot_api.version_info return VersionDTO(version.major, version.minor, version.micro).to_dict() - @Route.get(f'{BasePath}/settings') + @Route.get(f"{BasePath}/settings") @Route.authorize async def settings(self): import bot_api + version = bot_api.version_info - return jsonify(SettingsDTO( - '', - VersionDTO(version.major, version.minor, version.micro), - os.path.abspath(os.path.join(self._env.working_directory, 'config')), - '/', - '/', - self._auth_settings.token_expire_time, - self._auth_settings.refresh_token_expire_time, - self._mail_settings.user_name, - self._mail_settings.port, - self._mail_settings.host, - self._mail_settings.user_name, - self._mail_settings.user_name, - ).to_dict()) + return jsonify( + SettingsDTO( + "", + VersionDTO(version.major, version.minor, version.micro), + os.path.abspath(os.path.join(self._env.working_directory, "config")), + "/", + "/", + self._auth_settings.token_expire_time, + self._auth_settings.refresh_token_expire_time, + self._mail_settings.user_name, + self._mail_settings.port, + self._mail_settings.host, + self._mail_settings.user_name, + self._mail_settings.user_name, + ).to_dict() + ) - @Route.post(f'{BasePath}/send-test-mail/') + @Route.post(f"{BasePath}/send-test-mail/") @Route.authorize async def send_test_mail(self, email: str): mail = EMail() - mail.add_header('Mime-Version: 1.0') - mail.add_header('Content-Type: text/plain; charset=utf-8') - mail.add_header('Content-Transfer-Encoding: quoted-printable') + mail.add_header("Mime-Version: 1.0") + mail.add_header("Content-Type: text/plain; charset=utf-8") + mail.add_header("Content-Transfer-Encoding: quoted-printable") mail.add_receiver(email) - mail.subject = self._t.transform('api.api.test_mail.subject') - mail.body = self._t.transform('api.api.test_mail.message').format(self._env.host_name, self._env.environment_name) + mail.subject = self._t.transform("api.api.test_mail.subject") + mail.body = self._t.transform("api.api.test_mail.message").format( + self._env.host_name, self._env.environment_name + ) self._mailer.send_mail(mail) - return '', 200 + return "", 200 diff --git a/kdb-bot/src/bot_api/event/__init__.py b/kdb-bot/src/bot_api/event/__init__.py index 0627d7cf..32906644 100644 --- a/kdb-bot/src/bot_api/event/__init__.py +++ b/kdb-bot/src/bot_api/event/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'bot_api.event' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "bot_api.event" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/bot_api/event/bot_api_on_ready_event.py b/kdb-bot/src/bot_api/event/bot_api_on_ready_event.py index ca63a03c..b144f0b4 100644 --- a/kdb-bot/src/bot_api/event/bot_api_on_ready_event.py +++ b/kdb-bot/src/bot_api/event/bot_api_on_ready_event.py @@ -4,7 +4,6 @@ from bot_api.api_thread import ApiThread class BotApiOnReadyEvent(OnReadyABC): - def __init__(self, api: ApiThread): OnReadyABC.__init__(self) self._api = api diff --git a/kdb-bot/src/bot_api/exception/__init__.py b/kdb-bot/src/bot_api/exception/__init__.py index 4db4fc25..55a69991 100644 --- a/kdb-bot/src/bot_api/exception/__init__.py +++ b/kdb-bot/src/bot_api/exception/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'bot_api.exception' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "bot_api.exception" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/bot_api/exception/service_exception.py b/kdb-bot/src/bot_api/exception/service_exception.py index 6451ae50..0b0ed95d 100644 --- a/kdb-bot/src/bot_api/exception/service_exception.py +++ b/kdb-bot/src/bot_api/exception/service_exception.py @@ -2,7 +2,6 @@ from bot_api.exception.service_error_code_enum import ServiceErrorCode class ServiceException(Exception): - def __init__(self, error_code: ServiceErrorCode, message: str, *args): Exception.__init__(self, *args) @@ -10,4 +9,4 @@ class ServiceException(Exception): self.message = message def get_detailed_message(self) -> str: - return f'ServiceException - ErrorCode: {self.error_code} - ErrorMessage: {self.message}' + return f"ServiceException - ErrorCode: {self.error_code} - ErrorMessage: {self.message}" diff --git a/kdb-bot/src/bot_api/filter/__init__.py b/kdb-bot/src/bot_api/filter/__init__.py index 0b898bd2..7ea12cf3 100644 --- a/kdb-bot/src/bot_api/filter/__init__.py +++ b/kdb-bot/src/bot_api/filter/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'bot_api.filter' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "bot_api.filter" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/bot_api/filter/auth_user_select_criteria.py b/kdb-bot/src/bot_api/filter/auth_user_select_criteria.py index 8ac7784e..eaa2ee7f 100644 --- a/kdb-bot/src/bot_api/filter/auth_user_select_criteria.py +++ b/kdb-bot/src/bot_api/filter/auth_user_select_criteria.py @@ -2,18 +2,16 @@ from bot_api.abc.select_criteria_abc import SelectCriteriaABC class AuthUserSelectCriteria(SelectCriteriaABC): - def __init__( - self, - page_index: int, - page_size: int, - sort_direction: str, - sort_column: str, - - first_name: str, - last_name: str, - email: str, - auth_role: int + self, + page_index: int, + page_size: int, + sort_direction: str, + sort_column: str, + first_name: str, + last_name: str, + email: str, + auth_role: int, ): SelectCriteriaABC.__init__(self, page_index, page_size, sort_direction, sort_column) diff --git a/kdb-bot/src/bot_api/filter/discord/__init__.py b/kdb-bot/src/bot_api/filter/discord/__init__.py index 1f6d5f55..95eddd93 100644 --- a/kdb-bot/src/bot_api/filter/discord/__init__.py +++ b/kdb-bot/src/bot_api/filter/discord/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'bot_api.filter.discord' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "bot_api.filter.discord" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/bot_api/filter/discord/server_select_criteria.py b/kdb-bot/src/bot_api/filter/discord/server_select_criteria.py index f1454a8c..5f194809 100644 --- a/kdb-bot/src/bot_api/filter/discord/server_select_criteria.py +++ b/kdb-bot/src/bot_api/filter/discord/server_select_criteria.py @@ -2,15 +2,13 @@ from bot_api.abc.select_criteria_abc import SelectCriteriaABC class ServerSelectCriteria(SelectCriteriaABC): - def __init__( - self, - page_index: int, - page_size: int, - sort_direction: str, - sort_column: str, - - name: str, + self, + page_index: int, + page_size: int, + sort_direction: str, + sort_column: str, + name: str, ): SelectCriteriaABC.__init__(self, page_index, page_size, sort_direction, sort_column) diff --git a/kdb-bot/src/bot_api/json_processor.py b/kdb-bot/src/bot_api/json_processor.py index ede53d2c..6bf54267 100644 --- a/kdb-bot/src/bot_api/json_processor.py +++ b/kdb-bot/src/bot_api/json_processor.py @@ -5,7 +5,6 @@ from cpl_core.utils import String class JSONProcessor: - @staticmethod def process(_t: type, values: dict) -> object: args = [] @@ -13,14 +12,14 @@ class JSONProcessor: sig = signature(_t.__init__) for param in sig.parameters.items(): parameter = param[1] - if parameter.name == 'self' or parameter.annotation == Parameter.empty: + if parameter.name == "self" or parameter.annotation == Parameter.empty: continue name = String.convert_to_camel_case(parameter.name) - name = name.replace('Dto', 'DTO') + name = name.replace("Dto", "DTO") name_first_lower = String.first_to_lower(name) if name in values or name_first_lower in values: - value = '' + value = "" if name in values: value = values[name] else: diff --git a/kdb-bot/src/bot_api/logging/__init__.py b/kdb-bot/src/bot_api/logging/__init__.py index 7575e633..986732c8 100644 --- a/kdb-bot/src/bot_api/logging/__init__.py +++ b/kdb-bot/src/bot_api/logging/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'bot_api.logging' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "bot_api.logging" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/bot_api/logging/api_logger.py b/kdb-bot/src/bot_api/logging/api_logger.py index 1e4f00e8..af14f72d 100644 --- a/kdb-bot/src/bot_api/logging/api_logger.py +++ b/kdb-bot/src/bot_api/logging/api_logger.py @@ -6,6 +6,10 @@ from bot_core.abc.custom_file_logger_abc import CustomFileLoggerABC class ApiLogger(CustomFileLoggerABC): - - def __init__(self, config: ConfigurationABC, time_format: TimeFormatSettings, env: ApplicationEnvironmentABC): - CustomFileLoggerABC.__init__(self, 'Api', config, time_format, env) + def __init__( + self, + config: ConfigurationABC, + time_format: TimeFormatSettings, + env: ApplicationEnvironmentABC, + ): + CustomFileLoggerABC.__init__(self, "Api", config, time_format, env) diff --git a/kdb-bot/src/bot_api/model/__init__.py b/kdb-bot/src/bot_api/model/__init__.py index 47a3f826..9657727c 100644 --- a/kdb-bot/src/bot_api/model/__init__.py +++ b/kdb-bot/src/bot_api/model/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'bot_api.model' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "bot_api.model" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/bot_api/model/auth_user_dto.py b/kdb-bot/src/bot_api/model/auth_user_dto.py index 347df8ad..8d0d98b3 100644 --- a/kdb-bot/src/bot_api/model/auth_user_dto.py +++ b/kdb-bot/src/bot_api/model/auth_user_dto.py @@ -5,16 +5,15 @@ from bot_data.model.auth_role_enum import AuthRoleEnum class AuthUserDTO(DtoABC): - def __init__( - self, - id: int = None, - first_name: str = None, - last_name: str = None, - email: str = None, - password: str = None, - confirmation_id: Optional[str] = None, - auth_role: AuthRoleEnum = None, + self, + id: int = None, + first_name: str = None, + last_name: str = None, + email: str = None, + password: str = None, + confirmation_id: Optional[str] = None, + auth_role: AuthRoleEnum = None, ): DtoABC.__init__(self) @@ -79,21 +78,21 @@ class AuthUserDTO(DtoABC): self._auth_role = value def from_dict(self, values: dict): - self._id = values['id'] - self._first_name = values['firstName'] - self._last_name = values['lastName'] - self._email = values['email'] - self._password = values['password'] - self._is_confirmed = values['isConfirmed'] - self._auth_role = AuthRoleEnum(values['authRole']) + self._id = values["id"] + self._first_name = values["firstName"] + self._last_name = values["lastName"] + self._email = values["email"] + self._password = values["password"] + self._is_confirmed = values["isConfirmed"] + self._auth_role = AuthRoleEnum(values["authRole"]) def to_dict(self) -> dict: return { - 'id': self._id, - 'firstName': self._first_name, - 'lastName': self._last_name, - 'email': self._email, - 'password': self._password, - 'isConfirmed': self._is_confirmed, - 'authRole': self._auth_role.value, + "id": self._id, + "firstName": self._first_name, + "lastName": self._last_name, + "email": self._email, + "password": self._password, + "isConfirmed": self._is_confirmed, + "authRole": self._auth_role.value, } diff --git a/kdb-bot/src/bot_api/model/auth_user_filtered_result_dto.py b/kdb-bot/src/bot_api/model/auth_user_filtered_result_dto.py index a3125d25..7c70ce8b 100644 --- a/kdb-bot/src/bot_api/model/auth_user_filtered_result_dto.py +++ b/kdb-bot/src/bot_api/model/auth_user_filtered_result_dto.py @@ -5,17 +5,13 @@ from bot_data.filtered_result import FilteredResult class AuthUserFilteredResultDTO(DtoABC, FilteredResult): - def __init__(self, result: List = None, total_count: int = 0): DtoABC.__init__(self) FilteredResult.__init__(self, result, total_count) def from_dict(self, values: dict): - self._result = values['users'] - self._total_count = values['totalCount'] + self._result = values["users"] + self._total_count = values["totalCount"] def to_dict(self) -> dict: - return { - 'users': self.result, - 'totalCount': self.total_count - } + return {"users": self.result, "totalCount": self.total_count} diff --git a/kdb-bot/src/bot_api/model/discord/__init__.py b/kdb-bot/src/bot_api/model/discord/__init__.py index a7bbccf9..90dd66c0 100644 --- a/kdb-bot/src/bot_api/model/discord/__init__.py +++ b/kdb-bot/src/bot_api/model/discord/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'bot_api.model.discord' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "bot_api.model.discord" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/bot_api/model/discord/server_dto.py b/kdb-bot/src/bot_api/model/discord/server_dto.py index a4a5a2da..2c5b7ad5 100644 --- a/kdb-bot/src/bot_api/model/discord/server_dto.py +++ b/kdb-bot/src/bot_api/model/discord/server_dto.py @@ -4,15 +4,13 @@ from bot_api.abc.dto_abc import DtoABC class ServerDTO(DtoABC): - def __init__( - self, - server_id: int, - discord_id: int, - name: str, - member_count: int, - icon_url: Optional[str] - + self, + server_id: int, + discord_id: int, + name: str, + member_count: int, + icon_url: Optional[str], ): DtoABC.__init__(self) @@ -21,19 +19,19 @@ class ServerDTO(DtoABC): self._name = name self._member_count = member_count self._icon_url = icon_url - + @property def server_id(self) -> int: return self._server_id - + @property def discord_id(self) -> int: return self._discord_id - + @property def name(self) -> str: return self._name - + @property def member_count(self) -> int: return self._member_count @@ -43,16 +41,16 @@ class ServerDTO(DtoABC): return self._icon_url def from_dict(self, values: dict): - self._server_id = int(values['serverId']) - self._discord_id = int(values['discordId']) - self._name = values['name'] - self._icon_url = values['iconURL'] + self._server_id = int(values["serverId"]) + self._discord_id = int(values["discordId"]) + self._name = values["name"] + self._icon_url = values["iconURL"] def to_dict(self) -> dict: return { - 'serverId': self._server_id, - 'discordId': self._discord_id, - 'name': self._name, - 'memberCount': self._member_count, - 'iconURL': self._icon_url, + "serverId": self._server_id, + "discordId": self._discord_id, + "name": self._name, + "memberCount": self._member_count, + "iconURL": self._icon_url, } diff --git a/kdb-bot/src/bot_api/model/discord/server_filtered_result_dto.py b/kdb-bot/src/bot_api/model/discord/server_filtered_result_dto.py index eceb642c..e8af2d59 100644 --- a/kdb-bot/src/bot_api/model/discord/server_filtered_result_dto.py +++ b/kdb-bot/src/bot_api/model/discord/server_filtered_result_dto.py @@ -5,17 +5,13 @@ from bot_data.filtered_result import FilteredResult class ServerFilteredResultDTO(DtoABC, FilteredResult): - def __init__(self, result: List = None, total_count: int = 0): DtoABC.__init__(self) FilteredResult.__init__(self, result, total_count) def from_dict(self, values: dict): - self._result = values['servers'] - self._total_count = values['totalCount'] + self._result = values["servers"] + self._total_count = values["totalCount"] def to_dict(self) -> dict: - return { - 'servers': self.result, - 'totalCount': self.total_count - } + return {"servers": self.result, "totalCount": self.total_count} diff --git a/kdb-bot/src/bot_api/model/email_string_dto.py b/kdb-bot/src/bot_api/model/email_string_dto.py index 5ad6eecb..421ed7ea 100644 --- a/kdb-bot/src/bot_api/model/email_string_dto.py +++ b/kdb-bot/src/bot_api/model/email_string_dto.py @@ -6,16 +6,13 @@ from bot_api.abc.dto_abc import DtoABC class EMailStringDTO(DtoABC): - def __init__(self, email: str): DtoABC.__init__(self) self._email = email def from_dict(self, values: dict): - self._email = values['email'] + self._email = values["email"] def to_dict(self) -> dict: - return { - 'email': self._email - } + return {"email": self._email} diff --git a/kdb-bot/src/bot_api/model/error_dto.py b/kdb-bot/src/bot_api/model/error_dto.py index 39c7d6a1..867e581c 100644 --- a/kdb-bot/src/bot_api/model/error_dto.py +++ b/kdb-bot/src/bot_api/model/error_dto.py @@ -8,7 +8,6 @@ from bot_api.exception.service_error_code_enum import ServiceErrorCode class ErrorDTO(DtoABC): - def __init__(self, error_code: Optional[ServiceErrorCode], message: str): DtoABC.__init__(self) @@ -24,11 +23,8 @@ class ErrorDTO(DtoABC): return self._message def from_dict(self, values: dict): - self._error_code = values['ErrorCode'] - self._message = values['Message'] + self._error_code = values["ErrorCode"] + self._message = values["Message"] def to_dict(self) -> dict: - return { - 'errorCode': int(self._error_code.value), - 'message': self._message - } + return {"errorCode": int(self._error_code.value), "message": self._message} diff --git a/kdb-bot/src/bot_api/model/o_auth_dto.py b/kdb-bot/src/bot_api/model/o_auth_dto.py index 72eb7bd1..54d56f63 100644 --- a/kdb-bot/src/bot_api/model/o_auth_dto.py +++ b/kdb-bot/src/bot_api/model/o_auth_dto.py @@ -6,11 +6,10 @@ from bot_data.model.auth_role_enum import AuthRoleEnum class OAuthDTO(DtoABC): - def __init__( - self, - user: AuthUserDTO, - o_auth_id: Optional[str], + self, + user: AuthUserDTO, + o_auth_id: Optional[str], ): DtoABC.__init__(self) @@ -34,11 +33,8 @@ class OAuthDTO(DtoABC): self._oauth_id = value def from_dict(self, values: dict): - self._user = AuthUserDTO().from_dict(values['user']) - self._oauth_id = values['oAuthId'] + self._user = AuthUserDTO().from_dict(values["user"]) + self._oauth_id = values["oAuthId"] def to_dict(self) -> dict: - return { - 'user': self._user.to_dict(), - 'oAuthId': self._oauth_id - } + return {"user": self._user.to_dict(), "oAuthId": self._oauth_id} diff --git a/kdb-bot/src/bot_api/model/reset_password_dto.py b/kdb-bot/src/bot_api/model/reset_password_dto.py index 64de816d..f2c096f7 100644 --- a/kdb-bot/src/bot_api/model/reset_password_dto.py +++ b/kdb-bot/src/bot_api/model/reset_password_dto.py @@ -6,7 +6,6 @@ from bot_api.abc.dto_abc import DtoABC class ResetPasswordDTO(DtoABC): - def __init__(self, id: str, password: str): DtoABC.__init__(self) @@ -22,11 +21,8 @@ class ResetPasswordDTO(DtoABC): return self._password def from_dict(self, values: dict): - self._id = values['id'] - self._password = values['password'] + self._id = values["id"] + self._password = values["password"] def to_dict(self) -> dict: - return { - 'id': self._id, - 'password': self._password - } + return {"id": self._id, "password": self._password} diff --git a/kdb-bot/src/bot_api/model/settings_dto.py b/kdb-bot/src/bot_api/model/settings_dto.py index 09df375c..412b9a8f 100644 --- a/kdb-bot/src/bot_api/model/settings_dto.py +++ b/kdb-bot/src/bot_api/model/settings_dto.py @@ -3,21 +3,20 @@ from bot_api.model.version_dto import VersionDTO class SettingsDTO(DtoABC): - def __init__( - self, - web_version: str, - api_version: VersionDTO, - config_path: str, - web_base_url: str, - api_base_url: str, - token_expire_time: int, - refresh_token_expire_time: int, - mail_user: str, - mail_port: int, - mail_host: str, - mail_transceiver: str, - mail_transceiver_address: str, + self, + web_version: str, + api_version: VersionDTO, + config_path: str, + web_base_url: str, + api_base_url: str, + token_expire_time: int, + refresh_token_expire_time: int, + mail_user: str, + mail_port: int, + mail_host: str, + mail_transceiver: str, + mail_transceiver_address: str, ): DtoABC.__init__(self) @@ -37,31 +36,31 @@ class SettingsDTO(DtoABC): self._mail_transceiver_address = mail_transceiver_address def from_dict(self, values: dict): - self._web_version = values['webVersion'] - self._api_version.from_dict(values['apiVersion']) - self._config_path = values['configPath'] - self._web_base_url = values['webBaseURL'] - self._api_base_url = values['apiBaseURL'] - self._token_expire_time = values['tokenExpireTime'] - self._refresh_token_expire_time = values['refreshTokenExpireTime'] - self._mail_user = values['mailUser'] - self._mail_port = values['mailPort'] - self._mail_host = values['mailHost'] - self._mail_transceiver = values['mailTransceiver'] - self._mail_transceiver_address = values['mailTransceiverAddress'] + self._web_version = values["webVersion"] + self._api_version.from_dict(values["apiVersion"]) + self._config_path = values["configPath"] + self._web_base_url = values["webBaseURL"] + self._api_base_url = values["apiBaseURL"] + self._token_expire_time = values["tokenExpireTime"] + self._refresh_token_expire_time = values["refreshTokenExpireTime"] + self._mail_user = values["mailUser"] + self._mail_port = values["mailPort"] + self._mail_host = values["mailHost"] + self._mail_transceiver = values["mailTransceiver"] + self._mail_transceiver_address = values["mailTransceiverAddress"] def to_dict(self) -> dict: return { - 'webVersion': self._web_version, - 'apiVersion': self._api_version.str, - 'configPath': self._config_path, - 'webBaseURL': self._web_base_url, - 'apiBaseURL': self._api_base_url, - 'tokenExpireTime': self._token_expire_time, - 'refreshTokenExpireTime': self._refresh_token_expire_time, - 'mailUser': self._mail_user, - 'mailPort': self._mail_port, - 'mailHost': self._mail_host, - 'mailTransceiver': self._mail_transceiver, - 'mailTransceiverAddress': self._mail_transceiver_address, + "webVersion": self._web_version, + "apiVersion": self._api_version.str, + "configPath": self._config_path, + "webBaseURL": self._web_base_url, + "apiBaseURL": self._api_base_url, + "tokenExpireTime": self._token_expire_time, + "refreshTokenExpireTime": self._refresh_token_expire_time, + "mailUser": self._mail_user, + "mailPort": self._mail_port, + "mailHost": self._mail_host, + "mailTransceiver": self._mail_transceiver, + "mailTransceiverAddress": self._mail_transceiver_address, } diff --git a/kdb-bot/src/bot_api/model/token_dto.py b/kdb-bot/src/bot_api/model/token_dto.py index d5fc3087..d4a73f2f 100644 --- a/kdb-bot/src/bot_api/model/token_dto.py +++ b/kdb-bot/src/bot_api/model/token_dto.py @@ -6,27 +6,23 @@ from bot_api.abc.dto_abc import DtoABC class TokenDTO(DtoABC): - def __init__(self, token: str, refresh_token: str): DtoABC.__init__(self) self._token = token self._refresh_token = refresh_token - + @property def token(self) -> str: return self._token - + @property def refresh_token(self) -> str: return self._refresh_token def from_dict(self, values: dict): - self._token = values['token'] - self._refresh_token = values['refreshToken'] + self._token = values["token"] + self._refresh_token = values["refreshToken"] def to_dict(self) -> dict: - return { - 'token': self._token, - 'refreshToken': self._refresh_token - } + return {"token": self._token, "refreshToken": self._refresh_token} diff --git a/kdb-bot/src/bot_api/model/update_auth_user_dto.py b/kdb-bot/src/bot_api/model/update_auth_user_dto.py index ac71e033..28e57768 100644 --- a/kdb-bot/src/bot_api/model/update_auth_user_dto.py +++ b/kdb-bot/src/bot_api/model/update_auth_user_dto.py @@ -7,12 +7,11 @@ from bot_api.model.auth_user_dto import AuthUserDTO class UpdateAuthUserDTO(DtoABC): - def __init__( - self, - auth_user_dto: AuthUserDTO, - new_auth_user_dto: AuthUserDTO, - change_password: bool = False + self, + auth_user_dto: AuthUserDTO, + new_auth_user_dto: AuthUserDTO, + change_password: bool = False, ): DtoABC.__init__(self) @@ -33,13 +32,13 @@ class UpdateAuthUserDTO(DtoABC): return self._change_password def from_dict(self, values: dict): - self._auth_user = AuthUserDTO().from_dict(values['authUser']) - self._new_auth_user = AuthUserDTO().from_dict(values['newAuthUser']) - self._change_password = False if 'changePassword' not in values else bool(values['changePassword']) + self._auth_user = AuthUserDTO().from_dict(values["authUser"]) + self._new_auth_user = AuthUserDTO().from_dict(values["newAuthUser"]) + self._change_password = False if "changePassword" not in values else bool(values["changePassword"]) def to_dict(self) -> dict: return { - 'authUser': self._auth_user, - 'newAuthUser': self._new_auth_user, - 'changePassword': self._change_password + "authUser": self._auth_user, + "newAuthUser": self._new_auth_user, + "changePassword": self._change_password, } diff --git a/kdb-bot/src/bot_api/model/version_dto.py b/kdb-bot/src/bot_api/model/version_dto.py index c15413a0..b3de84d0 100644 --- a/kdb-bot/src/bot_api/model/version_dto.py +++ b/kdb-bot/src/bot_api/model/version_dto.py @@ -6,7 +6,6 @@ from bot_api.abc.dto_abc import DtoABC class VersionDTO(DtoABC): - def __init__(self, major: str = None, minor: str = None, micro: str = None): DtoABC.__init__(self) @@ -28,16 +27,16 @@ class VersionDTO(DtoABC): @property def str(self) -> str: - return f'{self._major}.{self._minor}.{self._micro}' + return f"{self._major}.{self._minor}.{self._micro}" def from_dict(self, values: dict): - self._major = values['major'] - self._minor = values['minor'] - self._micro = values['micro'] + self._major = values["major"] + self._minor = values["minor"] + self._micro = values["micro"] def to_dict(self) -> dict: return { - 'major': self._major, - 'minor': self._minor, - 'micro': self._micro, + "major": self._major, + "minor": self._minor, + "micro": self._micro, } diff --git a/kdb-bot/src/bot_api/route/__init__.py b/kdb-bot/src/bot_api/route/__init__.py index 7225cfad..3df22820 100644 --- a/kdb-bot/src/bot_api/route/__init__.py +++ b/kdb-bot/src/bot_api/route/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'bot_api.route' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "bot_api.route" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/bot_api/route/route.py b/kdb-bot/src/bot_api/route/route.py index 26bdad2b..63c01016 100644 --- a/kdb-bot/src/bot_api/route/route.py +++ b/kdb-bot/src/bot_api/route/route.py @@ -32,39 +32,39 @@ class Route: @wraps(f) async def decorator(*args, **kwargs): token = None - if 'Authorization' in request.headers: - bearer = request.headers.get('Authorization') + if "Authorization" in request.headers: + bearer = request.headers.get("Authorization") token = bearer.split()[1] if token is None: - ex = ServiceException(ServiceErrorCode.Unauthorized, f'Token not set') + ex = ServiceException(ServiceErrorCode.Unauthorized, f"Token not set") error = ErrorDTO(ex.error_code, ex.message) return jsonify(error.to_dict()), 401 if cls._auth_users is None or cls._auth is None: - ex = ServiceException(ServiceErrorCode.Unauthorized, f'Authorize is not initialized') + ex = ServiceException(ServiceErrorCode.Unauthorized, f"Authorize is not initialized") error = ErrorDTO(ex.error_code, ex.message) return jsonify(error.to_dict()), 401 if not cls._auth.verify_login(token): - ex = ServiceException(ServiceErrorCode.Unauthorized, f'Token expired') + ex = ServiceException(ServiceErrorCode.Unauthorized, f"Token expired") error = ErrorDTO(ex.error_code, ex.message) return jsonify(error.to_dict()), 401 token = cls._auth.decode_token(token) - if token is None or 'email' not in token: - ex = ServiceException(ServiceErrorCode.Unauthorized, f'Token invalid') + if token is None or "email" not in token: + ex = ServiceException(ServiceErrorCode.Unauthorized, f"Token invalid") error = ErrorDTO(ex.error_code, ex.message) return jsonify(error.to_dict()), 401 - user = cls._auth_users.get_auth_user_by_email(token['email']) + user = cls._auth_users.get_auth_user_by_email(token["email"]) if user is None: - ex = ServiceException(ServiceErrorCode.Unauthorized, f'Token invalid') + ex = ServiceException(ServiceErrorCode.Unauthorized, f"Token invalid") error = ErrorDTO(ex.error_code, ex.message) return jsonify(error.to_dict()), 401 if role is not None and user.auth_role.value < role.value: - ex = ServiceException(ServiceErrorCode.Unauthorized, f'Role {role} required') + ex = ServiceException(ServiceErrorCode.Unauthorized, f"Role {role} required") error = ErrorDTO(ex.error_code, ex.message) return jsonify(error.to_dict()), 403 @@ -84,20 +84,20 @@ class Route: @classmethod def get(cls, path=None, **kwargs): - return cls.route(path, methods=['GET'], **kwargs) + return cls.route(path, methods=["GET"], **kwargs) @classmethod def post(cls, path=None, **kwargs): - return cls.route(path, methods=['POST'], **kwargs) + return cls.route(path, methods=["POST"], **kwargs) @classmethod def head(cls, path=None, **kwargs): - return cls.route(path, methods=['HEAD'], **kwargs) + return cls.route(path, methods=["HEAD"], **kwargs) @classmethod def put(cls, path=None, **kwargs): - return cls.route(path, methods=['PUT'], **kwargs) + return cls.route(path, methods=["PUT"], **kwargs) @classmethod def delete(cls, path=None, **kwargs): - return cls.route(path, methods=['DELETE'], **kwargs) + return cls.route(path, methods=["DELETE"], **kwargs) diff --git a/kdb-bot/src/bot_api/service/__init__.py b/kdb-bot/src/bot_api/service/__init__.py index 1e2fd6a5..9c33b510 100644 --- a/kdb-bot/src/bot_api/service/__init__.py +++ b/kdb-bot/src/bot_api/service/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'bot_api.service' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "bot_api.service" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/bot_api/service/auth_service.py b/kdb-bot/src/bot_api/service/auth_service.py index 7903c8b4..1ba01206 100644 --- a/kdb-bot/src/bot_api/service/auth_service.py +++ b/kdb-bot/src/bot_api/service/auth_service.py @@ -38,26 +38,24 @@ from bot_data.model.auth_role_enum import AuthRoleEnum from bot_data.model.auth_user import AuthUser from bot_data.model.auth_user_users_relation import AuthUserUsersRelation -_email_regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b' +_email_regex = r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b" class AuthService(AuthServiceABC): - def __init__( - self, - env: ApplicationEnvironmentABC, - logger: ApiLogger, - bot: DiscordBotServiceABC, - db: DatabaseContextABC, - auth_users: AuthUserRepositoryABC, - users: UserRepositoryABC, - servers: ServerRepositoryABC, - # mailer: MailThread, - mailer: EMailClientABC, - t: TranslatePipe, - auth_settings: AuthenticationSettings, - frontend_settings: FrontendSettings, - + self, + env: ApplicationEnvironmentABC, + logger: ApiLogger, + bot: DiscordBotServiceABC, + db: DatabaseContextABC, + auth_users: AuthUserRepositoryABC, + users: UserRepositoryABC, + servers: ServerRepositoryABC, + # mailer: MailThread, + mailer: EMailClientABC, + t: TranslatePipe, + auth_settings: AuthenticationSettings, + frontend_settings: FrontendSettings, ): AuthServiceABC.__init__(self) @@ -75,7 +73,7 @@ class AuthService(AuthServiceABC): @staticmethod def _hash_sha256(password: str, salt: str) -> str: - return hashlib.sha256(f'{password}{salt}'.encode('utf-8')).hexdigest() + return hashlib.sha256(f"{password}{salt}".encode("utf-8")).hexdigest() @staticmethod def _is_email_valid(email: str) -> bool: @@ -87,14 +85,14 @@ class AuthService(AuthServiceABC): def generate_token(self, user: AuthUser) -> str: token = jwt.encode( payload={ - 'user_id': user.id, - 'email': user.email, - 'role': user.auth_role.value, - 'exp': datetime.now(tz=timezone.utc) + timedelta(days=self._auth_settings.token_expire_time), - 'iss': self._auth_settings.issuer, - 'aud': self._auth_settings.audience + "user_id": user.id, + "email": user.email, + "role": user.auth_role.value, + "exp": datetime.now(tz=timezone.utc) + timedelta(days=self._auth_settings.token_expire_time), + "iss": self._auth_settings.issuer, + "aud": self._auth_settings.audience, }, - key=CredentialManager.decrypt(self._auth_settings.secret_key) + key=CredentialManager.decrypt(self._auth_settings.secret_key), ) return token @@ -105,39 +103,43 @@ class AuthService(AuthServiceABC): key=CredentialManager.decrypt(self._auth_settings.secret_key), issuer=self._auth_settings.issuer, audience=self._auth_settings.audience, - algorithms=['HS256'] + algorithms=["HS256"], ) def get_decoded_token_from_request(self) -> dict: token = None - if 'Authorization' in request.headers: - bearer = request.headers.get('Authorization') + if "Authorization" in request.headers: + bearer = request.headers.get("Authorization") token = bearer.split()[1] if token is None: - raise ServiceException(ServiceErrorCode.Unauthorized, f'Token not set') + raise ServiceException(ServiceErrorCode.Unauthorized, f"Token not set") return jwt.decode( token, key=CredentialManager.decrypt(self._auth_settings.secret_key), issuer=self._auth_settings.issuer, audience=self._auth_settings.audience, - algorithms=['HS256'] + algorithms=["HS256"], ) def find_decoded_token_from_request(self) -> Optional[dict]: token = None - if 'Authorization' in request.headers: - bearer = request.headers.get('Authorization') + if "Authorization" in request.headers: + bearer = request.headers.get("Authorization") token = bearer.split()[1] - return jwt.decode( - token, - key=CredentialManager.decrypt(self._auth_settings.secret_key), - issuer=self._auth_settings.issuer, - audience=self._auth_settings.audience, - algorithms=['HS256'] - ) if token is not None else None + return ( + jwt.decode( + token, + key=CredentialManager.decrypt(self._auth_settings.secret_key), + issuer=self._auth_settings.issuer, + audience=self._auth_settings.audience, + algorithms=["HS256"], + ) + if token is not None + else None + ) def _create_and_save_refresh_token(self, user: AuthUser) -> str: token = str(uuid.uuid4()) @@ -149,58 +151,56 @@ class AuthService(AuthServiceABC): def _send_link_mail(self, email: str, subject: str, message: str): url = self._frontend_settings.url - if not url.endswith('/'): - url = f'{url}/' + if not url.endswith("/"): + url = f"{url}/" self._mailer.connect() mail = EMail() - mail.add_header('Mime-Version: 1.0') - mail.add_header('Content-Type: text/plain; charset=utf-8') - mail.add_header('Content-Transfer-Encoding: quoted-printable') + mail.add_header("Mime-Version: 1.0") + mail.add_header("Content-Type: text/plain; charset=utf-8") + mail.add_header("Content-Transfer-Encoding: quoted-printable") mail.add_receiver(str(email)) mail.subject = subject - mail.body = textwrap.dedent(f"""{message} + mail.body = textwrap.dedent( + f"""{message} {self._t.transform('api.mail.automatic_mail').format(self._environment.application_name, self._environment.environment_name, self._environment.host_name)} - """) + """ + ) thr = Thread(target=self._mailer.send_mail, args=[mail]) thr.start() def _send_confirmation_id_to_user(self, user: AuthUser): url = self._frontend_settings.url - if not url.endswith('/'): - url = f'{url}/' + if not url.endswith("/"): + url = f"{url}/" self._send_link_mail( user.email, - self._t.transform('api.auth.confirmation.subject').format(user.first_name, user.last_name), - self._t.transform('api.auth.confirmation.message').format(url, user.confirmation_id) + self._t.transform("api.auth.confirmation.subject").format(user.first_name, user.last_name), + self._t.transform("api.auth.confirmation.message").format(url, user.confirmation_id), ) def _send_forgot_password_id_to_user(self, user: AuthUser): url = self._frontend_settings.url - if not url.endswith('/'): - url = f'{url}/' + if not url.endswith("/"): + url = f"{url}/" self._send_link_mail( user.email, - self._t.transform('api.auth.forgot_password.subject').format(user.first_name, user.last_name), - self._t.transform('api.auth.forgot_password.message').format(url, user.forgot_password_id) + self._t.transform("api.auth.forgot_password.subject").format(user.first_name, user.last_name), + self._t.transform("api.auth.forgot_password.message").format(url, user.forgot_password_id), ) async def get_all_auth_users_async(self) -> List[AuthUserDTO]: - result = self._auth_users.get_all_auth_users() \ - .select(lambda x: AUT.to_dto(x)) + result = self._auth_users.get_all_auth_users().select(lambda x: AUT.to_dto(x)) return List(AuthUserDTO, result) async def get_filtered_auth_users_async(self, criteria: AuthUserSelectCriteria) -> AuthUserFilteredResultDTO: users = self._auth_users.get_filtered_auth_users(criteria) result = users.result.select(lambda x: AUT.to_dto(x)) - return AuthUserFilteredResultDTO( - List(AuthUserDTO, result), - users.total_count - ) + return AuthUserFilteredResultDTO(List(AuthUserDTO, result), users.total_count) async def get_auth_user_by_email_async(self, email: str, with_password: bool = False) -> AuthUserDTO: try: @@ -208,8 +208,8 @@ class AuthService(AuthServiceABC): user = self._auth_users.get_auth_user_by_email(email) return AUT.to_dto(user, password=user.password if with_password else None) except Exception as e: - self._logger.error(__name__, f'AuthUser not found', e) - raise ServiceException(ServiceErrorCode.InvalidData, f'User not found {email}') + self._logger.error(__name__, f"AuthUser not found", e) + raise ServiceException(ServiceErrorCode.InvalidData, f"User not found {email}") async def find_auth_user_by_email_async(self, email: str) -> Optional[AuthUser]: user = self._auth_users.find_auth_user_by_email(email) @@ -218,7 +218,7 @@ class AuthService(AuthServiceABC): async def add_auth_user_async(self, user_dto: AuthUserDTO): db_user = self._auth_users.find_auth_user_by_email(user_dto.email) if db_user is not None: - raise ServiceException(ServiceErrorCode.InvalidUser, 'User already exists') + raise ServiceException(ServiceErrorCode.InvalidUser, "User already exists") user = AUT.to_db(user_dto) if self._auth_users.get_all_auth_users().count() == 0: @@ -227,26 +227,26 @@ class AuthService(AuthServiceABC): user.password_salt = uuid.uuid4() user.password = self._hash_sha256(user_dto.password, user.password_salt) if not self._is_email_valid(user.email): - raise ServiceException(ServiceErrorCode.InvalidData, 'Invalid E-Mail address') + raise ServiceException(ServiceErrorCode.InvalidData, "Invalid E-Mail address") try: user.confirmation_id = uuid.uuid4() self._auth_users.add_auth_user(user) self._send_confirmation_id_to_user(user) self._db.save_changes() - self._logger.info(__name__, f'Added auth user with E-Mail: {user_dto.email}') + self._logger.info(__name__, f"Added auth user with E-Mail: {user_dto.email}") except Exception as e: - self._logger.error(__name__, f'Cannot add user with E-Mail {user_dto.email}', e) + self._logger.error(__name__, f"Cannot add user with E-Mail {user_dto.email}", e) raise ServiceException(ServiceErrorCode.UnableToAdd, "Invalid E-Mail") async def add_auth_user_by_oauth_async(self, dto: OAuthDTO): db_user = self._auth_users.find_auth_user_by_email(dto.user.email) if db_user is None: - raise ServiceException(ServiceErrorCode.InvalidUser, 'User not found') + raise ServiceException(ServiceErrorCode.InvalidUser, "User not found") if db_user.oauth_id != dto.oauth_id: - raise ServiceException(ServiceErrorCode.InvalidUser, 'Wrong OAuthId') + raise ServiceException(ServiceErrorCode.InvalidUser, "Wrong OAuthId") try: db_user.first_name = dto.user.first_name @@ -257,9 +257,9 @@ class AuthService(AuthServiceABC): db_user.confirmation_id = uuid.uuid4() self._send_confirmation_id_to_user(db_user) self._auth_users.update_auth_user(db_user) - self._logger.info(__name__, f'Added auth user with E-Mail: {dto.user.email}') + self._logger.info(__name__, f"Added auth user with E-Mail: {dto.user.email}") except Exception as e: - self._logger.error(__name__, f'Cannot add user with E-Mail {dto.user.email}', e) + self._logger.error(__name__, f"Cannot add user with E-Mail {dto.user.email}", e) raise ServiceException(ServiceErrorCode.UnableToAdd, "Invalid E-Mail") self._db.save_changes() @@ -270,23 +270,23 @@ class AuthService(AuthServiceABC): # user exists if db_auth_user is not None and db_auth_user.users.count() > 0: # raise ServiceException(ServiceErrorCode.InvalidUser, 'User already exists') - self._logger.debug(__name__, f'Discord user already exists') + self._logger.debug(__name__, f"Discord user already exists") return OAuthDTO(AUT.to_dto(db_auth_user), None) # user exists but discord user id not set elif db_auth_user is not None and db_auth_user.users.count() == 0: - self._logger.debug(__name__, f'Auth user exists but not linked with discord') + self._logger.debug(__name__, f"Auth user exists but not linked with discord") # users = self._users.get_users_by_discord_id(user_dto.user_id) # add auth_user to user refs db_auth_user.oauth_id = None else: # user does not exists - self._logger.debug(__name__, f'Auth user does not exist') + self._logger.debug(__name__, f"Auth user does not exist") try: user_dto.user_id = self._users.get_users_by_discord_id(user_dto.user_id).single().user_id except Exception as e: - self._logger.error(__name__, f'User not found') + self._logger.error(__name__, f"User not found") user_dto.user_id = None await self.add_auth_user_async(user_dto) @@ -311,46 +311,61 @@ class AuthService(AuthServiceABC): async def update_user_async(self, update_user_dto: UpdateAuthUserDTO): if update_user_dto is None: - raise ServiceException(ServiceErrorCode.InvalidData, f'User is empty') + raise ServiceException(ServiceErrorCode.InvalidData, f"User is empty") if update_user_dto.auth_user is None: - raise ServiceException(ServiceErrorCode.InvalidData, f'Existing user is empty') + raise ServiceException(ServiceErrorCode.InvalidData, f"Existing user is empty") if update_user_dto.new_auth_user is None: - raise ServiceException(ServiceErrorCode.InvalidData, f'New user is empty') + raise ServiceException(ServiceErrorCode.InvalidData, f"New user is empty") - if not self._is_email_valid(update_user_dto.auth_user.email) or not self._is_email_valid(update_user_dto.new_auth_user.email): - raise ServiceException(ServiceErrorCode.InvalidData, f'Invalid E-Mail') + if not self._is_email_valid(update_user_dto.auth_user.email) or not self._is_email_valid( + update_user_dto.new_auth_user.email + ): + raise ServiceException(ServiceErrorCode.InvalidData, f"Invalid E-Mail") user = self._auth_users.find_auth_user_by_email(update_user_dto.auth_user.email) if user is None: - raise ServiceException(ServiceErrorCode.InvalidUser, 'User not found') + raise ServiceException(ServiceErrorCode.InvalidUser, "User not found") if user.confirmation_id is not None: - raise ServiceException(ServiceErrorCode.InvalidUser, 'E-Mail not confirmed') + raise ServiceException(ServiceErrorCode.InvalidUser, "E-Mail not confirmed") # update first name - if update_user_dto.new_auth_user.first_name is not None and update_user_dto.auth_user.first_name != update_user_dto.new_auth_user.first_name: + if ( + update_user_dto.new_auth_user.first_name is not None + and update_user_dto.auth_user.first_name != update_user_dto.new_auth_user.first_name + ): user.first_name = update_user_dto.new_auth_user.first_name # update last name - if update_user_dto.new_auth_user.last_name is not None and update_user_dto.new_auth_user.last_name != '' and \ - update_user_dto.auth_user.last_name != update_user_dto.new_auth_user.last_name: + if ( + update_user_dto.new_auth_user.last_name is not None + and update_user_dto.new_auth_user.last_name != "" + and update_user_dto.auth_user.last_name != update_user_dto.new_auth_user.last_name + ): user.last_name = update_user_dto.new_auth_user.last_name # update E-Mail - if update_user_dto.new_auth_user.email is not None and update_user_dto.new_auth_user.email != '' and update_user_dto.auth_user.email != update_user_dto.new_auth_user.email: + if ( + update_user_dto.new_auth_user.email is not None + and update_user_dto.new_auth_user.email != "" + and update_user_dto.auth_user.email != update_user_dto.new_auth_user.email + ): user_by_new_e_mail = self._auth_users.find_auth_user_by_email(update_user_dto.new_auth_user.email) if user_by_new_e_mail is not None: - raise ServiceException(ServiceErrorCode.InvalidUser, 'User already exists') + raise ServiceException(ServiceErrorCode.InvalidUser, "User already exists") user.email = update_user_dto.new_auth_user.email update_user_dto.auth_user.password = self._hash_sha256(update_user_dto.auth_user.password, user.password_salt) if update_user_dto.auth_user.password != user.password: - raise ServiceException(ServiceErrorCode.InvalidUser, 'Wrong password') + raise ServiceException(ServiceErrorCode.InvalidUser, "Wrong password") # update password - if update_user_dto.new_auth_user.password is not None and self._hash_sha256(update_user_dto.new_auth_user.password, user.password_salt) != user.password: + if ( + update_user_dto.new_auth_user.password is not None + and self._hash_sha256(update_user_dto.new_auth_user.password, user.password_salt) != user.password + ): user.password_salt = uuid.uuid4() user.password = self._hash_sha256(update_user_dto.new_auth_user.password, user.password_salt) @@ -359,20 +374,22 @@ class AuthService(AuthServiceABC): async def update_user_as_admin_async(self, update_user_dto: UpdateAuthUserDTO): if update_user_dto is None: - raise ServiceException(ServiceErrorCode.InvalidData, f'User is empty') + raise ServiceException(ServiceErrorCode.InvalidData, f"User is empty") if update_user_dto.auth_user is None: - raise ServiceException(ServiceErrorCode.InvalidData, f'Existing user is empty') + raise ServiceException(ServiceErrorCode.InvalidData, f"Existing user is empty") if update_user_dto.new_auth_user is None: - raise ServiceException(ServiceErrorCode.InvalidData, f'New user is empty') + raise ServiceException(ServiceErrorCode.InvalidData, f"New user is empty") - if not self._is_email_valid(update_user_dto.auth_user.email) or not self._is_email_valid(update_user_dto.new_auth_user.email): - raise ServiceException(ServiceErrorCode.InvalidData, f'Invalid E-Mail') + if not self._is_email_valid(update_user_dto.auth_user.email) or not self._is_email_valid( + update_user_dto.new_auth_user.email + ): + raise ServiceException(ServiceErrorCode.InvalidData, f"Invalid E-Mail") user = self._auth_users.find_auth_user_by_email(update_user_dto.auth_user.email) if user is None: - raise ServiceException(ServiceErrorCode.InvalidUser, 'User not found') + raise ServiceException(ServiceErrorCode.InvalidUser, "User not found") if user.confirmation_id is not None and update_user_dto.new_auth_user.is_confirmed: user.confirmation_id = None @@ -382,27 +399,45 @@ class AuthService(AuthServiceABC): # raise ServiceException(ServiceErrorCode.InvalidUser, 'E-Mail not confirmed') # update first name - if update_user_dto.new_auth_user.first_name is not None and update_user_dto.auth_user.first_name != update_user_dto.new_auth_user.first_name: + if ( + update_user_dto.new_auth_user.first_name is not None + and update_user_dto.auth_user.first_name != update_user_dto.new_auth_user.first_name + ): user.first_name = update_user_dto.new_auth_user.first_name # update last name - if update_user_dto.new_auth_user.last_name is not None and update_user_dto.new_auth_user.last_name != '' and update_user_dto.auth_user.last_name != update_user_dto.new_auth_user.last_name: + if ( + update_user_dto.new_auth_user.last_name is not None + and update_user_dto.new_auth_user.last_name != "" + and update_user_dto.auth_user.last_name != update_user_dto.new_auth_user.last_name + ): user.last_name = update_user_dto.new_auth_user.last_name # update E-Mail - if update_user_dto.new_auth_user.email is not None and update_user_dto.new_auth_user.email != '' and update_user_dto.auth_user.email != update_user_dto.new_auth_user.email: + if ( + update_user_dto.new_auth_user.email is not None + and update_user_dto.new_auth_user.email != "" + and update_user_dto.auth_user.email != update_user_dto.new_auth_user.email + ): user_by_new_e_mail = self._auth_users.find_auth_user_by_email(update_user_dto.new_auth_user.email) if user_by_new_e_mail is not None: - raise ServiceException(ServiceErrorCode.InvalidUser, 'User already exists') + raise ServiceException(ServiceErrorCode.InvalidUser, "User already exists") user.email = update_user_dto.new_auth_user.email # update password - if update_user_dto.new_auth_user.password is not None and update_user_dto.change_password and user.password != self._hash_sha256(update_user_dto.new_auth_user.password, user.password_salt): + if ( + update_user_dto.new_auth_user.password is not None + and update_user_dto.change_password + and user.password != self._hash_sha256(update_user_dto.new_auth_user.password, user.password_salt) + ): user.password_salt = uuid.uuid4() user.password = self._hash_sha256(update_user_dto.new_auth_user.password, user.password_salt) # update role - if user.auth_role == update_user_dto.auth_user.auth_role and user.auth_role != update_user_dto.new_auth_user.auth_role: + if ( + user.auth_role == update_user_dto.auth_user.auth_role + and user.auth_role != update_user_dto.new_auth_user.auth_role + ): user.auth_role = update_user_dto.new_auth_user.auth_role self._auth_users.update_auth_user(user) @@ -414,43 +449,46 @@ class AuthService(AuthServiceABC): self._auth_users.delete_auth_user(user) self._db.save_changes() except Exception as e: - self._logger.error(__name__, f'Cannot delete user', e) - raise ServiceException(ServiceErrorCode.UnableToDelete, f'Cannot delete user by mail {email}') + self._logger.error(__name__, f"Cannot delete user", e) + raise ServiceException(ServiceErrorCode.UnableToDelete, f"Cannot delete user by mail {email}") async def delete_auth_user_async(self, user_dto: AuthUser): try: self._auth_users.delete_auth_user(AUT.to_db(user_dto)) self._db.save_changes() except Exception as e: - self._logger.error(__name__, f'Cannot delete user', e) - raise ServiceException(ServiceErrorCode.UnableToDelete, f'Cannot delete user by mail {user_dto.email}') + self._logger.error(__name__, f"Cannot delete user", e) + raise ServiceException( + ServiceErrorCode.UnableToDelete, + f"Cannot delete user by mail {user_dto.email}", + ) def verify_login(self, token_str: str) -> bool: try: token = self.decode_token(token_str) - if token is None or 'email' not in token: - raise ServiceException(ServiceErrorCode.InvalidData, 'Token invalid') + if token is None or "email" not in token: + raise ServiceException(ServiceErrorCode.InvalidData, "Token invalid") - user = self._auth_users.find_auth_user_by_email(token['email']) + user = self._auth_users.find_auth_user_by_email(token["email"]) if user is None: - raise ServiceException(ServiceErrorCode.InvalidData, 'Token expired') + raise ServiceException(ServiceErrorCode.InvalidData, "Token expired") except Exception as e: - self._logger.error(__name__, f'Token invalid', e) + self._logger.error(__name__, f"Token invalid", e) return False return True async def login_async(self, user_dto: AuthUser) -> TokenDTO: if user_dto is None: - raise ServiceException(ServiceErrorCode.InvalidData, 'User not set') + raise ServiceException(ServiceErrorCode.InvalidData, "User not set") db_user = self._auth_users.find_auth_user_by_email(user_dto.email) if db_user is None: - raise ServiceException(ServiceErrorCode.InvalidUser, f'User not found') + raise ServiceException(ServiceErrorCode.InvalidUser, f"User not found") user_dto.password = self._hash_sha256(user_dto.password, db_user.password_salt) if db_user.password != user_dto.password: - raise ServiceException(ServiceErrorCode.InvalidUser, 'Wrong password') + raise ServiceException(ServiceErrorCode.InvalidUser, "Wrong password") token = self.generate_token(db_user) refresh_token = self._create_and_save_refresh_token(db_user) @@ -462,7 +500,7 @@ class AuthService(AuthServiceABC): async def login_discord_async(self, user_dto: AuthUserDTO) -> TokenDTO: if user_dto is None: - raise ServiceException(ServiceErrorCode.InvalidData, 'User not set') + raise ServiceException(ServiceErrorCode.InvalidData, "User not set") db_user = self._auth_users.find_auth_user_by_email(user_dto.email) if db_user is None: @@ -480,38 +518,46 @@ class AuthService(AuthServiceABC): async def refresh_async(self, token_dto: TokenDTO) -> TokenDTO: if token_dto is None: - raise ServiceException(ServiceErrorCode.InvalidData, f'Token not set') + raise ServiceException(ServiceErrorCode.InvalidData, f"Token not set") try: token = self.decode_token(token_dto.token) - if token is None or 'email' not in token: - raise ServiceException(ServiceErrorCode.InvalidData, 'Token invalid') + if token is None or "email" not in token: + raise ServiceException(ServiceErrorCode.InvalidData, "Token invalid") - user = self._auth_users.get_auth_user_by_email(token['email']) - if user is None or user.refresh_token != token_dto.refresh_token or user.refresh_token_expire_time <= datetime.now(): - raise ServiceException(ServiceErrorCode.InvalidData, 'Token expired') + user = self._auth_users.get_auth_user_by_email(token["email"]) + if ( + user is None + or user.refresh_token != token_dto.refresh_token + or user.refresh_token_expire_time <= datetime.now() + ): + raise ServiceException(ServiceErrorCode.InvalidData, "Token expired") return TokenDTO(self.generate_token(user), self._create_and_save_refresh_token(user)) except Exception as e: - self._logger.error(__name__, f'Refreshing token failed', e) - return TokenDTO('', '') + self._logger.error(__name__, f"Refreshing token failed", e) + return TokenDTO("", "") async def revoke_async(self, token_dto: TokenDTO): if token_dto is None or token_dto.token is None or token_dto.refresh_token is None: - raise ServiceException(ServiceErrorCode.InvalidData, 'Token not set') + raise ServiceException(ServiceErrorCode.InvalidData, "Token not set") try: token = self.decode_token(token_dto.token) - user = self._auth_users.get_auth_user_by_email(token['email']) - if user is None or user.refresh_token != token_dto.refresh_token or user.refresh_token_expire_time <= datetime.now(): - raise ServiceException(ServiceErrorCode.InvalidData, 'Token expired') + user = self._auth_users.get_auth_user_by_email(token["email"]) + if ( + user is None + or user.refresh_token != token_dto.refresh_token + or user.refresh_token_expire_time <= datetime.now() + ): + raise ServiceException(ServiceErrorCode.InvalidData, "Token expired") user.refresh_token = None self._auth_users.update_auth_user(user) self._db.save_changes() except Exception as e: - self._logger.error(__name__, f'Refreshing token failed', e) + self._logger.error(__name__, f"Refreshing token failed", e) async def confirm_email_async(self, id: str) -> bool: user = self._auth_users.find_auth_user_by_confirmation_id(id) @@ -540,13 +586,16 @@ class AuthService(AuthServiceABC): async def reset_password_async(self, rp_dto: ResetPasswordDTO): user = self._auth_users.find_auth_user_by_forgot_password_id(rp_dto.id) if user is None: - raise ServiceException(ServiceErrorCode.InvalidUser, f'User by forgot password id {rp_dto.id} not found') + raise ServiceException( + ServiceErrorCode.InvalidUser, + f"User by forgot password id {rp_dto.id} not found", + ) if user.confirmation_id is not None: - raise ServiceException(ServiceErrorCode.InvalidUser, f'E-Mail not confirmed') + raise ServiceException(ServiceErrorCode.InvalidUser, f"E-Mail not confirmed") - if user.password is None or rp_dto.password == '': - raise ServiceException(ServiceErrorCode.InvalidData, f'Password not set') + if user.password is None or rp_dto.password == "": + raise ServiceException(ServiceErrorCode.InvalidData, f"Password not set") user.password_salt = uuid.uuid4() user.password = self._hash_sha256(rp_dto.password, user.password_salt) diff --git a/kdb-bot/src/bot_api/service/discord_service.py b/kdb-bot/src/bot_api/service/discord_service.py index 507a9713..4770930a 100644 --- a/kdb-bot/src/bot_api/service/discord_service.py +++ b/kdb-bot/src/bot_api/service/discord_service.py @@ -20,14 +20,13 @@ from bot_data.model.server import Server class DiscordService: - def __init__( - self, - bot: DiscordBotServiceABC, - servers: ServerRepositoryABC, - auth: AuthServiceABC, - auth_users: AuthUserRepositoryABC, - users: UserRepositoryABC, + self, + bot: DiscordBotServiceABC, + servers: ServerRepositoryABC, + auth: AuthServiceABC, + auth_users: AuthUserRepositoryABC, + users: UserRepositoryABC, ): self._bot = bot self._servers = servers @@ -38,64 +37,53 @@ class DiscordService: def _to_dto(self, x: Server) -> Optional[ServerDTO]: guild = self._bot.get_guild(x.discord_server_id) if guild is None: - return ServerTransformer.to_dto( - x, - '', - 0, - None - ) + return ServerTransformer.to_dto(x, "", 0, None) - return ServerTransformer.to_dto( - x, - guild.name, - guild.member_count, - guild.icon - ) + return ServerTransformer.to_dto(x, guild.name, guild.member_count, guild.icon) async def get_all_servers(self) -> List[ServerDTO]: servers = List(ServerDTO, self._servers.get_servers()) - return servers.select(self._to_dto).where(lambda x: x.name != '') + return servers.select(self._to_dto).where(lambda x: x.name != "") async def get_all_servers_by_user(self) -> List[ServerDTO]: token = self._auth.get_decoded_token_from_request() - if token is None or 'email' not in token or 'role' not in token: - raise ServiceException(ServiceErrorCode.InvalidData, 'Token invalid') + if token is None or "email" not in token or "role" not in token: + raise ServiceException(ServiceErrorCode.InvalidData, "Token invalid") - role = AuthRoleEnum(token['role']) + role = AuthRoleEnum(token["role"]) servers = self._servers.get_servers() if role != AuthRoleEnum.admin: - auth_user = self._auth_users.find_auth_user_by_email(token['email']) + auth_user = self._auth_users.find_auth_user_by_email(token["email"]) if auth_user is not None: user_ids = auth_user.users.select(lambda x: x.server is not None and x.server.server_id) servers = servers.where(lambda x: x.server_id in user_ids) servers = List(ServerDTO, servers) - return servers.select(self._to_dto).where(lambda x: x.name != '') + return servers.select(self._to_dto).where(lambda x: x.name != "") async def get_filtered_servers_async(self, criteria: ServerSelectCriteria) -> ServerFilteredResultDTO: token = self._auth.get_decoded_token_from_request() - if token is None or 'email' not in token or 'role' not in token: - raise ServiceException(ServiceErrorCode.InvalidData, 'Token invalid') + if token is None or "email" not in token or "role" not in token: + raise ServiceException(ServiceErrorCode.InvalidData, "Token invalid") - role = AuthRoleEnum(token['role']) + role = AuthRoleEnum(token["role"]) filtered_result = self._servers.get_filtered_servers(criteria) # filter out servers, where the user not exists if role != AuthRoleEnum.admin: - auth_user = self._auth_users.find_auth_user_by_email(token['email']) + auth_user = self._auth_users.find_auth_user_by_email(token["email"]) if auth_user is not None: user_ids = auth_user.users.select(lambda x: x.server is not None and x.server.server_id) filtered_result.result = filtered_result.result.where(lambda x: x.server_id in user_ids) - servers: List = filtered_result.result.select(self._to_dto).where(lambda x: x.name != '') + servers: List = filtered_result.result.select(self._to_dto).where(lambda x: x.name != "") result = List(ServerDTO, servers) - if criteria.name is not None and criteria.name != '': - result = result.where(lambda x: criteria.name.lower() in x.name.lower() or x.name.lower() == criteria.name.lower()) + if criteria.name is not None and criteria.name != "": + result = result.where( + lambda x: criteria.name.lower() in x.name.lower() or x.name.lower() == criteria.name.lower() + ) - return ServerFilteredResultDTO( - List(ServerDTO, result), - servers.count() - ) + return ServerFilteredResultDTO(List(ServerDTO, result), servers.count()) async def get_server_by_id_async(self, id: int) -> ServerDTO: server = self._servers.get_server_by_id(id) diff --git a/kdb-bot/src/bot_api/transformer/__init__.py b/kdb-bot/src/bot_api/transformer/__init__.py index a1915e9f..3cde8386 100644 --- a/kdb-bot/src/bot_api/transformer/__init__.py +++ b/kdb-bot/src/bot_api/transformer/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'bot_api.transformer' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "bot_api.transformer" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/bot_api/transformer/auth_user_transformer.py b/kdb-bot/src/bot_api/transformer/auth_user_transformer.py index 5fc74c7f..56b35504 100644 --- a/kdb-bot/src/bot_api/transformer/auth_user_transformer.py +++ b/kdb-bot/src/bot_api/transformer/auth_user_transformer.py @@ -7,7 +7,6 @@ from bot_data.model.auth_user import AuthUser class AuthUserTransformer(TransformerABC): - @staticmethod def to_db(dto: AuthUserDTO) -> AuthUser: return AuthUser( @@ -22,7 +21,7 @@ class AuthUserTransformer(TransformerABC): None, datetime.now(), AuthRoleEnum.normal if dto.auth_role is None else AuthRoleEnum(dto.auth_role), - auth_user_id=0 if dto.id is None else dto.id + auth_user_id=0 if dto.id is None else dto.id, ) @staticmethod @@ -32,7 +31,7 @@ class AuthUserTransformer(TransformerABC): db.first_name, db.last_name, db.email, - '' if password is None else password, + "" if password is None else password, db.confirmation_id, - db.auth_role + db.auth_role, ) diff --git a/kdb-bot/src/bot_api/transformer/server_transformer.py b/kdb-bot/src/bot_api/transformer/server_transformer.py index d883c42d..bc4c5eeb 100644 --- a/kdb-bot/src/bot_api/transformer/server_transformer.py +++ b/kdb-bot/src/bot_api/transformer/server_transformer.py @@ -8,7 +8,6 @@ from bot_data.model.server import Server class ServerTransformer(TransformerABC): - @staticmethod def to_db(dto: ServerDTO) -> Server: return Server(dto.discord_id) diff --git a/kdb-bot/src/bot_core/__init__.py b/kdb-bot/src/bot_core/__init__.py index 9d27fa55..790bd362 100644 --- a/kdb-bot/src/bot_core/__init__.py +++ b/kdb-bot/src/bot_core/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'bot_core' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "bot_core" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/bot_core/abc/__init__.py b/kdb-bot/src/bot_core/abc/__init__.py index e8949ac9..c28bc6f3 100644 --- a/kdb-bot/src/bot_core/abc/__init__.py +++ b/kdb-bot/src/bot_core/abc/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'bot_core.abc' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "bot_core.abc" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/bot_core/abc/client_utils_abc.py b/kdb-bot/src/bot_core/abc/client_utils_abc.py new file mode 100644 index 00000000..022665c0 --- /dev/null +++ b/kdb-bot/src/bot_core/abc/client_utils_abc.py @@ -0,0 +1,61 @@ +from abc import ABC, abstractmethod +from datetime import datetime +from typing import Callable + +from cpl_query.extension import List +from discord.ext.commands import Context + +from bot_data.model.user import User +from modules.base.configuration.base_server_settings import BaseServerSettings + + +class ClientUtilsABC(ABC): + @abstractmethod + def __init__(self): + pass + + @abstractmethod + def received_command(self, guild_id: int): + pass + + @abstractmethod + def moved_user(self, guild_id: int): + pass + + @abstractmethod + def moved_users(self, guild_id: int, count: int): + pass + + @abstractmethod + def get_client(self, dc_ic: int, guild_id: int): + pass + + @abstractmethod + async def check_if_bot_is_ready_yet(self) -> bool: + pass + + @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 + + @abstractmethod + def get_auto_complete_list(self, _l: List, current: str, select: Callable = None) -> List: + pass + + @abstractmethod + def is_message_xp_count_by_hour_higher_that_max_message_count_per_hour( + self, + created_at: datetime, + user: User, + settings: BaseServerSettings, + is_reaction: bool = False, + ) -> bool: + pass + + @abstractmethod + def get_ontime_for_user(self, user: User) -> float: + pass diff --git a/kdb-bot/src/bot_core/abc/client_utils_service_abc.py b/kdb-bot/src/bot_core/abc/client_utils_service_abc.py deleted file mode 100644 index ca6405ef..00000000 --- a/kdb-bot/src/bot_core/abc/client_utils_service_abc.py +++ /dev/null @@ -1,35 +0,0 @@ -from abc import ABC, abstractmethod -from typing import Callable - -from cpl_query.extension import List -from discord.ext.commands import Context - - -class ClientUtilsServiceABC(ABC): - - @abstractmethod - def __init__(self): pass - - @abstractmethod - def received_command(self, guild_id: int): pass - - @abstractmethod - def moved_user(self, guild_id: int): pass - - @abstractmethod - def moved_users(self, guild_id: int, count: int): pass - - @abstractmethod - def get_client(self, dc_ic: int, guild_id: int): pass - - @abstractmethod - async def check_if_bot_is_ready_yet(self) -> bool: pass - - @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 - - @abstractmethod - def get_auto_complete_list(self, _l: List, current: str, select: Callable = None) -> List: pass diff --git a/kdb-bot/src/bot_core/abc/custom_file_logger_abc.py b/kdb-bot/src/bot_core/abc/custom_file_logger_abc.py index d1cb8160..2b2bbe0a 100644 --- a/kdb-bot/src/bot_core/abc/custom_file_logger_abc.py +++ b/kdb-bot/src/bot_core/abc/custom_file_logger_abc.py @@ -9,11 +9,16 @@ from bot_core.configuration.file_logging_settings import FileLoggingSettings class CustomFileLoggerABC(Logger, ABC): - @abstractmethod - def __init__(self, key: str, config: ConfigurationABC, time_format: TimeFormatSettings, env: ApplicationEnvironmentABC): + def __init__( + self, + key: str, + config: ConfigurationABC, + time_format: TimeFormatSettings, + env: ApplicationEnvironmentABC, + ): self._key = key - self._settings: LoggingSettings = config.get_configuration(f'{FileLoggingSettings.__name__}_{key}') + self._settings: LoggingSettings = config.get_configuration(f"{FileLoggingSettings.__name__}_{key}") Logger.__init__(self, self._settings, time_format, env) self._begin_log() @@ -24,41 +29,41 @@ class CustomFileLoggerABC(Logger, ABC): def _begin_log(self): console_level = self._console.value self._console = LoggingLevelEnum.OFF - self.info(__name__, f'Starting...') + self.info(__name__, f"Starting...") self._console = LoggingLevelEnum(console_level) def _get_string(self, name_list_as_str: str, level: LoggingLevelEnum, message: str) -> str: - names = name_list_as_str.split(' ') + names = name_list_as_str.split(" ") log_level = level.name - string = f'<{self._get_datetime_now()}> [ {log_level} ]' + string = f"<{self._get_datetime_now()}> [ {log_level} ]" for name in names: - string += f' [ {name} ]' - string += f': {message}' + string += f" [ {name} ]" + string += f": {message}" return string def header(self, string: str): super().header(string) def trace(self, name: str, message: str): - name = f'{name} {self._key}' + name = f"{name} {self._key}" super().trace(name, message) def debug(self, name: str, message: str): - name = f'{name} {self._key}' + name = f"{name} {self._key}" super().debug(name, message) def info(self, name: str, message: str): - name = f'{name} {self._key}' + name = f"{name} {self._key}" super().info(name, message) def warn(self, name: str, message: str): - name = f'{name} {self._key}' + name = f"{name} {self._key}" super().warn(name, message) def error(self, name: str, message: str, ex: Exception = None): - name = f'{name} {self._key}' + name = f"{name} {self._key}" super().error(name, message, ex) def fatal(self, name: str, message: str, ex: Exception = None): - name = f'{name} {self._key}' + name = f"{name} {self._key}" super().fatal(name, message, ex) diff --git a/kdb-bot/src/bot_core/abc/message_service_abc.py b/kdb-bot/src/bot_core/abc/message_service_abc.py index 4af35bff..2719b313 100644 --- a/kdb-bot/src/bot_core/abc/message_service_abc.py +++ b/kdb-bot/src/bot_core/abc/message_service_abc.py @@ -1,5 +1,5 @@ from abc import ABC, abstractmethod -from typing import Union +from typing import Union, Optional import discord from cpl_query.extension import List @@ -8,24 +8,58 @@ from discord.ext.commands import Context class MessageServiceABC(ABC): + @abstractmethod + def __init__(self): + pass @abstractmethod - def __init__(self): pass + async def delete_messages(self, messages: List[discord.Message], guild_id: int, without_tracking=False): + pass @abstractmethod - async def delete_messages(self, messages: List[discord.Message], guild_id: int, without_tracking=False): pass + async def delete_message(self, message: discord.Message, without_tracking=False): + pass @abstractmethod - async def delete_message(self, message: discord.Message, without_tracking=False): pass + async def send_channel_message( + self, + channel: discord.TextChannel, + message: Union[str, discord.Embed], + without_tracking=True, + ): + pass @abstractmethod - async def send_channel_message(self, channel: discord.TextChannel, message: Union[str, discord.Embed], without_tracking=True): pass + async def send_dm_message( + self, + message: Union[str, discord.Embed], + receiver: Union[discord.User, discord.Member], + without_tracking=False, + ): + pass @abstractmethod - async def send_dm_message(self, message: Union[str, discord.Embed], receiver: Union[discord.User, discord.Member], without_tracking=False): pass + async def send_ctx_msg( + self, + ctx: Context, + message: Union[str, discord.Embed], + file: discord.File = None, + is_persistent: bool = False, + is_public: bool = False, + wait_before_delete: int = None, + without_tracking=True, + ) -> Optional[discord.Message]: + pass @abstractmethod - async def send_ctx_msg(self, ctx: Context, message: Union[str, discord.Embed], file: discord.File = None, is_persistent: bool = False, is_public: bool = False, wait_before_delete: int = None, without_tracking=True): pass - - @abstractmethod - async def send_interaction_msg(self, interaction: Interaction, message: Union[str, discord.Embed], is_persistent: bool = False, is_public: bool = False, wait_before_delete: int = None, without_tracking=True, **kwargs): pass + async def send_interaction_msg( + self, + interaction: Interaction, + message: Union[str, discord.Embed], + is_persistent: bool = False, + is_public: bool = False, + wait_before_delete: int = None, + without_tracking=True, + **kwargs + ): + pass diff --git a/kdb-bot/src/bot_core/abc/module_abc.py b/kdb-bot/src/bot_core/abc/module_abc.py index 45f5f5b2..8ffb1c6d 100644 --- a/kdb-bot/src/bot_core/abc/module_abc.py +++ b/kdb-bot/src/bot_core/abc/module_abc.py @@ -7,7 +7,6 @@ from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum class ModuleABC(StartupExtensionABC): - @abstractmethod def __init__(self, dc: DiscordCollectionABC, feature_flag: FeatureFlagsEnum): StartupExtensionABC.__init__(self) diff --git a/kdb-bot/src/bot_core/bot-core.json b/kdb-bot/src/bot_core/bot-core.json index 1e7a6a1a..fc6849ec 100644 --- a/kdb-bot/src/bot_core/bot-core.json +++ b/kdb-bot/src/bot_core/bot-core.json @@ -4,7 +4,7 @@ "Version": { "Major": "0", "Minor": "3", - "Micro": "0" + "Micro": "1" }, "Author": "Sven Heidemann", "AuthorEmail": "sven.heidemann@sh-edraft.de", diff --git a/kdb-bot/src/bot_core/configuration/__init__.py b/kdb-bot/src/bot_core/configuration/__init__.py index 3e2d80ff..29bc8a60 100644 --- a/kdb-bot/src/bot_core/configuration/__init__.py +++ b/kdb-bot/src/bot_core/configuration/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'bot_core.configuration' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "bot_core.configuration" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/bot_core/configuration/bot_logging_settings.py b/kdb-bot/src/bot_core/configuration/bot_logging_settings.py index 37ecd6ed..b69e2c73 100644 --- a/kdb-bot/src/bot_core/configuration/bot_logging_settings.py +++ b/kdb-bot/src/bot_core/configuration/bot_logging_settings.py @@ -8,7 +8,6 @@ from bot_core.configuration.file_logging_settings import FileLoggingSettings class BotLoggingSettings(ConfigurationModelABC): - def __init__(self): ConfigurationModelABC.__init__(self) self._files: List[FileLoggingSettings] = List(FileLoggingSettings) @@ -22,12 +21,12 @@ class BotLoggingSettings(ConfigurationModelABC): files = List(FileLoggingSettings) for s in settings: st = FileLoggingSettings() - settings[s]['Key'] = s + settings[s]["Key"] = s st.from_dict(settings[s]) files.append(st) self._files = files except Exception as e: Console.set_foreground_color(ForegroundColorEnum.red) - Console.write_line(f'[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings') - Console.write_line(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}') + Console.write_line(f"[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings") + Console.write_line(f"[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}") Console.set_foreground_color(ForegroundColorEnum.default) diff --git a/kdb-bot/src/bot_core/configuration/bot_settings.py b/kdb-bot/src/bot_core/configuration/bot_settings.py index fbac1dfc..5fb5e0ee 100644 --- a/kdb-bot/src/bot_core/configuration/bot_settings.py +++ b/kdb-bot/src/bot_core/configuration/bot_settings.py @@ -8,7 +8,6 @@ from bot_core.configuration.server_settings import ServerSettings class BotSettings(ConfigurationModelABC): - def __init__(self): ConfigurationModelABC.__init__(self) @@ -16,7 +15,8 @@ class BotSettings(ConfigurationModelABC): self._technicians: List[int] = List(int) self._wait_for_restart = 2 self._wait_for_shutdown = 2 - + self._cache_max_messages = 1000 + @property def servers(self) -> List[ServerSettings]: return self._servers @@ -33,6 +33,10 @@ class BotSettings(ConfigurationModelABC): def wait_for_shutdown(self) -> int: return self._wait_for_shutdown + @property + def cache_max_messages(self) -> int: + return self._cache_max_messages + def from_dict(self, settings: dict): try: self._technicians = settings["Technicians"] @@ -41,6 +45,11 @@ class BotSettings(ConfigurationModelABC): settings.pop("Technicians") settings.pop("WaitForRestart") settings.pop("WaitForShutdown") + + if "CacheMaxMessages" in settings: + self._cache_max_messages = settings["CacheMaxMessages"] + settings.pop("CacheMaxMessages") + servers = List(ServerSettings) for s in settings: st = ServerSettings() @@ -49,5 +58,5 @@ class BotSettings(ConfigurationModelABC): servers.append(st) self._servers = servers except Exception as e: - Console.error(f'[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings') - Console.error(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}') + Console.error(f"[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings") + Console.error(f"[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}") diff --git a/kdb-bot/src/bot_core/configuration/feature_flags_enum.py b/kdb-bot/src/bot_core/configuration/feature_flags_enum.py index f04e5ca7..c5312cdf 100644 --- a/kdb-bot/src/bot_core/configuration/feature_flags_enum.py +++ b/kdb-bot/src/bot_core/configuration/feature_flags_enum.py @@ -3,19 +3,19 @@ from enum import Enum class FeatureFlagsEnum(Enum): # modules - api_module = 'ApiModule' - admin_module = 'AdminModule' - auto_role_module = 'AutoRoleModule' - base_module = 'BaseModule' - boot_log_module = 'BootLogModule' - core_module = 'CoreModule' - core_extension_module = 'CoreExtensionModule' - data_module = 'DataModule', - database_module = 'DatabaseModule', - level_module = 'LevelModule' - moderator_module = 'ModeratorModule' - permission_module = 'PermissionModule' - stats_module = 'StatsModule' + api_module = "ApiModule" + admin_module = "AdminModule" + auto_role_module = "AutoRoleModule" + base_module = "BaseModule" + boot_log_module = "BootLogModule" + core_module = "CoreModule" + core_extension_module = "CoreExtensionModule" + data_module = ("DataModule",) + database_module = ("DatabaseModule",) + level_module = "LevelModule" + moderator_module = "ModeratorModule" + permission_module = "PermissionModule" + stats_module = "StatsModule" # features - api_only = 'ApiOnly' - presence = 'Presence' + api_only = "ApiOnly" + presence = "Presence" diff --git a/kdb-bot/src/bot_core/configuration/feature_flags_settings.py b/kdb-bot/src/bot_core/configuration/feature_flags_settings.py index dff28c6e..966b746e 100644 --- a/kdb-bot/src/bot_core/configuration/feature_flags_settings.py +++ b/kdb-bot/src/bot_core/configuration/feature_flags_settings.py @@ -8,7 +8,6 @@ from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum class FeatureFlagsSettings(ConfigurationModelABC): - def __init__(self): ConfigurationModelABC.__init__(self) @@ -47,5 +46,5 @@ class FeatureFlagsSettings(ConfigurationModelABC): for flag in [f.value for f in FeatureFlagsEnum]: self._load_flag(settings, FeatureFlagsEnum(flag)) except Exception as e: - Console.error(f'[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings') - Console.error(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}') + Console.error(f"[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings") + Console.error(f"[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}") diff --git a/kdb-bot/src/bot_core/configuration/file_logging_settings.py b/kdb-bot/src/bot_core/configuration/file_logging_settings.py index 50f3ddb0..58d461b9 100644 --- a/kdb-bot/src/bot_core/configuration/file_logging_settings.py +++ b/kdb-bot/src/bot_core/configuration/file_logging_settings.py @@ -5,11 +5,10 @@ from cpl_core.logging import LoggingSettings class FileLoggingSettings(LoggingSettings): - def __init__(self): LoggingSettings.__init__(self) - self._key = '' + self._key = "" @property def key(self) -> str: @@ -17,8 +16,8 @@ class FileLoggingSettings(LoggingSettings): def from_dict(self, settings: dict): try: - self._key = settings['Key'] + self._key = settings["Key"] super().from_dict(settings) except Exception as e: - Console.error(f'[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings') - Console.error(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}') + Console.error(f"[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings") + Console.error(f"[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}") diff --git a/kdb-bot/src/bot_core/configuration/server_settings.py b/kdb-bot/src/bot_core/configuration/server_settings.py index 039d16c8..92b73d29 100644 --- a/kdb-bot/src/bot_core/configuration/server_settings.py +++ b/kdb-bot/src/bot_core/configuration/server_settings.py @@ -5,7 +5,6 @@ from cpl_core.console import Console class ServerSettings(ConfigurationModelABC): - def __init__(self): ConfigurationModelABC.__init__(self) @@ -22,8 +21,8 @@ class ServerSettings(ConfigurationModelABC): def from_dict(self, settings: dict): try: - self._id = int(settings['Id']) - self._message_delete_timer = int(settings['MessageDeleteTimer']) + self._id = int(settings["Id"]) + self._message_delete_timer = int(settings["MessageDeleteTimer"]) except Exception as e: - Console.error(f'[ ERROR ] [ {__name__} ]: Reading error in settings') - Console.error(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}') + Console.error(f"[ ERROR ] [ {__name__} ]: Reading error in settings") + Console.error(f"[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}") diff --git a/kdb-bot/src/bot_core/core_extension/__init__.py b/kdb-bot/src/bot_core/core_extension/__init__.py index f6d56342..23dc223f 100644 --- a/kdb-bot/src/bot_core/core_extension/__init__.py +++ b/kdb-bot/src/bot_core/core_extension/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'bot_core.core_extension' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "bot_core.core_extension" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/bot_core/core_extension/core_extension.py b/kdb-bot/src/bot_core/core_extension/core_extension.py index a482bcc3..de5a1781 100644 --- a/kdb-bot/src/bot_core/core_extension/core_extension.py +++ b/kdb-bot/src/bot_core/core_extension/core_extension.py @@ -3,7 +3,7 @@ from cpl_core.configuration import ConfigurationABC from cpl_core.dependency_injection import ServiceProviderABC from cpl_translation import TranslatePipe -from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC +from bot_core.abc.client_utils_abc import ClientUtilsABC from bot_core.abc.message_service_abc import MessageServiceABC from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings @@ -13,7 +13,6 @@ from modules.permission.abc.permission_service_abc import PermissionServiceABC class CoreExtension(ApplicationExtensionABC): - def __init__(self): ApplicationExtensionABC.__init__(self) @@ -23,7 +22,7 @@ class CoreExtension(ApplicationExtensionABC): return permissions: PermissionServiceABC = services.get_service(PermissionServiceABC) - client_utils: ClientUtilsServiceABC = services.get_service(ClientUtilsServiceABC) + client_utils: ClientUtilsABC = services.get_service(ClientUtilsABC) message_service: MessageServiceABC = services.get_service(MessageServiceABC) t: TranslatePipe = services.get_service(TranslatePipe) CommandChecks.init(permissions, client_utils, message_service, t) diff --git a/kdb-bot/src/bot_core/core_extension/core_extension_module.py b/kdb-bot/src/bot_core/core_extension/core_extension_module.py index 26f1a063..d6cba99b 100644 --- a/kdb-bot/src/bot_core/core_extension/core_extension_module.py +++ b/kdb-bot/src/bot_core/core_extension/core_extension_module.py @@ -6,11 +6,12 @@ from cpl_discord.service.discord_collection_abc import DiscordCollectionABC from bot_core.abc.module_abc import ModuleABC from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum -from bot_core.core_extension.core_extension_on_ready_event import CoreExtensionOnReadyEvent +from bot_core.core_extension.core_extension_on_ready_event import ( + CoreExtensionOnReadyEvent, +) class CoreExtensionModule(ModuleABC): - def __init__(self, dc: DiscordCollectionABC): ModuleABC.__init__(self, dc, FeatureFlagsEnum.core_extension_module) diff --git a/kdb-bot/src/bot_core/core_extension/core_extension_on_ready_event.py b/kdb-bot/src/bot_core/core_extension/core_extension_on_ready_event.py index fd1f42c6..78992473 100644 --- a/kdb-bot/src/bot_core/core_extension/core_extension_on_ready_event.py +++ b/kdb-bot/src/bot_core/core_extension/core_extension_on_ready_event.py @@ -5,17 +5,16 @@ 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 +from bot_core.abc.client_utils_abc import ClientUtilsABC class CoreExtensionOnReadyEvent(OnReadyABC): - def __init__( - self, - logger: LoggerABC, - bot: DiscordBotServiceABC, - client_utils: ClientUtilsServiceABC, - t: TranslatePipe + self, + logger: LoggerABC, + bot: DiscordBotServiceABC, + client_utils: ClientUtilsABC, + t: TranslatePipe, ): OnReadyABC.__init__(self) @@ -24,9 +23,9 @@ class CoreExtensionOnReadyEvent(OnReadyABC): self._client_utils = client_utils self._t = t - self._logger.info(__name__, f'Module {type(self)} loaded') + 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') + 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/kdb-bot/src/bot_core/core_module.py b/kdb-bot/src/bot_core/core_module.py index 60d4337a..001dc36c 100644 --- a/kdb-bot/src/bot_core/core_module.py +++ b/kdb-bot/src/bot_core/core_module.py @@ -4,7 +4,7 @@ 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.client_utils_service_abc import ClientUtilsServiceABC +from bot_core.abc.client_utils_abc import ClientUtilsABC from bot_core.abc.message_service_abc import MessageServiceABC from bot_core.abc.module_abc import ModuleABC from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum @@ -15,7 +15,6 @@ from bot_core.service.message_service import MessageService class CoreModule(ModuleABC): - def __init__(self, dc: DiscordCollectionABC): ModuleABC.__init__(self, dc, FeatureFlagsEnum.core_module) @@ -24,7 +23,7 @@ class CoreModule(ModuleABC): def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC): services.add_transient(MessageServiceABC, MessageService) - services.add_transient(ClientUtilsServiceABC, ClientUtilsService) + services.add_transient(ClientUtilsABC, ClientUtilsService) # pipes services.add_transient(DateTimeOffsetPipe) diff --git a/kdb-bot/src/bot_core/events/__init__.py b/kdb-bot/src/bot_core/events/__init__.py index 3ea3777d..8d776c9b 100644 --- a/kdb-bot/src/bot_core/events/__init__.py +++ b/kdb-bot/src/bot_core/events/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'bot_core.events' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "bot_core.events" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/bot_core/events/core_on_ready_event.py b/kdb-bot/src/bot_core/events/core_on_ready_event.py index 540f9d1f..10a88f9d 100644 --- a/kdb-bot/src/bot_core/events/core_on_ready_event.py +++ b/kdb-bot/src/bot_core/events/core_on_ready_event.py @@ -3,17 +3,16 @@ 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 +from bot_core.abc.client_utils_abc import ClientUtilsABC class CoreOnReadyEvent(OnReadyABC): - def __init__( - self, - logger: LoggerABC, - bot: DiscordBotServiceABC, - client_utils: ClientUtilsServiceABC, - t: TranslatePipe, + self, + logger: LoggerABC, + bot: DiscordBotServiceABC, + client_utils: ClientUtilsABC, + t: TranslatePipe, ): OnReadyABC.__init__(self) @@ -22,9 +21,9 @@ class CoreOnReadyEvent(OnReadyABC): self._client_utils = client_utils self._t = t - self._logger.info(__name__, f'Module {type(self)} loaded') + 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') + 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/kdb-bot/src/bot_core/exception/__init__.py b/kdb-bot/src/bot_core/exception/__init__.py index 16cb02cc..8fc6b6f8 100644 --- a/kdb-bot/src/bot_core/exception/__init__.py +++ b/kdb-bot/src/bot_core/exception/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'bot_core.exception' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "bot_core.exception" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/bot_core/exception/check_error.py b/kdb-bot/src/bot_core/exception/check_error.py index d5c9a2b8..323065e8 100644 --- a/kdb-bot/src/bot_core/exception/check_error.py +++ b/kdb-bot/src/bot_core/exception/check_error.py @@ -2,6 +2,5 @@ from discord.ext.commands import CommandError class CheckError(CommandError): - def __init__(self, message, *args): CommandError.__init__(self, message, *args) diff --git a/kdb-bot/src/bot_core/helper/__init__.py b/kdb-bot/src/bot_core/helper/__init__.py index e6122ab2..86d269b5 100644 --- a/kdb-bot/src/bot_core/helper/__init__.py +++ b/kdb-bot/src/bot_core/helper/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'bot_core.helper' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "bot_core.helper" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/bot_core/helper/command_checks.py b/kdb-bot/src/bot_core/helper/command_checks.py index 6bb3fa30..e2048409 100644 --- a/kdb-bot/src/bot_core/helper/command_checks.py +++ b/kdb-bot/src/bot_core/helper/command_checks.py @@ -4,7 +4,7 @@ from cpl_translation import TranslatePipe from discord.ext import commands from discord.ext.commands import Context -from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC +from bot_core.abc.client_utils_abc import ClientUtilsABC from bot_core.abc.message_service_abc import MessageServiceABC from bot_core.exception.check_error import CheckError from modules.permission.abc.permission_service_abc import PermissionServiceABC @@ -12,17 +12,17 @@ from modules.permission.abc.permission_service_abc import PermissionServiceABC class CommandChecks: _permissions: Optional[PermissionServiceABC] = None - _client_utils: Optional[ClientUtilsServiceABC] = None + _client_utils: Optional[ClientUtilsABC] = None _message_service: Optional[MessageServiceABC] = None _t: Optional[TranslatePipe] = None @classmethod def init( - cls, - permissions: PermissionServiceABC, - client_utils: ClientUtilsServiceABC, - message_service: MessageServiceABC, - translate: TranslatePipe, + cls, + permissions: PermissionServiceABC, + client_utils: ClientUtilsABC, + message_service: MessageServiceABC, + translate: TranslatePipe, ): cls._permissions = permissions cls._client_utils = client_utils @@ -34,7 +34,7 @@ class CommandChecks: async def check_if_bot_is_ready_yet_and_respond(ctx: Context) -> bool: result = await cls._client_utils.check_if_bot_is_ready_yet_and_respond(ctx) if not result: - raise CheckError(f'Bot is not ready') + raise CheckError(f"Bot is not ready") return result return commands.check(check_if_bot_is_ready_yet_and_respond) @@ -44,8 +44,8 @@ class CommandChecks: async def check_is_member_admin(ctx: Context): has_permission = cls._permissions.is_member_admin(ctx.author) if not has_permission: - await cls._message_service.send_ctx_msg(ctx, cls._t.transform('common.no_permission_message')) - raise CheckError(f'Member {ctx.author.name} is not admin') + await cls._message_service.send_ctx_msg(ctx, cls._t.transform("common.no_permission_message")) + raise CheckError(f"Member {ctx.author.name} is not admin") return has_permission @@ -56,8 +56,8 @@ class CommandChecks: async def check_is_member_technician(ctx: Context): has_permission = cls._permissions.is_member_technician(ctx.author) if not has_permission: - await cls._message_service.send_ctx_msg(ctx, cls._t.transform('common.no_permission_message')) - raise CheckError(f'Member {ctx.author.name} is not technician') + await cls._message_service.send_ctx_msg(ctx, cls._t.transform("common.no_permission_message")) + raise CheckError(f"Member {ctx.author.name} is not technician") return has_permission @@ -68,8 +68,8 @@ class CommandChecks: async def check_is_member_moderator(ctx: Context): has_permission = cls._permissions.is_member_moderator(ctx.author) if not has_permission: - await cls._message_service.send_ctx_msg(ctx, cls._t.transform('common.no_permission_message')) - raise CheckError(f'Member {ctx.author.name} is not moderator') + await cls._message_service.send_ctx_msg(ctx, cls._t.transform("common.no_permission_message")) + raise CheckError(f"Member {ctx.author.name} is not moderator") return has_permission diff --git a/kdb-bot/src/bot_core/helper/event_checks.py b/kdb-bot/src/bot_core/helper/event_checks.py index 0eba341c..dbf241ab 100644 --- a/kdb-bot/src/bot_core/helper/event_checks.py +++ b/kdb-bot/src/bot_core/helper/event_checks.py @@ -4,19 +4,19 @@ from cpl_translation import TranslatePipe from discord.ext import commands from discord.ext.commands import Context -from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC +from bot_core.abc.client_utils_abc import ClientUtilsABC from bot_core.abc.message_service_abc import MessageServiceABC from bot_core.exception.check_error import CheckError from modules.permission.abc.permission_service_abc import PermissionServiceABC class EventChecks: - _client_utils: Optional[ClientUtilsServiceABC] = None + _client_utils: Optional[ClientUtilsABC] = None @classmethod def init( - cls, - client_utils: ClientUtilsServiceABC, + cls, + client_utils: ClientUtilsABC, ): cls._client_utils = client_utils @@ -25,7 +25,7 @@ class EventChecks: async def check_if_bot_is_ready() -> bool: result = await cls._client_utils.check_if_bot_is_ready() if not result: - raise CheckError(f'Bot is not ready') + raise CheckError(f"Bot is not ready") return result return commands.check(check_if_bot_is_ready) diff --git a/kdb-bot/src/bot_core/helper/log_message_helper.py b/kdb-bot/src/bot_core/helper/log_message_helper.py index 403bf688..7657a8af 100644 --- a/kdb-bot/src/bot_core/helper/log_message_helper.py +++ b/kdb-bot/src/bot_core/helper/log_message_helper.py @@ -2,8 +2,7 @@ import discord class LogMessageHelper: - @staticmethod def get_log_string(message: discord.Message): content = message.content.replace("\n", "\n\t") - return f'{message.author} @ {message.channel} -> \n\t{content}' + return f"{message.author} @ {message.channel} -> \n\t{content}" diff --git a/kdb-bot/src/bot_core/logging/__init__.py b/kdb-bot/src/bot_core/logging/__init__.py index 7c415dff..c5cc6143 100644 --- a/kdb-bot/src/bot_core/logging/__init__.py +++ b/kdb-bot/src/bot_core/logging/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'bot_core.logging' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "bot_core.logging" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/bot_core/logging/command_logger.py b/kdb-bot/src/bot_core/logging/command_logger.py index 16d6f15b..c790d615 100644 --- a/kdb-bot/src/bot_core/logging/command_logger.py +++ b/kdb-bot/src/bot_core/logging/command_logger.py @@ -6,6 +6,10 @@ from bot_core.abc.custom_file_logger_abc import CustomFileLoggerABC class CommandLogger(CustomFileLoggerABC): - - def __init__(self, config: ConfigurationABC, time_format: TimeFormatSettings, env: ApplicationEnvironmentABC): - CustomFileLoggerABC.__init__(self, 'Command', config, time_format, env) + def __init__( + self, + config: ConfigurationABC, + time_format: TimeFormatSettings, + env: ApplicationEnvironmentABC, + ): + CustomFileLoggerABC.__init__(self, "Command", config, time_format, env) diff --git a/kdb-bot/src/bot_core/logging/database_logger.py b/kdb-bot/src/bot_core/logging/database_logger.py index dfc1f637..3c88e46f 100644 --- a/kdb-bot/src/bot_core/logging/database_logger.py +++ b/kdb-bot/src/bot_core/logging/database_logger.py @@ -6,6 +6,10 @@ from bot_core.abc.custom_file_logger_abc import CustomFileLoggerABC class DatabaseLogger(CustomFileLoggerABC): - - def __init__(self, config: ConfigurationABC, time_format: TimeFormatSettings, env: ApplicationEnvironmentABC): - CustomFileLoggerABC.__init__(self, 'Database', config, time_format, env) + def __init__( + self, + config: ConfigurationABC, + time_format: TimeFormatSettings, + env: ApplicationEnvironmentABC, + ): + CustomFileLoggerABC.__init__(self, "Database", config, time_format, env) diff --git a/kdb-bot/src/bot_core/logging/message_logger.py b/kdb-bot/src/bot_core/logging/message_logger.py index 78ce56e1..05751e99 100644 --- a/kdb-bot/src/bot_core/logging/message_logger.py +++ b/kdb-bot/src/bot_core/logging/message_logger.py @@ -6,6 +6,10 @@ from bot_core.abc.custom_file_logger_abc import CustomFileLoggerABC class MessageLogger(CustomFileLoggerABC): - - def __init__(self, config: ConfigurationABC, time_format: TimeFormatSettings, env: ApplicationEnvironmentABC): - CustomFileLoggerABC.__init__(self, 'Message', config, time_format, env) + def __init__( + self, + config: ConfigurationABC, + time_format: TimeFormatSettings, + env: ApplicationEnvironmentABC, + ): + CustomFileLoggerABC.__init__(self, "Message", config, time_format, env) diff --git a/kdb-bot/src/bot_core/pipes/__init__.py b/kdb-bot/src/bot_core/pipes/__init__.py index 345eea8d..da20a4b1 100644 --- a/kdb-bot/src/bot_core/pipes/__init__.py +++ b/kdb-bot/src/bot_core/pipes/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'bot_core.pipes' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "bot_core.pipes" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/bot_core/pipes/date_time_offset_pipe.py b/kdb-bot/src/bot_core/pipes/date_time_offset_pipe.py index 85146047..2f7d1136 100644 --- a/kdb-bot/src/bot_core/pipes/date_time_offset_pipe.py +++ b/kdb-bot/src/bot_core/pipes/date_time_offset_pipe.py @@ -4,8 +4,8 @@ from cpl_core.pipes.pipe_abc import PipeABC class DateTimeOffsetPipe(PipeABC): - - def __init__(self): pass + def __init__(self): + pass def transform(self, value: datetime, *args): - return value.strftime('%Y-%m-%d %H:%M') + return value.strftime("%Y-%m-%d %H:%M") diff --git a/kdb-bot/src/bot_core/service/__init__.py b/kdb-bot/src/bot_core/service/__init__.py index 2e659d24..9341d634 100644 --- a/kdb-bot/src/bot_core/service/__init__.py +++ b/kdb-bot/src/bot_core/service/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'bot_core.service' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "bot_core.service" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/bot_core/service/client_utils_service.py b/kdb-bot/src/bot_core/service/client_utils_service.py index bf2aaef1..414b62e2 100644 --- a/kdb-bot/src/bot_core/service/client_utils_service.py +++ b/kdb-bot/src/bot_core/service/client_utils_service.py @@ -1,44 +1,58 @@ +from datetime import datetime from typing import Callable import discord from cpl_core.configuration import ConfigurationABC from cpl_core.database.context import DatabaseContextABC from cpl_core.logging import LoggerABC - +from cpl_core.time import TimeFormatSettings from cpl_discord.service import DiscordBotServiceABC from cpl_query.extension import List from cpl_translation import TranslatePipe -from discord import app_commands from discord.ext.commands import Context -from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC +from bot_core.abc.client_utils_abc import ClientUtilsABC from bot_core.abc.message_service_abc import MessageServiceABC from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings from bot_data.abc.client_repository_abc import ClientRepositoryABC from bot_data.abc.server_repository_abc import ServerRepositoryABC +from bot_data.abc.user_joined_voice_channel_repository_abc import ( + UserJoinedVoiceChannelRepositoryABC, +) +from bot_data.abc.user_message_count_per_hour_repository_abc import ( + UserMessageCountPerHourRepositoryABC, +) +from bot_data.model.user import User +from bot_data.model.user_message_count_per_hour import UserMessageCountPerHour +from modules.base.configuration.base_server_settings import BaseServerSettings -class ClientUtilsService(ClientUtilsServiceABC): - +class ClientUtilsService(ClientUtilsABC): def __init__( - self, - config: ConfigurationABC, - logger: LoggerABC, - bot: DiscordBotServiceABC, - servers: ServerRepositoryABC, - clients: ClientRepositoryABC, - message_service: MessageServiceABC, - db: DatabaseContextABC, - t: TranslatePipe, - feature_flags: FeatureFlagsSettings + self, + config: ConfigurationABC, + logger: LoggerABC, + time_format: TimeFormatSettings, + bot: DiscordBotServiceABC, + servers: ServerRepositoryABC, + clients: ClientRepositoryABC, + user_joined_vc: UserJoinedVoiceChannelRepositoryABC, + umcphs: UserMessageCountPerHourRepositoryABC, + message_service: MessageServiceABC, + db: DatabaseContextABC, + t: TranslatePipe, + feature_flags: FeatureFlagsSettings, ): - ClientUtilsServiceABC.__init__(self) + ClientUtilsABC.__init__(self) self._config = config self._logger = logger + self._time_format = time_format self._bot = bot self._servers = servers + self._umcphs = umcphs self._clients = clients + self._user_joined_voice_channel = user_joined_vc self._message_service = message_service self._db = db self._t = t @@ -71,16 +85,23 @@ class ClientUtilsService(ClientUtilsServiceABC): return client async def check_if_bot_is_ready_yet(self) -> bool: - if self._config.get_configuration('IS_READY') == 'true': + if self._config.get_configuration("IS_READY") == "true": return True - self._logger.debug(__name__, f'Bot is not ready yet {self._t.transform("common.errors.bot_not_ready_yet")}') + self._logger.debug( + __name__, + f'Bot is not ready yet {self._t.transform("common.errors.bot_not_ready_yet")}', + ) return False async def check_if_bot_is_ready_yet_and_respond(self, ctx: Context) -> bool: result = await self.check_if_bot_is_ready_yet() if not result: - await self._message_service.send_ctx_msg(ctx, self._t.transform('common.errors.bot_not_ready_yet'), without_tracking=True) + await self._message_service.send_ctx_msg( + ctx, + self._t.transform("common.errors.bot_not_ready_yet"), + without_tracking=True, + ) return result @@ -89,12 +110,13 @@ class ClientUtilsService(ClientUtilsServiceABC): return 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}') + self._logger.info(__name__, f"Set presence {name}") def get_auto_complete_list(self, _l: List, current: str, select: Callable = None) -> List: - if current != '': + if current != "": if select is None: select = lambda x: x @@ -106,3 +128,63 @@ class ClientUtilsService(ClientUtilsServiceABC): _l = _l.where(lambda x: x.name in sl) return _l.take(25) + + def is_message_xp_count_by_hour_higher_that_max_message_count_per_hour( + self, + created_at: datetime, + user: User, + settings: BaseServerSettings, + is_reaction: bool = False, + ) -> bool: + umcph = None + try: + umcph = self._umcphs.find_user_message_count_per_hour_by_user_id_and_date(user.user_id, created_at) + if umcph is None: + self._umcphs.add_user_message_count_per_hour( + UserMessageCountPerHour( + created_at.strftime(self._time_format.date_time_format), + created_at.hour, + 0, + user, + ) + ) + + self._db.save_changes() + + umcph = self._umcphs.get_user_message_count_per_hour_by_user_id_and_date(user.user_id, created_at) + except Exception as e: + self._logger.error( + __name__, + f"Cannot add user message count per hour with id {umcph.id}", + e, + ) + return False + + try: + if is_reaction: + umcph.xp_count += settings.xp_per_reaction + else: + umcph.xp_count += settings.xp_per_message + + self._umcphs.update_user_message_count_per_hour(umcph) + self._db.save_changes() + except Exception as e: + self._logger.error( + __name__, + f"Cannot update user message count per hour with id {umcph.id}", + e, + ) + return False + + if umcph.xp_count is None: + return False + + return umcph.xp_count > settings.max_message_xp_per_hour + + def get_ontime_for_user(self, user: User) -> float: + return round( + self._user_joined_voice_channel.get_user_joined_voice_channels_by_user_id(user.user_id) + .where(lambda x: x.leaved_on is not None and x.joined_on is not None) + .sum(lambda join: (join.leaved_on - join.joined_on).total_seconds() / 3600), + 2, + ) diff --git a/kdb-bot/src/bot_core/service/message_service.py b/kdb-bot/src/bot_core/service/message_service.py index 967d23e5..8b07cb79 100644 --- a/kdb-bot/src/bot_core/service/message_service.py +++ b/kdb-bot/src/bot_core/service/message_service.py @@ -1,5 +1,5 @@ import asyncio -from typing import Union +from typing import Union, Optional import discord from cpl_core.configuration.configuration_abc import ConfigurationABC @@ -17,41 +17,66 @@ from bot_data.abc.client_repository_abc import ClientRepositoryABC class MessageService(MessageServiceABC): - - def __init__(self, config: ConfigurationABC, logger: MessageLogger, bot: DiscordBotServiceABC, clients: ClientRepositoryABC, db: DatabaseContextABC): + def __init__( + self, + config: ConfigurationABC, + logger: MessageLogger, + bot: DiscordBotServiceABC, + clients: ClientRepositoryABC, + db: DatabaseContextABC, + ): self._config = config self._logger = logger self._bot = bot self._clients = clients self._db = db - + async def delete_messages(self, messages: List[discord.Message], guild_id: int, without_tracking=False): - self._logger.debug(__name__, f'Try to delete {messages.count()} messages') - server_st: ServerSettings = self._config.get_configuration(f'ServerSettings_{guild_id}') + self._logger.debug(__name__, f"Try to delete {messages.count()} messages") + server_st: ServerSettings = self._config.get_configuration(f"ServerSettings_{guild_id}") await asyncio.sleep(server_st.message_delete_timer) for message in messages: await self.delete_message(message, mass_delete=True, without_tracking=without_tracking) - self._logger.debug(__name__, 'Deleting messages finished') - + self._logger.debug(__name__, "Deleting messages finished") + async def delete_message(self, message: discord.Message, mass_delete=False, without_tracking=False): - server_st: ServerSettings = self._config.get_configuration(f'ServerSettings_{message.guild.id}') + guild_id = ( + message.guild.id + if message.guild is not None + else message.channel.guild.id + if message.channel is not None and message.channel.guild is not None + else message.reference.guild_id + if message.reference is not None and message.reference.guild_id is not None + else None + ) + + server_st: ServerSettings = self._config.get_configuration(f"ServerSettings_{guild_id}") if not mass_delete: await asyncio.sleep(server_st.message_delete_timer) - self._logger.debug(__name__, f'Try to delete message: {LogMessageHelper.get_log_string(message)}') - guild_id = message.guild.id + self._logger.debug( + __name__, + f"Try to delete message: {LogMessageHelper.get_log_string(message)}", + ) try: await message.delete() await asyncio.sleep(server_st.message_delete_timer) except Exception as e: - self._logger.error(__name__, f'Deleting message failed', e) + self._logger.error(__name__, f"Deleting message failed", e) else: if not without_tracking: self._clients.append_deleted_message_count(self._bot.user.id, guild_id, 1) self._db.save_changes() - self._logger.info(__name__, f'Deleted message {message}') - - async def send_channel_message(self, channel: discord.TextChannel, message: Union[str, discord.Embed], is_persistent: bool = False, wait_before_delete: int = None, without_tracking=False): - self._logger.debug(__name__, f'Try to send message\n\t{message}\n\tto: {channel}') + self._logger.info(__name__, f"Deleted message {message}") + + async def send_channel_message( + self, + channel: discord.TextChannel, + message: Union[str, discord.Embed], + is_persistent: bool = False, + wait_before_delete: int = None, + without_tracking=False, + ): + self._logger.debug(__name__, f"Try to send message\n\t{message}\n\tto: {channel}") msg = None try: if isinstance(message, discord.Embed): @@ -59,9 +84,9 @@ class MessageService(MessageServiceABC): else: msg = await channel.send(message) except Exception as e: - self._logger.error(__name__, f'Send message to channel {channel.id} failed', e) + self._logger.error(__name__, f"Send message to channel {channel.id} failed", e) else: - self._logger.info(__name__, f'Sent message to channel {channel.id}') + self._logger.info(__name__, f"Sent message to channel {channel.id}") if not without_tracking: self._clients.append_sent_message_count(self._bot.user.id, channel.guild.id, 1) self._db.save_changes() @@ -73,29 +98,43 @@ class MessageService(MessageServiceABC): return await self.delete_message(msg, without_tracking) - - async def send_dm_message(self, message: Union[str, discord.Embed], receiver: Union[discord.User, discord.Member], without_tracking=False): - self._logger.debug(__name__, f'Try to send message\n\t{message}\n\tto: {receiver}') + + async def send_dm_message( + self, + message: Union[str, discord.Embed], + receiver: Union[discord.User, discord.Member], + without_tracking=False, + ): + self._logger.debug(__name__, f"Try to send message\n\t{message}\n\tto: {receiver}") try: if isinstance(message, discord.Embed): msg = await receiver.send(embed=message) else: msg = await receiver.send(message) except Exception as e: - self._logger.error(__name__, f'Send message to user {receiver.id} failed', e) + self._logger.error(__name__, f"Send message to user {receiver.id} failed", e) else: if not without_tracking: self._clients.append_sent_message_count(self._bot.user.id, receiver.guild.id, 1) self._db.save_changes() - self._logger.info(__name__, f'Sent message to user {receiver.id}') - - async def send_ctx_msg(self, ctx: Context, message: Union[str, discord.Embed], file: discord.File = None, is_persistent: bool = False, is_public: bool = False, wait_before_delete: int = None, without_tracking=False): + self._logger.info(__name__, f"Sent message to user {receiver.id}") + + async def send_ctx_msg( + self, + ctx: Context, + message: Union[str, discord.Embed], + file: discord.File = None, + is_persistent: bool = False, + is_public: bool = False, + wait_before_delete: int = None, + without_tracking=False, + ) -> Optional[discord.Message]: if ctx is None: - self._logger.warn(__name__, 'Message context is empty') - self._logger.debug(__name__, f'Message: {message}') - return - - self._logger.debug(__name__, f'Try to send message\t\t{message}\n\tto: {ctx.channel}') + self._logger.warn(__name__, "Message context is empty") + self._logger.debug(__name__, f"Message: {message}") + return None + + self._logger.debug(__name__, f"Try to send message\t\t{message}\n\tto: {ctx.channel}") msg = None try: if isinstance(message, discord.Embed): @@ -103,9 +142,9 @@ class MessageService(MessageServiceABC): else: msg = await ctx.send(message, file=file, ephemeral=not is_public) except Exception as e: - self._logger.error(__name__, f'Send message to channel {ctx.channel.id} failed', e) + self._logger.error(__name__, f"Send message to channel {ctx.channel.id} failed", e) else: - self._logger.info(__name__, f'Sent message to channel {ctx.channel.id}') + self._logger.info(__name__, f"Sent message to channel {ctx.channel.id}") if not without_tracking and ctx.guild is not None: self._clients.append_sent_message_count(self._bot.user.id, ctx.guild.id, 1) self._db.save_changes() @@ -114,27 +153,38 @@ class MessageService(MessageServiceABC): await asyncio.sleep(wait_before_delete) if is_persistent: - return + return msg if ctx.guild is not None: await self.delete_message(msg, without_tracking) - async def send_interaction_msg(self, interaction: Interaction, message: Union[str, discord.Embed], is_persistent: bool = False, is_public: bool = False, wait_before_delete: int = None, without_tracking=False, **kwargs): + return msg + + async def send_interaction_msg( + self, + interaction: Interaction, + message: Union[str, discord.Embed], + is_persistent: bool = False, + is_public: bool = False, + wait_before_delete: int = None, + without_tracking=False, + **kwargs, + ): if interaction is None: - self._logger.warn(__name__, 'Message context is empty') - self._logger.debug(__name__, f'Message: {message}') + self._logger.warn(__name__, "Message context is empty") + self._logger.debug(__name__, f"Message: {message}") return - self._logger.debug(__name__, f'Try to send message\t\t{message}\n\tto: {interaction.channel}') + self._logger.debug(__name__, f"Try to send message\t\t{message}\n\tto: {interaction.channel}") try: if isinstance(message, discord.Embed): await interaction.response.send_message(embed=message, ephemeral=not is_public, **kwargs) else: await interaction.response.send_message(message, ephemeral=not is_public, **kwargs) except Exception as e: - self._logger.error(__name__, f'Send message to channel {interaction.channel.id} failed', e) + self._logger.error(__name__, f"Send message to channel {interaction.channel.id} failed", e) else: - self._logger.info(__name__, f'Sent message to channel {interaction.channel.id}') + self._logger.info(__name__, f"Sent message to channel {interaction.channel.id}") if not without_tracking and interaction.guild is not None: self._clients.append_sent_message_count(self._bot.user.id, interaction.guild.id, 1) self._db.save_changes() diff --git a/kdb-bot/src/bot_data/__init__.py b/kdb-bot/src/bot_data/__init__.py index 6ac4b954..56258bc2 100644 --- a/kdb-bot/src/bot_data/__init__.py +++ b/kdb-bot/src/bot_data/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'bot_data' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "bot_data" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/bot_data/abc/__init__.py b/kdb-bot/src/bot_data/abc/__init__.py index e312030c..d8521aab 100644 --- a/kdb-bot/src/bot_data/abc/__init__.py +++ b/kdb-bot/src/bot_data/abc/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'bot_data.abc' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "bot_data.abc" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/bot_data/abc/auth_user_repository_abc.py b/kdb-bot/src/bot_data/abc/auth_user_repository_abc.py index 85c85e44..f0299068 100644 --- a/kdb-bot/src/bot_data/abc/auth_user_repository_abc.py +++ b/kdb-bot/src/bot_data/abc/auth_user_repository_abc.py @@ -10,42 +10,54 @@ from bot_data.model.auth_user_users_relation import AuthUserUsersRelation class AuthUserRepositoryABC(ABC): + @abstractmethod + def __init__(self): + pass @abstractmethod - def __init__(self): pass + def get_all_auth_users(self) -> List[AuthUser]: + pass @abstractmethod - def get_all_auth_users(self) -> List[AuthUser]: pass + def get_filtered_auth_users(self, criteria: AuthUserSelectCriteria) -> FilteredResult: + pass @abstractmethod - def get_filtered_auth_users(self, criteria: AuthUserSelectCriteria) -> FilteredResult: pass + def get_auth_user_by_email(self, email: str) -> AuthUser: + pass @abstractmethod - def get_auth_user_by_email(self, email: str) -> AuthUser: pass + def find_auth_user_by_email(self, email: str) -> Optional[AuthUser]: + pass @abstractmethod - def find_auth_user_by_email(self, email: str) -> Optional[AuthUser]: pass + def find_auth_user_by_confirmation_id(self, id: str) -> Optional[AuthUser]: + pass @abstractmethod - def find_auth_user_by_confirmation_id(self, id: str) -> Optional[AuthUser]: pass + def find_auth_user_by_forgot_password_id(self, id: str) -> Optional[AuthUser]: + pass @abstractmethod - def find_auth_user_by_forgot_password_id(self, id: str) -> Optional[AuthUser]: pass + def add_auth_user(self, user: AuthUser): + pass @abstractmethod - def add_auth_user(self, user: AuthUser): pass + def update_auth_user(self, user: AuthUser): + pass @abstractmethod - def update_auth_user(self, user: AuthUser): pass + def delete_auth_user(self, user: AuthUser): + pass @abstractmethod - def delete_auth_user(self, user: AuthUser): pass + def add_auth_user_user_rel(self, rel: AuthUserUsersRelation): + pass @abstractmethod - def add_auth_user_user_rel(self, rel: AuthUserUsersRelation): pass + def update_auth_user_user_rel(self, rel: AuthUserUsersRelation): + pass @abstractmethod - def update_auth_user_user_rel(self, rel: AuthUserUsersRelation): pass - - @abstractmethod - def delete_auth_user_user_rel(self, rel: AuthUserUsersRelation): pass + def delete_auth_user_user_rel(self, rel: AuthUserUsersRelation): + pass diff --git a/kdb-bot/src/bot_data/abc/auto_role_repository_abc.py b/kdb-bot/src/bot_data/abc/auto_role_repository_abc.py index 4283824f..8a4ab02b 100644 --- a/kdb-bot/src/bot_data/abc/auto_role_repository_abc.py +++ b/kdb-bot/src/bot_data/abc/auto_role_repository_abc.py @@ -8,51 +8,66 @@ from bot_data.model.auto_role_rule import AutoRoleRule class AutoRoleRepositoryABC(ABC): + @abstractmethod + def __init__(self): + pass @abstractmethod - def __init__(self): pass + def get_auto_roles(self) -> List[AutoRole]: + pass @abstractmethod - def get_auto_roles(self) -> List[AutoRole]: pass + def get_auto_role_by_id(self, id: int) -> AutoRole: + pass @abstractmethod - def get_auto_role_by_id(self, id: int) -> AutoRole: pass + def find_auto_role_by_id(self, id: int) -> Optional[AutoRole]: + pass @abstractmethod - def find_auto_role_by_id(self, id: int) -> Optional[AutoRole]: pass + def get_auto_roles_by_server_id(self, id: int) -> List[AutoRole]: + pass @abstractmethod - def get_auto_roles_by_server_id(self, id: int) -> List[AutoRole]: pass + def get_auto_role_by_message_id(self, id: int) -> AutoRole: + pass @abstractmethod - def get_auto_role_by_message_id(self, id: int) -> AutoRole: pass + def find_auto_role_by_message_id(self, id: int) -> Optional[AutoRole]: + pass @abstractmethod - def find_auto_role_by_message_id(self, id: int) -> Optional[AutoRole]: pass + def add_auto_role(self, auto_role: AutoRole): + pass @abstractmethod - def add_auto_role(self, auto_role: AutoRole): pass + def update_auto_role(self, auto_role: AutoRole): + pass @abstractmethod - def update_auto_role(self, auto_role: AutoRole): pass + def delete_auto_role(self, auto_role: AutoRole): + pass @abstractmethod - def delete_auto_role(self, auto_role: AutoRole): pass + def get_auto_role_rules(self) -> List[AutoRoleRule]: + pass @abstractmethod - def get_auto_role_rules(self) -> List[AutoRoleRule]: pass + def get_auto_role_rule_by_id(self, id: int) -> AutoRoleRule: + pass @abstractmethod - def get_auto_role_rule_by_id(self, id: int) -> AutoRoleRule: pass + def get_auto_role_rules_by_auto_role_id(self, id: int) -> List[AutoRoleRule]: + pass @abstractmethod - def get_auto_role_rules_by_auto_role_id(self, id: int) -> List[AutoRoleRule]: pass + def add_auto_role_rule(self, auto_role: AutoRoleRule): + pass @abstractmethod - def add_auto_role_rule(self, auto_role: AutoRoleRule): pass + def update_auto_role_rule(self, auto_role: AutoRoleRule): + pass @abstractmethod - def update_auto_role_rule(self, auto_role: AutoRoleRule): pass - - @abstractmethod - def delete_auto_role_rule(self, auto_role: AutoRoleRule): pass + def delete_auto_role_rule(self, auto_role: AutoRoleRule): + pass diff --git a/kdb-bot/src/bot_data/abc/client_repository_abc.py b/kdb-bot/src/bot_data/abc/client_repository_abc.py index 881f43b3..97d34e13 100644 --- a/kdb-bot/src/bot_data/abc/client_repository_abc.py +++ b/kdb-bot/src/bot_data/abc/client_repository_abc.py @@ -6,48 +6,62 @@ from bot_data.model.client import Client class ClientRepositoryABC(ABC): + @abstractmethod + def __init__(self): + pass @abstractmethod - def __init__(self): pass - - @abstractmethod - def get_clients(self) -> List[Client]: pass - - @abstractmethod - def get_client_by_id(self, client_id: int) -> Client: pass - - @abstractmethod - def get_client_by_discord_id(self, discord_id: int) -> Client: pass - - @abstractmethod - def find_client_by_discord_id(self, discord_id: int) -> Optional[Client]: pass - - @abstractmethod - def find_client_by_server_id(self, server_id: int) -> Optional[Client]: pass - - @abstractmethod - def find_client_by_discord_id_and_server_id(self, discord_id: int, server_id: int) -> Optional[Client]: pass - - @abstractmethod - def add_client(self, client: Client): pass - - @abstractmethod - def update_client(self, client: Client): pass - - @abstractmethod - def delete_client(self, client: Client): pass + def get_clients(self) -> List[Client]: + pass @abstractmethod - def append_sent_message_count(self, client_id: int, server_id: int, value: int): pass + def get_client_by_id(self, client_id: int) -> Client: + pass @abstractmethod - def append_received_message_count(self, client_id: int, server_id: int, value: int): pass + def get_client_by_discord_id(self, discord_id: int) -> Client: + pass @abstractmethod - def append_deleted_message_count(self, client_id: int, server_id: int, value: int): pass + def find_client_by_discord_id(self, discord_id: int) -> Optional[Client]: + pass @abstractmethod - def append_received_command_count(self, client_id: int, server_id: int, value: int): pass + def find_client_by_server_id(self, server_id: int) -> Optional[Client]: + pass @abstractmethod - def append_moved_users_count(self, client_id: int, server_id: int, value: int): pass + def find_client_by_discord_id_and_server_id(self, discord_id: int, server_id: int) -> Optional[Client]: + pass + + @abstractmethod + def add_client(self, client: Client): + pass + + @abstractmethod + def update_client(self, client: Client): + pass + + @abstractmethod + def delete_client(self, client: Client): + pass + + @abstractmethod + def append_sent_message_count(self, client_id: int, server_id: int, value: int): + pass + + @abstractmethod + def append_received_message_count(self, client_id: int, server_id: int, value: int): + pass + + @abstractmethod + def append_deleted_message_count(self, client_id: int, server_id: int, value: int): + pass + + @abstractmethod + def append_received_command_count(self, client_id: int, server_id: int, value: int): + pass + + @abstractmethod + def append_moved_users_count(self, client_id: int, server_id: int, value: int): + pass diff --git a/kdb-bot/src/bot_data/abc/data_seeder_abc.py b/kdb-bot/src/bot_data/abc/data_seeder_abc.py index a4fecdd7..e49dc486 100644 --- a/kdb-bot/src/bot_data/abc/data_seeder_abc.py +++ b/kdb-bot/src/bot_data/abc/data_seeder_abc.py @@ -2,9 +2,10 @@ from abc import ABC, abstractmethod class DataSeederABC(ABC): + @abstractmethod + def __init__(self): + pass @abstractmethod - def __init__(self): pass - - @abstractmethod - def seed(self): pass + def seed(self): + pass diff --git a/kdb-bot/src/bot_data/abc/known_user_repository_abc.py b/kdb-bot/src/bot_data/abc/known_user_repository_abc.py index 6a3d529e..072fba08 100644 --- a/kdb-bot/src/bot_data/abc/known_user_repository_abc.py +++ b/kdb-bot/src/bot_data/abc/known_user_repository_abc.py @@ -7,24 +7,30 @@ from bot_data.model.known_user import KnownUser class KnownUserRepositoryABC(ABC): + @abstractmethod + def __init__(self): + pass @abstractmethod - def __init__(self): pass - + def get_users(self) -> List[KnownUser]: + pass + @abstractmethod - def get_users(self) -> List[KnownUser]: pass - + def get_user_by_id(self, id: int) -> KnownUser: + pass + @abstractmethod - def get_user_by_id(self, id: int) -> KnownUser: pass - + def get_user_by_discord_id(self, discord_id: int) -> KnownUser: + pass + @abstractmethod - def get_user_by_discord_id(self, discord_id: int) -> KnownUser: pass - + def find_user_by_discord_id(self, discord_id: int) -> Optional[KnownUser]: + pass + @abstractmethod - def find_user_by_discord_id(self, discord_id: int) -> Optional[KnownUser]: pass - + def add_user(self, known_user: KnownUser): + pass + @abstractmethod - def add_user(self, known_user: KnownUser): pass - - @abstractmethod - def delete_user(self, known_user: KnownUser): pass + def delete_user(self, known_user: KnownUser): + pass diff --git a/kdb-bot/src/bot_data/abc/level_repository_abc.py b/kdb-bot/src/bot_data/abc/level_repository_abc.py index 89a2a67f..73f04b0f 100644 --- a/kdb-bot/src/bot_data/abc/level_repository_abc.py +++ b/kdb-bot/src/bot_data/abc/level_repository_abc.py @@ -7,30 +7,38 @@ from bot_data.model.level import Level class LevelRepositoryABC(ABC): + @abstractmethod + def __init__(self): + pass @abstractmethod - def __init__(self): pass - - @abstractmethod - def get_levels(self) -> List[Level]: pass - - @abstractmethod - def get_level_by_id(self, id: int) -> Level: pass + def get_levels(self) -> List[Level]: + pass @abstractmethod - def find_level_by_id(self, id: int) -> Optional[Level]: pass - + def get_level_by_id(self, id: int) -> Level: + pass + @abstractmethod - def get_levels_by_server_id(self, server_id: int) -> List[Level]: pass - + def find_level_by_id(self, id: int) -> Optional[Level]: + pass + @abstractmethod - def find_levels_by_server_id(self, server_id: int) -> Optional[List[Level]]: pass - + def get_levels_by_server_id(self, server_id: int) -> List[Level]: + pass + @abstractmethod - def add_level(self, level: Level): pass - + def find_levels_by_server_id(self, server_id: int) -> Optional[List[Level]]: + pass + @abstractmethod - def update_level(self, level: Level): pass - + def add_level(self, level: Level): + pass + @abstractmethod - def delete_level(self, level: Level): pass + def update_level(self, level: Level): + pass + + @abstractmethod + def delete_level(self, level: Level): + pass diff --git a/kdb-bot/src/bot_data/abc/migration_abc.py b/kdb-bot/src/bot_data/abc/migration_abc.py index a3ce7ddc..f6af458c 100644 --- a/kdb-bot/src/bot_data/abc/migration_abc.py +++ b/kdb-bot/src/bot_data/abc/migration_abc.py @@ -5,10 +5,13 @@ class MigrationABC(ABC): name = None @abstractmethod - def __init__(self): pass + def __init__(self): + pass @abstractmethod - def upgrade(self): pass + def upgrade(self): + pass @abstractmethod - def downgrade(self): pass + def downgrade(self): + pass diff --git a/kdb-bot/src/bot_data/abc/server_repository_abc.py b/kdb-bot/src/bot_data/abc/server_repository_abc.py index f3eea75a..9ac973fa 100644 --- a/kdb-bot/src/bot_data/abc/server_repository_abc.py +++ b/kdb-bot/src/bot_data/abc/server_repository_abc.py @@ -9,30 +9,38 @@ from bot_data.model.server import Server class ServerRepositoryABC(ABC): + @abstractmethod + def __init__(self): + pass @abstractmethod - def __init__(self): pass - - @abstractmethod - def get_servers(self) -> List[Server]: pass + def get_servers(self) -> List[Server]: + pass @abstractmethod - def get_filtered_servers(self, criteria: ServerSelectCriteria) -> FilteredResult: pass - + def get_filtered_servers(self, criteria: ServerSelectCriteria) -> FilteredResult: + pass + @abstractmethod - def get_server_by_id(self, id: int) -> Server: pass - + def get_server_by_id(self, id: int) -> Server: + pass + @abstractmethod - def get_server_by_discord_id(self, discord_id: int) -> Server: pass - + def get_server_by_discord_id(self, discord_id: int) -> Server: + pass + @abstractmethod - def find_server_by_discord_id(self, discord_id: int) -> Optional[Server]: pass - + def find_server_by_discord_id(self, discord_id: int) -> Optional[Server]: + pass + @abstractmethod - def add_server(self, server: Server): pass - + def add_server(self, server: Server): + pass + @abstractmethod - def update_server(self, server: Server): pass - + def update_server(self, server: Server): + pass + @abstractmethod - def delete_server(self, server: Server): pass \ No newline at end of file + def delete_server(self, server: Server): + pass diff --git a/kdb-bot/src/bot_data/abc/statistic_repository_abc.py b/kdb-bot/src/bot_data/abc/statistic_repository_abc.py index bf16055d..c901ba43 100644 --- a/kdb-bot/src/bot_data/abc/statistic_repository_abc.py +++ b/kdb-bot/src/bot_data/abc/statistic_repository_abc.py @@ -7,30 +7,38 @@ from bot_data.model.statistic import Statistic class StatisticRepositoryABC(ABC): + @abstractmethod + def __init__(self): + pass @abstractmethod - def __init__(self): pass + def get_statistics(self) -> List[Statistic]: + pass @abstractmethod - def get_statistics(self) -> List[Statistic]: pass + def get_statistics_by_server_id(self, server_id: int) -> List[Statistic]: + pass @abstractmethod - def get_statistics_by_server_id(self, server_id: int) -> List[Statistic]: pass + def get_statistic_by_id(self, id: int) -> Statistic: + pass @abstractmethod - def get_statistic_by_id(self, id: int) -> Statistic: pass + def get_statistic_by_name(self, name: str, server_id: int) -> Statistic: + pass @abstractmethod - def get_statistic_by_name(self, name: str, server_id: int) -> Statistic: pass + def find_statistic_by_name(self, name: str, server_id: int) -> Optional[Statistic]: + pass @abstractmethod - def find_statistic_by_name(self, name: str, server_id: int) -> Optional[Statistic]: pass + def add_statistic(self, statistic: Statistic): + pass @abstractmethod - def add_statistic(self, statistic: Statistic): pass + def update_statistic(self, statistic: Statistic): + pass @abstractmethod - def update_statistic(self, statistic: Statistic): pass - - @abstractmethod - def delete_statistic(self, statistic: Statistic): pass + def delete_statistic(self, statistic: Statistic): + pass diff --git a/kdb-bot/src/bot_data/abc/user_joined_server_repository_abc.py b/kdb-bot/src/bot_data/abc/user_joined_server_repository_abc.py index 8c96444a..2b8dcc5f 100644 --- a/kdb-bot/src/bot_data/abc/user_joined_server_repository_abc.py +++ b/kdb-bot/src/bot_data/abc/user_joined_server_repository_abc.py @@ -6,30 +6,38 @@ from bot_data.model.user_joined_server import UserJoinedServer class UserJoinedServerRepositoryABC(ABC): + @abstractmethod + def __init__(self): + pass @abstractmethod - def __init__(self): pass - + def get_user_joined_servers(self) -> List[UserJoinedServer]: + pass + @abstractmethod - def get_user_joined_servers(self) -> List[UserJoinedServer]: pass - + def get_user_joined_server_by_id(self, id: int) -> UserJoinedServer: + pass + @abstractmethod - def get_user_joined_server_by_id(self, id: int) -> UserJoinedServer: pass - + def get_user_joined_servers_by_user_id(self, user_id: int) -> list[UserJoinedServer]: + pass + @abstractmethod - def get_user_joined_servers_by_user_id(self, user_id: int) -> list[UserJoinedServer]: pass - + def get_active_user_joined_server_by_user_id(self, user_id: int) -> UserJoinedServer: + pass + @abstractmethod - def get_active_user_joined_server_by_user_id(self, user_id: int) -> UserJoinedServer: pass - + def find_active_user_joined_server_by_user_id(self, user_id: int) -> Optional[UserJoinedServer]: + pass + @abstractmethod - def find_active_user_joined_server_by_user_id(self, user_id: int) -> Optional[UserJoinedServer]: pass - + def add_user_joined_server(self, user_joined_server: UserJoinedServer): + pass + @abstractmethod - def add_user_joined_server(self, user_joined_server: UserJoinedServer): pass - + def update_user_joined_server(self, user_joined_server: UserJoinedServer): + pass + @abstractmethod - def update_user_joined_server(self, user_joined_server: UserJoinedServer): pass - - @abstractmethod - def delete_user_joined_server(self, user_joined_server: UserJoinedServer): pass + def delete_user_joined_server(self, user_joined_server: UserJoinedServer): + pass diff --git a/kdb-bot/src/bot_data/abc/user_joined_voice_channel_abc.py b/kdb-bot/src/bot_data/abc/user_joined_voice_channel_repository_abc.py similarity index 68% rename from kdb-bot/src/bot_data/abc/user_joined_voice_channel_abc.py rename to kdb-bot/src/bot_data/abc/user_joined_voice_channel_repository_abc.py index b1084da8..7ce7e01a 100644 --- a/kdb-bot/src/bot_data/abc/user_joined_voice_channel_abc.py +++ b/kdb-bot/src/bot_data/abc/user_joined_voice_channel_repository_abc.py @@ -4,37 +4,48 @@ from typing import Optional from cpl_query.extension import List from bot_data.model.user_joined_voice_channel import UserJoinedVoiceChannel + class UserJoinedVoiceChannelRepositoryABC(ABC): + @abstractmethod + def __init__(self): + pass @abstractmethod - def __init__(self): pass - - @abstractmethod - def get_user_joined_voice_channels(self) -> List[UserJoinedVoiceChannel]: pass - - @abstractmethod - def get_user_joined_voice_channel_by_id(self, id: int) -> UserJoinedVoiceChannel: pass - - @abstractmethod - def get_user_joined_voice_channels_by_user_id(self, user_id: int) -> List[UserJoinedVoiceChannel]: pass - - @abstractmethod - def get_active_user_joined_voice_channel_by_user_id(self, user_id: int) -> UserJoinedVoiceChannel: pass - - @abstractmethod - def find_active_user_joined_voice_channel_by_user_id(self, user_id: int) -> Optional[UserJoinedVoiceChannel]: pass + def get_user_joined_voice_channels(self) -> List[UserJoinedVoiceChannel]: + pass @abstractmethod - def find_active_user_joined_voice_channels_by_user_id(self, user_id: int) -> List[Optional[UserJoinedVoiceChannel]]: pass - - @abstractmethod - def add_user_joined_voice_channel(self, user_joined_voice_channel: UserJoinedVoiceChannel): pass - - @abstractmethod - def update_user_joined_voice_channel(self, user_joined_voice_channel: UserJoinedVoiceChannel): pass - - @abstractmethod - def delete_user_joined_voice_channel(self, user_joined_voice_channel: UserJoinedVoiceChannel): pass + def get_user_joined_voice_channel_by_id(self, id: int) -> UserJoinedVoiceChannel: + pass @abstractmethod - def delete_user_joined_voice_channel_by_user_id(self, user_id: int): pass + def get_user_joined_voice_channels_by_user_id(self, user_id: int) -> List[UserJoinedVoiceChannel]: + pass + + @abstractmethod + def get_active_user_joined_voice_channel_by_user_id(self, user_id: int) -> UserJoinedVoiceChannel: + pass + + @abstractmethod + def find_active_user_joined_voice_channel_by_user_id(self, user_id: int) -> Optional[UserJoinedVoiceChannel]: + pass + + @abstractmethod + def find_active_user_joined_voice_channels_by_user_id(self, user_id: int) -> List[Optional[UserJoinedVoiceChannel]]: + pass + + @abstractmethod + def add_user_joined_voice_channel(self, user_joined_voice_channel: UserJoinedVoiceChannel): + pass + + @abstractmethod + def update_user_joined_voice_channel(self, user_joined_voice_channel: UserJoinedVoiceChannel): + pass + + @abstractmethod + def delete_user_joined_voice_channel(self, user_joined_voice_channel: UserJoinedVoiceChannel): + pass + + @abstractmethod + def delete_user_joined_voice_channel_by_user_id(self, user_id: int): + pass diff --git a/kdb-bot/src/bot_data/abc/user_message_count_per_hour_repository_abc.py b/kdb-bot/src/bot_data/abc/user_message_count_per_hour_repository_abc.py new file mode 100644 index 00000000..59108387 --- /dev/null +++ b/kdb-bot/src/bot_data/abc/user_message_count_per_hour_repository_abc.py @@ -0,0 +1,49 @@ +from abc import ABC, abstractmethod +from datetime import datetime +from typing import Optional + +from cpl_query.extension import List + +from bot_data.model.user_message_count_per_hour import UserMessageCountPerHour + + +class UserMessageCountPerHourRepositoryABC(ABC): + @abstractmethod + def __init__(self): + pass + + @abstractmethod + def get_user_message_count_per_hours(self) -> List[UserMessageCountPerHour]: + pass + + @abstractmethod + def find_user_message_count_per_hour_by_user_id(self, user_id: int) -> Optional[UserMessageCountPerHour]: + pass + + @abstractmethod + def get_user_message_count_per_hour_by_user_id_and_date( + self, user_id: int, date: datetime + ) -> Optional[UserMessageCountPerHour]: + pass + + @abstractmethod + def find_user_message_count_per_hour_by_user_id_and_date( + self, user_id: int, date: datetime + ) -> Optional[UserMessageCountPerHour]: + pass + + @abstractmethod + def add_user_message_count_per_hour(self, umcph: UserMessageCountPerHour): + pass + + @abstractmethod + def update_user_message_count_per_hour(self, umcph: UserMessageCountPerHour): + pass + + @abstractmethod + def delete_user_message_count_per_hour(self, umcph: UserMessageCountPerHour): + pass + + @abstractmethod + def delete_user_message_count_per_hour_by_user_id(self, user_id: int): + pass diff --git a/kdb-bot/src/bot_data/abc/user_repository_abc.py b/kdb-bot/src/bot_data/abc/user_repository_abc.py index 12878b6f..c40f20e5 100644 --- a/kdb-bot/src/bot_data/abc/user_repository_abc.py +++ b/kdb-bot/src/bot_data/abc/user_repository_abc.py @@ -7,33 +7,42 @@ from bot_data.model.user import User class UserRepositoryABC(ABC): + @abstractmethod + def __init__(self): + pass @abstractmethod - def __init__(self): pass - - @abstractmethod - def get_users(self) -> List[User]: pass - - @abstractmethod - def get_user_by_id(self, id: int) -> User: pass + def get_users(self) -> List[User]: + pass @abstractmethod - def find_user_by_id(self, id: int) -> Optional[User]: pass - + def get_user_by_id(self, id: int) -> User: + pass + @abstractmethod - def get_users_by_discord_id(self, discord_id: int) -> List[User]: pass - + def find_user_by_id(self, id: int) -> Optional[User]: + pass + @abstractmethod - def get_user_by_discord_id_and_server_id(self, discord_id: int, server_id: int) -> User: pass - + def get_users_by_discord_id(self, discord_id: int) -> List[User]: + pass + @abstractmethod - def find_user_by_discord_id_and_server_id(self, discord_id: int, server_id: int) -> Optional[User]: pass - + def get_user_by_discord_id_and_server_id(self, discord_id: int, server_id: int) -> User: + pass + @abstractmethod - def add_user(self, user: User): pass - + def find_user_by_discord_id_and_server_id(self, discord_id: int, server_id: int) -> Optional[User]: + pass + @abstractmethod - def update_user(self, user: User): pass - + def add_user(self, user: User): + pass + @abstractmethod - def delete_user(self, user: User): pass + def update_user(self, user: User): + pass + + @abstractmethod + def delete_user(self, user: User): + pass diff --git a/kdb-bot/src/bot_data/bot-data.json b/kdb-bot/src/bot_data/bot-data.json index e13602ad..4cfedaf6 100644 --- a/kdb-bot/src/bot_data/bot-data.json +++ b/kdb-bot/src/bot_data/bot-data.json @@ -4,7 +4,7 @@ "Version": { "Major": "0", "Minor": "3", - "Micro": "0" + "Micro": "1" }, "Author": "Sven Heidemann", "AuthorEmail": "sven.heidemann@sh-edraft.de", diff --git a/kdb-bot/src/bot_data/data_module.py b/kdb-bot/src/bot_data/data_module.py index e32d8039..87152541 100644 --- a/kdb-bot/src/bot_data/data_module.py +++ b/kdb-bot/src/bot_data/data_module.py @@ -13,7 +13,12 @@ from bot_data.abc.level_repository_abc import LevelRepositoryABC from bot_data.abc.server_repository_abc import ServerRepositoryABC from bot_data.abc.statistic_repository_abc import StatisticRepositoryABC 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_joined_voice_channel_repository_abc import ( + UserJoinedVoiceChannelRepositoryABC, +) +from bot_data.abc.user_message_count_per_hour_repository_abc import ( + UserMessageCountPerHourRepositoryABC, +) from bot_data.abc.user_repository_abc import UserRepositoryABC from bot_data.service.auth_user_repository_service import AuthUserRepositoryService from bot_data.service.auto_role_repository_service import AutoRoleRepositoryService @@ -23,13 +28,19 @@ from bot_data.service.level_repository_service import LevelRepositoryService from bot_data.service.seeder_service import SeederService from bot_data.service.server_repository_service import ServerRepositoryService from bot_data.service.statistic_repository_service import StatisticRepositoryService -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_joined_server_repository_service import ( + UserJoinedServerRepositoryService, +) +from bot_data.service.user_joined_voice_channel_repository_service import ( + UserJoinedVoiceChannelRepositoryService, +) +from bot_data.service.user_message_count_per_hour_repository_service import ( + UserMessageCountPerHourRepositoryService, +) from bot_data.service.user_repository_service import UserRepositoryService class DataModule(ModuleABC): - def __init__(self, dc: DiscordCollectionABC): ModuleABC.__init__(self, dc, FeatureFlagsEnum.data_module) @@ -47,5 +58,9 @@ class DataModule(ModuleABC): services.add_transient(AutoRoleRepositoryABC, AutoRoleRepositoryService) services.add_transient(LevelRepositoryABC, LevelRepositoryService) services.add_transient(StatisticRepositoryABC, StatisticRepositoryService) + services.add_transient( + UserMessageCountPerHourRepositoryABC, + UserMessageCountPerHourRepositoryService, + ) services.add_transient(SeederService) diff --git a/kdb-bot/src/bot_data/db_context.py b/kdb-bot/src/bot_data/db_context.py index 0f867228..6e208ed9 100644 --- a/kdb-bot/src/bot_data/db_context.py +++ b/kdb-bot/src/bot_data/db_context.py @@ -5,7 +5,6 @@ from bot_core.logging.database_logger import DatabaseLogger class DBContext(DatabaseContext): - def __init__(self, logger: DatabaseLogger): self._logger = logger @@ -32,5 +31,5 @@ class DBContext(DatabaseContext): try: return super(DBContext, self).select(statement) except Exception as e: - self._logger.error(__name__, f'Database error caused by {statement}', e) + self._logger.error(__name__, f"Database error caused by {statement}", e) return [] diff --git a/kdb-bot/src/bot_data/filtered_result.py b/kdb-bot/src/bot_data/filtered_result.py index 8bdf90a3..f61e7a1e 100644 --- a/kdb-bot/src/bot_data/filtered_result.py +++ b/kdb-bot/src/bot_data/filtered_result.py @@ -2,7 +2,6 @@ from cpl_query.extension import List class FilteredResult: - def __init__(self, result: List = None, total_count: int = 0): self._result = [] if result is None else result self._total_count = total_count diff --git a/kdb-bot/src/bot_data/migration/__init__.py b/kdb-bot/src/bot_data/migration/__init__.py index b8443711..fd2eb41f 100644 --- a/kdb-bot/src/bot_data/migration/__init__.py +++ b/kdb-bot/src/bot_data/migration/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'bot_data.migration' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "bot_data.migration" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/bot_data/migration/api_migration.py b/kdb-bot/src/bot_data/migration/api_migration.py index 8f59906a..e67eb53f 100644 --- a/kdb-bot/src/bot_data/migration/api_migration.py +++ b/kdb-bot/src/bot_data/migration/api_migration.py @@ -4,7 +4,7 @@ from bot_data.db_context import DBContext class ApiMigration(MigrationABC): - name = '0.3_ApiMigration' + name = "0.3_ApiMigration" def __init__(self, logger: DatabaseLogger, db: DBContext): MigrationABC.__init__(self) @@ -13,10 +13,11 @@ class ApiMigration(MigrationABC): self._cursor = db.cursor def upgrade(self): - self._logger.debug(__name__, 'Running upgrade') + self._logger.debug(__name__, "Running upgrade") self._cursor.execute( - str(f""" + str( + f""" CREATE TABLE IF NOT EXISTS `AuthUsers` ( `Id` BIGINT NOT NULL AUTO_INCREMENT, `FirstName` VARCHAR(255), @@ -34,11 +35,13 @@ class ApiMigration(MigrationABC): `LastModifiedAt` DATETIME(6) NOT NULL, PRIMARY KEY(`Id`) ); - """) + """ + ) ) self._cursor.execute( - str(f""" + str( + f""" CREATE TABLE IF NOT EXISTS `AuthUserUsersRelations`( `Id` BIGINT NOT NULL AUTO_INCREMENT, `AuthUserId` BIGINT DEFAULT NULL, @@ -49,10 +52,10 @@ class ApiMigration(MigrationABC): FOREIGN KEY (`AuthUserId`) REFERENCES `AuthUsers`(`Id`), FOREIGN KEY (`UserId`) REFERENCES `Users`(`UserId`) ); - """) + """ + ) ) def downgrade(self): - self._cursor.execute('DROP TABLE `AuthUsers`;') - self._cursor.execute('DROP TABLE `AuthUserUsersRelations`;') - + self._cursor.execute("DROP TABLE `AuthUsers`;") + self._cursor.execute("DROP TABLE `AuthUserUsersRelations`;") diff --git a/kdb-bot/src/bot_data/migration/auto_role_fix1_migration.py b/kdb-bot/src/bot_data/migration/auto_role_fix1_migration.py index fd03325e..7a5766c2 100644 --- a/kdb-bot/src/bot_data/migration/auto_role_fix1_migration.py +++ b/kdb-bot/src/bot_data/migration/auto_role_fix1_migration.py @@ -4,7 +4,7 @@ from bot_data.db_context import DBContext class AutoRoleFix1Migration(MigrationABC): - name = '0.3.0_AutoRoleMigration' + name = "0.3.0_AutoRoleMigration" def __init__(self, logger: DatabaseLogger, db: DBContext): MigrationABC.__init__(self) @@ -13,17 +13,21 @@ class AutoRoleFix1Migration(MigrationABC): self._cursor = db.cursor def upgrade(self): - self._logger.debug(__name__, 'Running upgrade') + self._logger.debug(__name__, "Running upgrade") self._cursor.execute( - str(f""" + str( + f""" ALTER TABLE AutoRoles ADD DiscordChannelId BIGINT NOT NULL AFTER ServerId; - """) + """ + ) ) def downgrade(self): self._cursor.execute( - str(f""" + str( + f""" ALTER TABLE AutoRoles DROP COLUMN DiscordChannelId; - """) + """ + ) ) diff --git a/kdb-bot/src/bot_data/migration/auto_role_migration.py b/kdb-bot/src/bot_data/migration/auto_role_migration.py index d46fb363..4b8e0090 100644 --- a/kdb-bot/src/bot_data/migration/auto_role_migration.py +++ b/kdb-bot/src/bot_data/migration/auto_role_migration.py @@ -4,7 +4,7 @@ from bot_data.db_context import DBContext class AutoRoleMigration(MigrationABC): - name = '0.2.1_AutoRoleMigration' + name = "0.2.1_AutoRoleMigration" def __init__(self, logger: DatabaseLogger, db: DBContext): MigrationABC.__init__(self) @@ -13,10 +13,11 @@ class AutoRoleMigration(MigrationABC): self._cursor = db.cursor def upgrade(self): - self._logger.debug(__name__, 'Running upgrade') + self._logger.debug(__name__, "Running upgrade") self._cursor.execute( - str(f""" + str( + f""" CREATE TABLE IF NOT EXISTS `AutoRoles` ( `AutoRoleId` BIGINT NOT NULL AUTO_INCREMENT, `ServerId` BIGINT, @@ -26,11 +27,13 @@ class AutoRoleMigration(MigrationABC): PRIMARY KEY(`AutoRoleId`), FOREIGN KEY (`ServerId`) REFERENCES `Servers`(`ServerId`) ); - """) + """ + ) ) self._cursor.execute( - str(f""" + str( + f""" CREATE TABLE IF NOT EXISTS `AutoRoleRules` ( `AutoRoleRuleId` BIGINT NOT NULL AUTO_INCREMENT, `AutoRoleId` BIGINT, @@ -41,9 +44,10 @@ class AutoRoleMigration(MigrationABC): PRIMARY KEY(`AutoRoleRuleId`), FOREIGN KEY (`AutoRoleId`) REFERENCES `AutoRoles`(`AutoRoleId`) ); - """) + """ + ) ) def downgrade(self): - self._cursor.execute('DROP TABLE `AutoRole`;') - self._cursor.execute('DROP TABLE `AutoRoleRules`;') + self._cursor.execute("DROP TABLE `AutoRole`;") + self._cursor.execute("DROP TABLE `AutoRoleRules`;") diff --git a/kdb-bot/src/bot_data/migration/initial_migration.py b/kdb-bot/src/bot_data/migration/initial_migration.py index 54c2ae8f..48551dbd 100644 --- a/kdb-bot/src/bot_data/migration/initial_migration.py +++ b/kdb-bot/src/bot_data/migration/initial_migration.py @@ -4,7 +4,7 @@ from bot_data.db_context import DBContext class InitialMigration(MigrationABC): - name = '0.1_InitialMigration' + name = "0.1_InitialMigration" def __init__(self, logger: DatabaseLogger, db: DBContext): MigrationABC.__init__(self) @@ -13,21 +13,24 @@ class InitialMigration(MigrationABC): self._cursor = db.cursor def upgrade(self): - self._logger.debug(__name__, 'Running upgrade') + self._logger.debug(__name__, "Running upgrade") self._cursor.execute( - str(f""" + str( + f""" CREATE TABLE IF NOT EXISTS `MigrationHistory` ( `MigrationId` VARCHAR(255), `CreatedAt` DATETIME(6), `LastModifiedAt` DATETIME(6), PRIMARY KEY(`MigrationId`) ); - """) + """ + ) ) self._cursor.execute( - str(f""" + str( + f""" CREATE TABLE IF NOT EXISTS `Servers` ( `ServerId` BIGINT NOT NULL AUTO_INCREMENT, `DiscordServerId` BIGINT NOT NULL, @@ -35,11 +38,13 @@ class InitialMigration(MigrationABC): `LastModifiedAt` DATETIME(6), PRIMARY KEY(`ServerId`) ); - """) + """ + ) ) self._cursor.execute( - str(f""" + str( + f""" CREATE TABLE IF NOT EXISTS `Users` ( `UserId` BIGINT NOT NULL AUTO_INCREMENT, `DiscordId` BIGINT NOT NULL, @@ -50,11 +55,13 @@ class InitialMigration(MigrationABC): FOREIGN KEY (`ServerId`) REFERENCES Servers(`ServerId`), PRIMARY KEY(`UserId`) ); - """) + """ + ) ) self._cursor.execute( - str(f""" + str( + f""" CREATE TABLE IF NOT EXISTS `Clients` ( `ClientId` BIGINT NOT NULL AUTO_INCREMENT, `DiscordClientId` BIGINT NOT NULL, @@ -69,11 +76,13 @@ class InitialMigration(MigrationABC): FOREIGN KEY (`ServerId`) REFERENCES Servers(`ServerId`), PRIMARY KEY(`ClientId`) ); - """) + """ + ) ) self._cursor.execute( - str(f""" + str( + f""" CREATE TABLE IF NOT EXISTS `KnownUsers` ( `KnownUserId` BIGINT NOT NULL AUTO_INCREMENT, `DiscordId` BIGINT NOT NULL, @@ -81,11 +90,13 @@ class InitialMigration(MigrationABC): `LastModifiedAt` DATETIME(6), PRIMARY KEY(`KnownUserId`) ); - """) + """ + ) ) self._cursor.execute( - str(f""" + str( + f""" CREATE TABLE IF NOT EXISTS `UserJoinedServers` ( `JoinId` BIGINT NOT NULL AUTO_INCREMENT, `UserId` BIGINT NOT NULL, @@ -96,11 +107,13 @@ class InitialMigration(MigrationABC): FOREIGN KEY (`UserId`) REFERENCES Users(`UserId`), PRIMARY KEY(`JoinId`) ); - """) + """ + ) ) self._cursor.execute( - str(f""" + str( + f""" CREATE TABLE IF NOT EXISTS `UserJoinedVoiceChannel` ( `JoinId` BIGINT NOT NULL AUTO_INCREMENT, `UserId` BIGINT NOT NULL, @@ -112,13 +125,14 @@ class InitialMigration(MigrationABC): FOREIGN KEY (`UserId`) REFERENCES Users(`UserId`), PRIMARY KEY(`JoinId`) ); - """) + """ + ) ) def downgrade(self): - self._cursor.execute('DROP TABLE `Servers`;') - self._cursor.execute('DROP TABLE `Users`;') - self._cursor.execute('DROP TABLE `Clients`;') - self._cursor.execute('DROP TABLE `KnownUsers`;') - self._cursor.execute('DROP TABLE `UserJoinedServers`;') - self._cursor.execute('DROP TABLE `UserJoinedVoiceChannel`;') + self._cursor.execute("DROP TABLE `Servers`;") + self._cursor.execute("DROP TABLE `Users`;") + self._cursor.execute("DROP TABLE `Clients`;") + self._cursor.execute("DROP TABLE `KnownUsers`;") + self._cursor.execute("DROP TABLE `UserJoinedServers`;") + self._cursor.execute("DROP TABLE `UserJoinedVoiceChannel`;") diff --git a/kdb-bot/src/bot_data/migration/level_migration.py b/kdb-bot/src/bot_data/migration/level_migration.py index 5b1dbc0f..20ad3c7b 100644 --- a/kdb-bot/src/bot_data/migration/level_migration.py +++ b/kdb-bot/src/bot_data/migration/level_migration.py @@ -4,7 +4,7 @@ from bot_data.db_context import DBContext class LevelMigration(MigrationABC): - name = '0.3_LevelMigration' + name = "0.3_LevelMigration" def __init__(self, logger: DatabaseLogger, db: DBContext): MigrationABC.__init__(self) @@ -13,10 +13,11 @@ class LevelMigration(MigrationABC): self._cursor = db.cursor def upgrade(self): - self._logger.debug(__name__, 'Running upgrade') + self._logger.debug(__name__, "Running upgrade") self._cursor.execute( - str(f""" + str( + f""" CREATE TABLE IF NOT EXISTS `Levels` ( `Id` BIGINT NOT NULL AUTO_INCREMENT, `Name` VARCHAR(255) NOT NULL, @@ -29,9 +30,9 @@ class LevelMigration(MigrationABC): PRIMARY KEY(`Id`), FOREIGN KEY (`ServerId`) REFERENCES `Servers`(`ServerId`) ); - """) + """ + ) ) def downgrade(self): - self._cursor.execute('DROP TABLE `Levels`;') - + self._cursor.execute("DROP TABLE `Levels`;") diff --git a/kdb-bot/src/bot_data/migration/stats_migration.py b/kdb-bot/src/bot_data/migration/stats_migration.py index 92ba17ab..c28eeda9 100644 --- a/kdb-bot/src/bot_data/migration/stats_migration.py +++ b/kdb-bot/src/bot_data/migration/stats_migration.py @@ -4,7 +4,7 @@ from bot_data.db_context import DBContext class StatsMigration(MigrationABC): - name = '0.3_StatsMigration' + name = "0.3_StatsMigration" def __init__(self, logger: DatabaseLogger, db: DBContext): MigrationABC.__init__(self) @@ -13,10 +13,11 @@ class StatsMigration(MigrationABC): self._cursor = db.cursor def upgrade(self): - self._logger.debug(__name__, 'Running upgrade') + self._logger.debug(__name__, "Running upgrade") self._cursor.execute( - str(f""" + str( + f""" CREATE TABLE IF NOT EXISTS `Statistics` ( `Id` BIGINT NOT NULL AUTO_INCREMENT, `Name` VARCHAR(255) NOT NULL, @@ -28,9 +29,9 @@ class StatsMigration(MigrationABC): PRIMARY KEY(`Id`), FOREIGN KEY (`ServerId`) REFERENCES `Servers`(`ServerId`) ); - """) + """ + ) ) def downgrade(self): - self._cursor.execute('DROP TABLE `Statistics`;') - + self._cursor.execute("DROP TABLE `Statistics`;") diff --git a/kdb-bot/src/bot_data/migration/user_message_count_per_hour_migration.py b/kdb-bot/src/bot_data/migration/user_message_count_per_hour_migration.py new file mode 100644 index 00000000..c0c4199a --- /dev/null +++ b/kdb-bot/src/bot_data/migration/user_message_count_per_hour_migration.py @@ -0,0 +1,37 @@ +from bot_core.logging.database_logger import DatabaseLogger +from bot_data.abc.migration_abc import MigrationABC +from bot_data.db_context import DBContext + + +class UserMessageCountPerHourMigration(MigrationABC): + name = "0.3.1_UserMessageCountPerHourMigration" + + def __init__(self, logger: DatabaseLogger, db: DBContext): + MigrationABC.__init__(self) + self._logger = logger + self._db = db + self._cursor = db.cursor + + def upgrade(self): + self._logger.debug(__name__, "Running upgrade") + + self._cursor.execute( + str( + f""" + CREATE TABLE IF NOT EXISTS `UserMessageCountPerHour` ( + `Id` BIGINT NOT NULL AUTO_INCREMENT, + `Date` DATETIME(6) NOT NULL, + `Hour` BIGINT, + `XPCount` BIGINT, + `UserId` BIGINT, + `CreatedAt` DATETIME(6), + `LastModifiedAt` DATETIME(6), + PRIMARY KEY(`Id`), + FOREIGN KEY (`UserId`) REFERENCES `Users`(`UserId`) + ); + """ + ) + ) + + def downgrade(self): + self._cursor.execute("DROP TABLE `UserMessageCountPerHour`;") diff --git a/kdb-bot/src/bot_data/model/__init__.py b/kdb-bot/src/bot_data/model/__init__.py index ba35160c..51f3b8a6 100644 --- a/kdb-bot/src/bot_data/model/__init__.py +++ b/kdb-bot/src/bot_data/model/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'bot_data.model' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "bot_data.model" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/bot_data/model/auth_user.py b/kdb-bot/src/bot_data/model/auth_user.py index 26298666..7a91373d 100644 --- a/kdb-bot/src/bot_data/model/auth_user.py +++ b/kdb-bot/src/bot_data/model/auth_user.py @@ -10,24 +10,23 @@ from bot_data.model.user import User class AuthUser(TableABC): - def __init__( - self, - first_name: str, - last_name: str, - email: str, - password: str, - password_salt: Optional[str], - refresh_token: Optional[str], - confirmation_id: Optional[str], - forgot_password_id: Optional[str], - oauth_id: Optional[str], - refresh_token_expire_time: datetime, - auth_role: AuthRoleEnum, - created_at: datetime = None, - modified_at: datetime = None, - auth_user_id=0, - users: List[User] = None + self, + first_name: str, + last_name: str, + email: str, + password: str, + password_salt: Optional[str], + refresh_token: Optional[str], + confirmation_id: Optional[str], + forgot_password_id: Optional[str], + oauth_id: Optional[str], + refresh_token_expire_time: datetime, + auth_role: AuthRoleEnum, + created_at: datetime = None, + modified_at: datetime = None, + auth_user_id=0, + users: List[User] = None, ): self._auth_user_id = auth_user_id self._first_name = first_name @@ -152,48 +151,61 @@ class AuthUser(TableABC): @staticmethod def get_select_all_string() -> str: - return str(f""" + return str( + f""" SELECT * FROM `AuthUsers`; - """) + """ + ) @staticmethod def get_select_by_id_string(id: int) -> str: - return str(f""" + return str( + f""" SELECT * FROM `AuthUsers` WHERE `Id` = {id}; - """) + """ + ) @staticmethod def get_select_by_email_string(email: str) -> str: - return str(f""" + return str( + f""" SELECT * FROM `AuthUsers` WHERE `EMail` = '{email}'; - """) + """ + ) @staticmethod def get_select_by_confirmation_id_string(id: str) -> str: - return str(f""" + return str( + f""" SELECT * FROM `AuthUsers` WHERE `ConfirmationId` = '{id}'; - """) + """ + ) @staticmethod def get_select_by_forgot_password_id_string(id: str) -> str: - return str(f""" + return str( + f""" SELECT * FROM `AuthUsers` WHERE `ForgotPasswordId` = '{id}'; - """) + """ + ) def get_select_user_id_from_relations(self) -> str: - return str(f""" + return str( + f""" SELECT `UserId` FROM `AuthUserUsersRelations` WHERE `AuthUserId` = {self._auth_user_id}; - """) + """ + ) @property def insert_string(self) -> str: - return str(f""" + return str( + f""" INSERT INTO `AuthUsers` ( `Id`, `FirstName`, @@ -225,11 +237,13 @@ class AuthUser(TableABC): '{self._created_at}', '{self._modified_at}' ) - """) + """ + ) @property def udpate_string(self) -> str: - return str(f""" + return str( + f""" UPDATE `AuthUsers` SET `FirstName` = '{self._first_name}', `LastName` = '{self._last_name}', @@ -244,11 +258,14 @@ class AuthUser(TableABC): `AuthRole` = {self._auth_role_id.value}, `LastModifiedAt` = '{self._modified_at}' WHERE `AuthUsers`.`Id` = {self._auth_user_id}; - """) + """ + ) @property def delete_string(self) -> str: - return str(f""" + return str( + f""" DELETE FROM `AuthUsers` WHERE `Id` = {self._auth_user_id}; - """) + """ + ) diff --git a/kdb-bot/src/bot_data/model/auth_user_users_relation.py b/kdb-bot/src/bot_data/model/auth_user_users_relation.py index e40e53b0..1ef7e35d 100644 --- a/kdb-bot/src/bot_data/model/auth_user_users_relation.py +++ b/kdb-bot/src/bot_data/model/auth_user_users_relation.py @@ -7,8 +7,13 @@ from bot_data.model.user import User class AuthUserUsersRelation(TableABC): - - def __init__(self, auth_user: AuthUser, user: User, created_at: datetime = None, modified_at: datetime = None): + def __init__( + self, + auth_user: AuthUser, + user: User, + created_at: datetime = None, + modified_at: datetime = None, + ): self._auth_user = auth_user self._user = user @@ -34,27 +39,34 @@ class AuthUserUsersRelation(TableABC): @staticmethod def get_select_all_string() -> str: - return str(f""" + return str( + f""" SELECT * FROM `AuthUserUsersRelations`; - """) + """ + ) @staticmethod def get_select_by_auth_user_id_string(id: int) -> str: - return str(f""" + return str( + f""" SELECT * FROM `AuthUserUsersRelations` WHERE `AuthUserId` = {id}; - """) + """ + ) @staticmethod def get_select_by_user_id_string(id: int) -> str: - return str(f""" + return str( + f""" SELECT * FROM `AuthUserUsersRelations` WHERE `UserId` = {id}; - """) + """ + ) @property def insert_string(self) -> str: - return str(f""" + return str( + f""" INSERT INTO `AuthUserUsersRelations` ( `AuthUserId`, `UserId`, `CreatedAt`, `LastModifiedAt` ) VALUES ( @@ -63,23 +75,28 @@ class AuthUserUsersRelation(TableABC): '{self._created_at}', '{self._modified_at}' ); - """) + """ + ) @property def udpate_string(self) -> str: - return str(f""" + return str( + f""" UPDATE `AuthUserUsersRelations` SET `AuthUserId` = '{self._auth_user.id}',, `UserId` = '{self._user.user_id}' `LastModifiedAt` = '{self._modified_at}' WHERE `AuthUserId` = {self._auth_user.id} AND `UserId` = {self._user.user_id}; - """) + """ + ) @property def delete_string(self) -> str: - return str(f""" + return str( + f""" DELETE FROM `AuthUserUsersRelations` WHERE `AuthUserId` = {self._auth_user.id} AND `UserId` = {self._user.user_id}; - """) + """ + ) diff --git a/kdb-bot/src/bot_data/model/auto_role.py b/kdb-bot/src/bot_data/model/auto_role.py index 54d108c5..dfef0155 100644 --- a/kdb-bot/src/bot_data/model/auto_role.py +++ b/kdb-bot/src/bot_data/model/auto_role.py @@ -5,13 +5,20 @@ from cpl_core.database import TableABC class AutoRole(TableABC): - - def __init__(self, server_id: int, dc_channel_id: int, dc_message_id: int, created_at: datetime=None, modified_at: datetime=None, id=0): + def __init__( + self, + server_id: int, + dc_channel_id: int, + dc_message_id: int, + created_at: datetime = None, + modified_at: datetime = None, + id=0, + ): self._auto_role_id = id self._server_id = server_id self._discord_channel_id = dc_channel_id self._discord_message_id = dc_message_id - + TableABC.__init__(self) self._created_at = created_at if created_at is not None else self._created_at self._modified_at = modified_at if modified_at is not None else self._modified_at @@ -34,34 +41,43 @@ class AutoRole(TableABC): @staticmethod def get_select_all_string() -> str: - return str(f""" + return str( + f""" SELECT * FROM `AutoRoles`; - """) - + """ + ) + @staticmethod def get_select_by_id_string(id: int) -> str: - return str(f""" + return str( + f""" SELECT * FROM `AutoRoles` WHERE `AutoRoleId` = {id}; - """) - + """ + ) + @staticmethod def get_select_by_server_id_string(id: int) -> str: - return str(f""" + return str( + f""" SELECT * FROM `AutoRoles` WHERE `ServerId` = {id}; - """) + """ + ) @staticmethod def get_select_by_message_id_string(id: int) -> str: - return str(f""" + return str( + f""" SELECT * FROM `AutoRoles` WHERE `DiscordMessageId` = {id}; - """) + """ + ) @property def insert_string(self) -> str: - return str(f""" + return str( + f""" INSERT INTO `AutoRoles` ( `ServerId`, `DiscordChannelId`, `DiscordMessageId`, `CreatedAt`, `LastModifiedAt` ) VALUES ( @@ -71,22 +87,27 @@ class AutoRole(TableABC): '{self._created_at}', '{self._modified_at}' ); - """) + """ + ) @property def udpate_string(self) -> str: - return str(f""" + return str( + f""" UPDATE `AutoRoles` SET `ServerId` = {self._server_id}, `DiscordChannelId` = {self._discord_channel_id}, `DiscordMessageId` = {self._discord_message_id}, `LastModifiedAt` = '{self._modified_at}' WHERE `AutoRoleId` = {self._auto_role_id}; - """) + """ + ) @property def delete_string(self) -> str: - return str(f""" + return str( + f""" DELETE FROM `AutoRoles` WHERE `AutoRoleId` = {self._auto_role_id}; - """) + """ + ) diff --git a/kdb-bot/src/bot_data/model/auto_role_rule.py b/kdb-bot/src/bot_data/model/auto_role_rule.py index 38f40b3c..01d45ebe 100644 --- a/kdb-bot/src/bot_data/model/auto_role_rule.py +++ b/kdb-bot/src/bot_data/model/auto_role_rule.py @@ -5,8 +5,15 @@ from cpl_core.database import TableABC class AutoRoleRule(TableABC): - - def __init__(self, auto_role_id: int, discord_emoji_name: str, discord_role_id: int, created_at: datetime=None, modified_at: datetime=None, id=0): + def __init__( + self, + auto_role_id: int, + discord_emoji_name: str, + discord_role_id: int, + created_at: datetime = None, + modified_at: datetime = None, + id=0, + ): self._auto_role_rule_id = id self._auto_role_id = auto_role_id self._discord_emoji_name = discord_emoji_name @@ -34,27 +41,34 @@ class AutoRoleRule(TableABC): @staticmethod def get_select_all_string() -> str: - return str(f""" + return str( + f""" SELECT * FROM `AutoRoleRules`; - """) + """ + ) @staticmethod def get_select_by_id_string(id: int) -> str: - return str(f""" + return str( + f""" SELECT * FROM `AutoRoleRules` WHERE `AutoRoleRuleId` = {id}; - """) + """ + ) @staticmethod def get_select_by_auto_role_id_string(id: int) -> str: - return str(f""" + return str( + f""" SELECT * FROM `AutoRoleRules` WHERE `AutoRoleId` = {id}; - """) + """ + ) @property def insert_string(self) -> str: - return str(f""" + return str( + f""" INSERT INTO `AutoRoleRules` ( `AutoRoleId`, `DiscordEmojiName`, `DiscordRoleId`, `CreatedAt`, `LastModifiedAt` ) VALUES ( @@ -64,22 +78,27 @@ class AutoRoleRule(TableABC): '{self._created_at}', '{self._modified_at}' ); - """) + """ + ) @property def udpate_string(self) -> str: - return str(f""" + return str( + f""" UPDATE `AutoRoleRules` SET `AutoRoleId` = {self._auto_role_id}, `DiscordEmojiName` = {self._discord_emoji_name}, `DiscordRoleId` = {self._discord_role_id}, `LastModifiedAt` = '{self._modified_at}' WHERE `AutoRoleRuleId` = {self._auto_role_rule_id}; - """) + """ + ) @property def delete_string(self) -> str: - return str(f""" + return str( + f""" DELETE FROM `AutoRoleRules` WHERE `AutoRoleRuleId` = {self._auto_role_rule_id}; - """) + """ + ) diff --git a/kdb-bot/src/bot_data/model/client.py b/kdb-bot/src/bot_data/model/client.py index 3e942f38..db98caaf 100644 --- a/kdb-bot/src/bot_data/model/client.py +++ b/kdb-bot/src/bot_data/model/client.py @@ -5,18 +5,18 @@ from bot_data.model.server import Server class Client(TableABC): - - def __init__(self, - dc_id: int, - smc: int, - rmc: int, - dmc: int, - rcc: int, - muc: int, - server: Server, - created_at: datetime = None, - modified_at: datetime = None, - id=0 + def __init__( + self, + dc_id: int, + smc: int, + rmc: int, + dmc: int, + rcc: int, + muc: int, + server: Server, + created_at: datetime = None, + modified_at: datetime = None, + id=0, ): self._client_id = id self._discord_client_id = dc_id @@ -90,42 +90,53 @@ class Client(TableABC): @staticmethod def get_select_all_string() -> str: - return str(f""" + return str( + f""" SELECT * FROM `Clients`; - """) + """ + ) @staticmethod def get_select_by_id_string(id: int) -> str: - return str(f""" + return str( + f""" SELECT * FROM `Clients` WHERE `ClientId` = {id}; - """) + """ + ) @staticmethod def get_select_by_discord_id_string(id: int) -> str: - return str(f""" + return str( + f""" SELECT * FROM `Clients` WHERE `DiscordClientId` = {id}; - """) + """ + ) @staticmethod def get_select_by_server_id_string(id: int) -> str: - return str(f""" + return str( + f""" SELECT * FROM `Clients` WHERE `ServerId` = {id}; - """) + """ + ) @staticmethod def get_select_by_discord_id_and_server_id_string(id: int, server_id: int) -> str: - return str(f""" + return str( + f""" SELECT * FROM `Clients` WHERE `DiscordClientId` = {id} AND `ServerId` = {server_id}; - """) + """ + ) @property def insert_string(self) -> str: - return str(f""" + return str( + f""" INSERT INTO `Clients` ( `DiscordClientId`, `SentMessageCount`, @@ -147,11 +158,13 @@ class Client(TableABC): '{self._created_at}', '{self._modified_at}' ); - """) + """ + ) @property def udpate_string(self) -> str: - return str(f""" + return str( + f""" UPDATE `Clients` SET `SentMessageCount` = {self._sent_message_count}, `ReceivedMessageCount` = {self._received_message_count}, @@ -160,11 +173,14 @@ class Client(TableABC): `MovedUsersCount` = {self._moved_users_count}, `LastModifiedAt` = '{self._modified_at}' WHERE `ClientId` = {self._client_id}; - """) + """ + ) @property def delete_string(self) -> str: - return str(f""" + return str( + f""" DELETE FROM `Clients` WHERE `ClientId` = {self._client_id}; - """) + """ + ) diff --git a/kdb-bot/src/bot_data/model/known_user.py b/kdb-bot/src/bot_data/model/known_user.py index 12c9a05d..be64d9d5 100644 --- a/kdb-bot/src/bot_data/model/known_user.py +++ b/kdb-bot/src/bot_data/model/known_user.py @@ -6,11 +6,16 @@ from bot_data.model.server import Server class KnownUser(TableABC): - - def __init__(self, dc_id: int, created_at: datetime = None, modified_at: datetime = None, id=0): + def __init__( + self, + dc_id: int, + created_at: datetime = None, + modified_at: datetime = None, + id=0, + ): self._known_user_id = id self._discord_id = dc_id - + TableABC.__init__(self) self._created_at = created_at if created_at is not None else self._created_at self._modified_at = modified_at if modified_at is not None else self._modified_at @@ -25,27 +30,34 @@ class KnownUser(TableABC): @staticmethod def get_select_all_string() -> str: - return str(f""" + return str( + f""" SELECT * FROM `KnownUsers`; - """) + """ + ) @staticmethod def get_select_by_id_string(id: int) -> str: - return str(f""" + return str( + f""" SELECT * FROM `KnownUsers` WHERE `KnownUserId` = {id}; - """) + """ + ) @staticmethod def get_select_by_discord_id_string(id: int) -> str: - return str(f""" + return str( + f""" SELECT * FROM `KnownUsers` WHERE `DiscordId` = {id}; - """) + """ + ) @property def insert_string(self) -> str: - return str(f""" + return str( + f""" INSERT INTO `KnownUsers` ( `DiscordId`, `CreatedAt`, `LastModifiedAt` ) VALUES ( @@ -53,15 +65,18 @@ class KnownUser(TableABC): '{self._created_at}', '{self._modified_at}' ); - """) + """ + ) @property def udpate_string(self) -> str: - return '' + return "" @property def delete_string(self) -> str: - return str(f""" + return str( + f""" DELETE FROM `KnownUsers` WHERE `Id` = {self._known_user_id}; - """) + """ + ) diff --git a/kdb-bot/src/bot_data/model/level.py b/kdb-bot/src/bot_data/model/level.py index 9cfc63f1..fbea3634 100644 --- a/kdb-bot/src/bot_data/model/level.py +++ b/kdb-bot/src/bot_data/model/level.py @@ -6,15 +6,24 @@ from bot_data.model.server import Server class Level(TableABC): - - def __init__(self, name: str, color: str, min_xp: int, permissions: int, server: Optional[Server], created_at: datetime = None, modified_at: datetime = None, id=0): + def __init__( + self, + name: str, + color: str, + min_xp: int, + permissions: int, + server: Optional[Server], + created_at: datetime = None, + modified_at: datetime = None, + id=0, + ): self._id = id self._name = name self._color = color self._min_xp = min_xp self._permissions = permissions self._server = server - + TableABC.__init__(self) self._created_at = created_at if created_at is not None else self._created_at self._modified_at = modified_at if modified_at is not None else self._modified_at @@ -22,70 +31,82 @@ class Level(TableABC): @property def id(self) -> int: return self._id - + @property def name(self) -> str: return self._name - + @name.setter def name(self, value: str): + self._modified_at = datetime.now().isoformat() self._name = value - + @property def color(self) -> str: return self._color - + @color.setter def color(self, value: str): + self._modified_at = datetime.now().isoformat() self._color = value - + @property def min_xp(self) -> int: return self._min_xp - + @min_xp.setter def min_xp(self, value: int): + self._modified_at = datetime.now().isoformat() self._min_xp = value - + @property def permissions(self) -> int: return self._permissions - + @permissions.setter def permissions(self, value: int): + self._modified_at = datetime.now().isoformat() self._permissions = value - + @property def server(self) -> Server: return self._server - + @server.setter def server(self, value: Server): + self._modified_at = datetime.now().isoformat() self._server = value @staticmethod def get_select_all_string() -> str: - return str(f""" + return str( + f""" SELECT * FROM `Levels`; - """) + """ + ) @staticmethod def get_select_by_id_string(id: int) -> str: - return str(f""" + return str( + f""" SELECT * FROM `Levels` WHERE `Id` = {id}; - """) + """ + ) @staticmethod def get_select_by_server_id_string(s_id: int) -> str: - return str(f""" + return str( + f""" SELECT * FROM `Levels` WHERE `ServerId` = {s_id}; - """) + """ + ) @property def insert_string(self) -> str: - return str(f""" + return str( + f""" INSERT INTO `Levels` ( `Name`, `Color`, `MinXp`, `PermissionInt`, `ServerId`, `CreatedAt`, `LastModifiedAt` ) VALUES ( @@ -97,11 +118,13 @@ class Level(TableABC): '{self._created_at}', '{self._modified_at}' ); - """) + """ + ) @property def udpate_string(self) -> str: - return str(f""" + return str( + f""" UPDATE `Levels` SET `Name` = '{self._name}', `Color` = '{self._color}', @@ -109,11 +132,14 @@ class Level(TableABC): `PermissionInt` = {self._permissions}, `LastModifiedAt` = '{self._modified_at}' WHERE `Id` = {self._id}; - """) + """ + ) @property def delete_string(self) -> str: - return str(f""" + return str( + f""" DELETE FROM `Levels` WHERE `Id` = {self._id}; - """) + """ + ) diff --git a/kdb-bot/src/bot_data/model/migration_history.py b/kdb-bot/src/bot_data/model/migration_history.py index c00ba7ad..464591bc 100644 --- a/kdb-bot/src/bot_data/model/migration_history.py +++ b/kdb-bot/src/bot_data/model/migration_history.py @@ -2,26 +2,28 @@ from cpl_core.database import TableABC class MigrationHistory(TableABC): - def __init__(self, id: str): self._id = id TableABC.__init__(self) - + @property def migration_id(self) -> str: return self._id @staticmethod def get_select_by_id_string(id: str) -> str: - return str(f""" + return str( + f""" SELECT * FROM `MigrationHistory` WHERE `MigrationId` = '{id}'; - """) + """ + ) @property def insert_string(self) -> str: - return str(f""" + return str( + f""" INSERT INTO `MigrationHistory` ( `MigrationId`, `CreatedAt`, `LastModifiedAt` ) VALUES ( @@ -29,19 +31,24 @@ class MigrationHistory(TableABC): '{self._created_at}', '{self._modified_at}' ); - """) + """ + ) @property def udpate_string(self) -> str: - return str(f""" + return str( + f""" UPDATE `MigrationHistory` SET LastModifiedAt` = '{self._modified_at}' WHERE `MigrationId` = '{self._id}'; - """) + """ + ) @property def delete_string(self) -> str: - return str(f""" + return str( + f""" DELETE FROM `MigrationHistory` WHERE `MigrationId` = '{self._id}'; - """) + """ + ) diff --git a/kdb-bot/src/bot_data/model/server.py b/kdb-bot/src/bot_data/model/server.py index c3054952..4f22ec1c 100644 --- a/kdb-bot/src/bot_data/model/server.py +++ b/kdb-bot/src/bot_data/model/server.py @@ -5,15 +5,20 @@ from cpl_core.database import TableABC class Server(TableABC): - - def __init__(self, dc_id: int, created_at: datetime=None, modified_at: datetime=None, id=0): + def __init__( + self, + dc_id: int, + created_at: datetime = None, + modified_at: datetime = None, + id=0, + ): self._server_id = id self._discord_server_id = dc_id - + TableABC.__init__(self) self._created_at = created_at if created_at is not None else self._created_at self._modified_at = modified_at if modified_at is not None else self._modified_at - + @property def server_id(self) -> int: return self._server_id @@ -21,30 +26,37 @@ class Server(TableABC): @property def discord_server_id(self) -> int: return self._discord_server_id - + @staticmethod def get_select_all_string() -> str: - return str(f""" + return str( + f""" SELECT * FROM `Servers`; - """) - + """ + ) + @staticmethod def get_select_by_id_string(id: int) -> str: - return str(f""" + return str( + f""" SELECT * FROM `Servers` WHERE `ServerId` = {id}; - """) - + """ + ) + @staticmethod def get_select_by_discord_id_string(id: int) -> str: - return str(f""" + return str( + f""" SELECT * FROM `Servers` WHERE `DiscordServerId` = {id}; - """) + """ + ) @property def insert_string(self) -> str: - return str(f""" + return str( + f""" INSERT INTO `Servers` ( `DiscordServerId`, `CreatedAt`, `LastModifiedAt` ) VALUES ( @@ -52,20 +64,25 @@ class Server(TableABC): '{self._created_at}', '{self._modified_at}' ); - """) + """ + ) @property def udpate_string(self) -> str: - return str(f""" + return str( + f""" UPDATE `Servers` SET `DiscordServerId` = {self._discord_server_id}, `LastModifiedAt` = '{self._modified_at}' WHERE `ServerId` = {self._server_id}; - """) + """ + ) @property def delete_string(self) -> str: - return str(f""" + return str( + f""" DELETE FROM `Servers` WHERE `ServerId` = {self._server_id}; - """) + """ + ) diff --git a/kdb-bot/src/bot_data/model/statistic.py b/kdb-bot/src/bot_data/model/statistic.py index 11011237..0b4476a2 100644 --- a/kdb-bot/src/bot_data/model/statistic.py +++ b/kdb-bot/src/bot_data/model/statistic.py @@ -7,8 +7,16 @@ from bot_data.model.server import Server class Statistic(TableABC): - - def __init__(self, name: str, description: str, code: str, server: Server, created_at: datetime=None, modified_at: datetime=None, id=0): + def __init__( + self, + name: str, + description: str, + code: str, + server: Server, + created_at: datetime = None, + modified_at: datetime = None, + id=0, + ): self._id = id self._name = name self._description = description @@ -18,66 +26,75 @@ class Statistic(TableABC): TableABC.__init__(self) self._created_at = created_at if created_at is not None else self._created_at self._modified_at = modified_at if modified_at is not None else self._modified_at - + @property def id(self) -> int: return self._id - + @property def name(self) -> str: return self._name - + @property def description(self) -> str: return self._description - + @description.setter def description(self, value: str): self._description = value - + @property def code(self) -> str: return CredentialManager.decrypt(self._code) - + @code.setter def code(self, value: str): self._code = CredentialManager.encrypt(value) - + @property def server(self) -> Server: return self._server - + @staticmethod def get_select_all_string() -> str: - return str(f""" + return str( + f""" SELECT * FROM `Statistics`; - """) - + """ + ) + @staticmethod def get_select_by_id_string(id: int) -> str: - return str(f""" + return str( + f""" SELECT * FROM `Statistics` WHERE `Id` = {id}; - """) + """ + ) @staticmethod def get_select_by_name_string(name: str, s_id: int) -> str: - return str(f""" + return str( + f""" SELECT * FROM `Statistics` WHERE `ServerId` = {s_id} AND `Name` = '{name}'; - """) + """ + ) @staticmethod def get_select_by_server_string(s_id: int) -> str: - return str(f""" + return str( + f""" SELECT * FROM `Statistics` WHERE `ServerId` = {s_id}; - """) + """ + ) @property def insert_string(self) -> str: - return str(f""" + return str( + f""" INSERT INTO `Statistics` ( `Name`, `Description`, `Code`, `ServerId`, `CreatedAt`, `LastModifiedAt` ) VALUES ( @@ -88,22 +105,27 @@ class Statistic(TableABC): '{self._created_at}', '{self._modified_at}' ); - """) + """ + ) @property def udpate_string(self) -> str: - return str(f""" + return str( + f""" UPDATE `Statistics` SET `Name` = '{self._name}', `Description` = '{self._description}', `Code` = '{self._code}', `LastModifiedAt` = '{self._modified_at}' WHERE `Id` = {self._id}; - """) + """ + ) @property def delete_string(self) -> str: - return str(f""" + return str( + f""" DELETE FROM `Statistics` WHERE `Id` = {self._id}; - """) + """ + ) diff --git a/kdb-bot/src/bot_data/model/user.py b/kdb-bot/src/bot_data/model/user.py index 289d755d..1592e471 100644 --- a/kdb-bot/src/bot_data/model/user.py +++ b/kdb-bot/src/bot_data/model/user.py @@ -6,13 +6,20 @@ from bot_data.model.server import Server class User(TableABC): - - def __init__(self, dc_id: int, xp: int, server: Optional[Server], created_at: datetime = None, modified_at: datetime = None, id=0): + def __init__( + self, + dc_id: int, + xp: int, + server: Optional[Server], + created_at: datetime = None, + modified_at: datetime = None, + id=0, + ): self._user_id = id self._discord_id = dc_id self._xp = xp self._server = server - + TableABC.__init__(self) self._created_at = created_at if created_at is not None else self._created_at self._modified_at = modified_at if modified_at is not None else self._modified_at @@ -40,35 +47,44 @@ class User(TableABC): @staticmethod def get_select_all_string() -> str: - return str(f""" + return str( + f""" SELECT * FROM `Users`; - """) + """ + ) @staticmethod def get_select_by_id_string(id: int) -> str: - return str(f""" + return str( + f""" SELECT * FROM `Users` WHERE `UserId` = {id}; - """) + """ + ) @staticmethod def get_select_by_discord_id_string(id: int) -> str: - return str(f""" + return str( + f""" SELECT * FROM `Users` WHERE `DiscordId` = {id}; - """) + """ + ) @staticmethod def get_select_by_discord_id_and_server_id_string(dc_id: int, s_id: int) -> str: - return str(f""" + return str( + f""" SELECT * FROM `Users` WHERE `DiscordId` = {dc_id} AND `ServerId` = {s_id}; - """) + """ + ) @property def insert_string(self) -> str: - return str(f""" + return str( + f""" INSERT INTO `Users` ( `DiscordId`, `XP`, `ServerId`, `CreatedAt`, `LastModifiedAt` ) VALUES ( @@ -78,20 +94,25 @@ class User(TableABC): '{self._created_at}', '{self._modified_at}' ); - """) + """ + ) @property def udpate_string(self) -> str: - return str(f""" + return str( + f""" UPDATE `Users` SET `XP` = {self._xp}, `LastModifiedAt` = '{self._modified_at}' WHERE `UserId` = {self._user_id}; - """) + """ + ) @property def delete_string(self) -> str: - return str(f""" + return str( + f""" DELETE FROM `Users` WHERE `UserId` = {self._user_id}; - """) + """ + ) diff --git a/kdb-bot/src/bot_data/model/user_joined_server.py b/kdb-bot/src/bot_data/model/user_joined_server.py index 2f84539d..7c0764d1 100644 --- a/kdb-bot/src/bot_data/model/user_joined_server.py +++ b/kdb-bot/src/bot_data/model/user_joined_server.py @@ -8,13 +8,20 @@ from bot_data.model.server import Server class UserJoinedServer(TableABC): - - def __init__(self, user: User, joined_on: datetime, leaved_on: datetime=None, created_at: datetime=None, modified_at: datetime=None, id=0): + def __init__( + self, + user: User, + joined_on: datetime, + leaved_on: datetime = None, + created_at: datetime = None, + modified_at: datetime = None, + id=0, + ): self._join_id = id self._user = user self._joined_on = joined_on self._leaved_on = leaved_on - + TableABC.__init__(self) self._created_at = created_at if created_at is not None else self._created_at self._modified_at = modified_at if modified_at is not None else self._modified_at @@ -44,39 +51,48 @@ class UserJoinedServer(TableABC): def leaved_on(self, value: datetime): self._modified_at = datetime.now() self._leaved_on = value - + @staticmethod def get_select_all_string() -> str: - return str(f""" + return str( + f""" SELECT * FROM `UserJoinedServers`; - """) - + """ + ) + @staticmethod def get_select_by_id_string(id: int) -> str: - return str(f""" + return str( + f""" SELECT * FROM `UserJoinedServers` WHERE `JoinId` = {id}; - """) - + """ + ) + @staticmethod def get_select_by_user_id_string(id: int) -> str: - return str(f""" + return str( + f""" SELECT * FROM `UserJoinedServers` WHERE `UserId` = {id}; - """) - + """ + ) + @staticmethod def get_select_active_by_user_id_string(id: int) -> str: - return str(f""" + return str( + f""" SELECT * FROM `UserJoinedServers` WHERE `UserId` = {id} AND `LeavedOn` IS NULL; - """) + """ + ) @property def insert_string(self) -> str: if self._leaved_on is not None: - return str(f""" + return str( + f""" INSERT INTO `UserJoinedServers` ( `UserId`, `JoinedOn`, `LeavedOn`, `CreatedAt`, `LastModifiedAt` ) VALUES ( @@ -86,9 +102,11 @@ class UserJoinedServer(TableABC): '{self._created_at}', '{self._modified_at}' ); - """) + """ + ) else: - return str(f""" + return str( + f""" INSERT INTO `UserJoinedServers` ( `UserId`, `JoinedOn`, `CreatedAt`, `LastModifiedAt` ) VALUES ( @@ -97,20 +115,25 @@ class UserJoinedServer(TableABC): '{self._created_at}', '{self._modified_at}' ); - """) + """ + ) @property def udpate_string(self) -> str: - return str(f""" + return str( + f""" UPDATE `UserJoinedServers` SET `LeavedOn` = '{self._leaved_on}', `LastModifiedAt` = '{self._modified_at}' WHERE `UserId` = {self._user.user_id}; - """) + """ + ) @property def delete_string(self) -> str: - return str(f""" + return str( + f""" DELETE FROM `UserJoinedServers` WHERE `Id` = {self._join_id}; - """) + """ + ) diff --git a/kdb-bot/src/bot_data/model/user_joined_voice_channel.py b/kdb-bot/src/bot_data/model/user_joined_voice_channel.py index 4977c2e6..59e46466 100644 --- a/kdb-bot/src/bot_data/model/user_joined_voice_channel.py +++ b/kdb-bot/src/bot_data/model/user_joined_voice_channel.py @@ -6,8 +6,16 @@ from bot_data.model.user import User class UserJoinedVoiceChannel(TableABC): - - def __init__(self, user: User, dc_channel_id: int, joined_on: datetime, leaved_on: datetime = None, created_at: datetime = None, modified_at: datetime = None, id=0): + def __init__( + self, + user: User, + dc_channel_id: int, + joined_on: datetime, + leaved_on: datetime = None, + created_at: datetime = None, + modified_at: datetime = None, + id=0, + ): self._join_id = id self._dc_channel_id = dc_channel_id self._user = user @@ -21,7 +29,7 @@ class UserJoinedVoiceChannel(TableABC): @property def join_id(self) -> int: return self._join_id - + @property def dc_channel_id(self) -> int: return self._dc_channel_id @@ -47,39 +55,48 @@ class UserJoinedVoiceChannel(TableABC): def leaved_on(self, value: datetime): self._modified_at = datetime.now() self._leaved_on = value - + @staticmethod def get_select_all_string() -> str: - return str(f""" + return str( + f""" SELECT * FROM `UserJoinedVoiceChannel`; - """) - + """ + ) + @staticmethod def get_select_by_id_string(id: int) -> str: - return str(f""" + return str( + f""" SELECT * FROM `UserJoinedVoiceChannel` WHERE `JoinId` = {id}; - """) - + """ + ) + @staticmethod def get_select_by_user_id_string(id: int) -> str: - return str(f""" + return str( + f""" SELECT * FROM `UserJoinedVoiceChannel` WHERE `UserId` = {id}; - """) - + """ + ) + @staticmethod def get_select_active_by_user_id_string(id: int) -> str: - return str(f""" + return str( + f""" SELECT * FROM `UserJoinedVoiceChannel` WHERE `UserId` = {id} AND `LeavedOn` IS NULL; - """) + """ + ) @property def insert_string(self) -> str: if self._leaved_on is not None: - return str(f""" + return str( + f""" INSERT INTO `UserJoinedVoiceChannel` ( `UserId`, `DiscordChannelId`, `JoinedOn`, `LeavedOn`, `CreatedAt`, `LastModifiedAt` ) VALUES ( @@ -90,9 +107,11 @@ class UserJoinedVoiceChannel(TableABC): '{self._created_at}', '{self._modified_at}' ); - """) + """ + ) else: - return str(f""" + return str( + f""" INSERT INTO `UserJoinedVoiceChannel` ( `UserId`, `DiscordChannelId`, `JoinedOn`, `CreatedAt`, `LastModifiedAt` ) VALUES ( @@ -102,27 +121,34 @@ class UserJoinedVoiceChannel(TableABC): '{self._created_at}', '{self._modified_at}' ); - """) + """ + ) @property def udpate_string(self) -> str: - return str(f""" + return str( + f""" UPDATE `UserJoinedVoiceChannel` SET `LeavedOn` = '{self._leaved_on}', `LastModifiedAt` = '{self._modified_at}' WHERE `JoinId` = {self._join_id}; - """) + """ + ) @property def delete_string(self) -> str: - return str(f""" + return str( + f""" DELETE FROM `UserJoinedVoiceChannel` WHERE `JoinId` = {self._join_id}; - """) + """ + ) @staticmethod def delete_by_user_id_string(id: int) -> str: - return str(f""" + return str( + f""" DELETE FROM `UserJoinedVoiceChannel` WHERE `UserId` = {id} - """) \ No newline at end of file + """ + ) diff --git a/kdb-bot/src/bot_data/model/user_message_count_per_hour.py b/kdb-bot/src/bot_data/model/user_message_count_per_hour.py new file mode 100644 index 00000000..6fdb7b9b --- /dev/null +++ b/kdb-bot/src/bot_data/model/user_message_count_per_hour.py @@ -0,0 +1,137 @@ +from datetime import datetime + +from cpl_core.database import TableABC + +from bot_data.model.user import User + + +class UserMessageCountPerHour(TableABC): + def __init__( + self, + date: str, + hour: int, + xp_count: int, + user: User, + created_at: datetime = None, + modified_at: datetime = None, + id=0, + ): + self._id = id + self._date = date + self._hour = hour + self._xp_count = xp_count + self._user = user + + TableABC.__init__(self) + self._created_at = created_at if created_at is not None else self._created_at + self._modified_at = modified_at if modified_at is not None else self._modified_at + + @property + def id(self) -> int: + return self._id + + @property + def date(self) -> datetime: + return self._date + + @property + def hour(self) -> int: + return self._hour + + @property + def xp_count(self) -> int: + return self._xp_count + + @xp_count.setter + def xp_count(self, value: int): + self._modified_at = datetime.now().isoformat() + self._xp_count = value + + @property + def user(self) -> User: + return self._user + + @staticmethod + def get_select_all_string() -> str: + return str( + f""" + SELECT * FROM `UserMessageCountPerHour`; + """ + ) + + @staticmethod + def get_select_by_id_string(id: int) -> str: + return str( + f""" + SELECT * FROM `UserMessageCountPerHour` + WHERE `Id` = {id}; + """ + ) + + @staticmethod + def get_select_by_user_id_string(id: int) -> str: + return str( + f""" + SELECT * FROM `UserMessageCountPerHour` + WHERE `UserId` = {id}; + """ + ) + + @staticmethod + def get_select_by_user_id_and_date_string(id: int, date: datetime) -> str: + date_str = f"{str(date.year).zfill(4)}-{str(date.month).zfill(2)}-{str(date.day).zfill(2)}%" + + return str( + f""" + SELECT * FROM `UserMessageCountPerHour` + WHERE `UserId` = {id} + AND `Date` LIKE '{date_str}' + AND `Hour` = {date.hour}; + """ + ) + + @property + def insert_string(self) -> str: + return str( + f""" + INSERT INTO `UserMessageCountPerHour` ( + `UserId`, `Date`, `Hour`, `XPCount`, `CreatedAt`, `LastModifiedAt` + ) VALUES ( + {self._user.user_id}, + '{self._date}', + {self._hour}, + {self._xp_count}, + '{self._created_at}', + '{self._modified_at}' + ); + """ + ) + + @property + def udpate_string(self) -> str: + return str( + f""" + UPDATE `UserMessageCountPerHour` + SET `XPCount` = '{self._xp_count}', + `LastModifiedAt` = '{self._modified_at}' + WHERE `Id` = {self._id}; + """ + ) + + @property + def delete_string(self) -> str: + return str( + f""" + DELETE FROM `UserMessageCountPerHour` + WHERE `Id` = {self._id}; + """ + ) + + @staticmethod + def delete_by_user_id_string(id: int) -> str: + return str( + f""" + DELETE FROM `UserMessageCountPerHour` + WHERE `UserId` = {id} + """ + ) diff --git a/kdb-bot/src/bot_data/service/__init__.py b/kdb-bot/src/bot_data/service/__init__.py index 6ed37769..73214e20 100644 --- a/kdb-bot/src/bot_data/service/__init__.py +++ b/kdb-bot/src/bot_data/service/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'bot_data.service' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "bot_data.service" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/bot_data/service/auth_user_repository_service.py b/kdb-bot/src/bot_data/service/auth_user_repository_service.py index ac5a670c..15592b4c 100644 --- a/kdb-bot/src/bot_data/service/auth_user_repository_service.py +++ b/kdb-bot/src/bot_data/service/auth_user_repository_service.py @@ -15,8 +15,12 @@ from bot_data.model.user import User class AuthUserRepositoryService(AuthUserRepositoryABC): - - def __init__(self, logger: DatabaseLogger, db_context: DatabaseContextABC, users: UserRepositoryABC): + def __init__( + self, + logger: DatabaseLogger, + db_context: DatabaseContextABC, + users: UserRepositoryABC, + ): self._logger = logger self._context = db_context self._users = users @@ -25,7 +29,7 @@ class AuthUserRepositoryService(AuthUserRepositoryABC): @staticmethod def _get_value_from_result(value: any) -> Optional[any]: - if isinstance(value, str) and 'NULL' in value: + if isinstance(value, str) and "NULL" in value: return None return value @@ -43,10 +47,13 @@ class AuthUserRepositoryService(AuthUserRepositoryABC): self._get_value_from_result(au_result[9]), self._get_value_from_result(au_result[10]), AuthRoleEnum(self._get_value_from_result(au_result[11])), - auth_user_id=self._get_value_from_result(au_result[0]) + auth_user_id=self._get_value_from_result(au_result[0]), ) - self._logger.trace(__name__, f'Send SQL command: {auth_user.get_select_user_id_from_relations()}') + self._logger.trace( + __name__, + f"Send SQL command: {auth_user.get_select_user_id_from_relations()}", + ) results = self._context.select(auth_user.get_select_user_id_from_relations()) for result in results: user_id = self._get_value_from_result(result[0]) @@ -60,33 +67,38 @@ class AuthUserRepositoryService(AuthUserRepositoryABC): def get_all_auth_users(self) -> List[AuthUser]: users = List(AuthUser) - self._logger.trace(__name__, f'Send SQL command: {AuthUser.get_select_all_string()}') + self._logger.trace(__name__, f"Send SQL command: {AuthUser.get_select_all_string()}") results = self._context.select(AuthUser.get_select_all_string()) for result in results: - self._logger.trace(__name__, f'Get auth user with id {result[0]}') + self._logger.trace(__name__, f"Get auth user with id {result[0]}") users.append(self._user_from_result(result)) return users def get_filtered_auth_users(self, criteria: AuthUserSelectCriteria) -> FilteredResult: users = self.get_all_auth_users() - self._logger.trace(__name__, f'Send SQL command: {AuthUser.get_select_all_string()}') + self._logger.trace(__name__, f"Send SQL command: {AuthUser.get_select_all_string()}") query = users - if criteria.first_name is not None and criteria.first_name != '': + if criteria.first_name is not None and criteria.first_name != "": query = query.where(lambda x: criteria.first_name in x.first_name or x.first_name == criteria.first_name) - if criteria.last_name is not None and criteria.last_name != '': + if criteria.last_name is not None and criteria.last_name != "": query = query.where(lambda x: criteria.last_name in x.last_name or x.last_name == criteria.last_name) - if criteria.email is not None and criteria.email != '': + if criteria.email is not None and criteria.email != "": query = query.where(lambda x: criteria.email in x.email or x.email == criteria.email) if criteria.auth_role is not None: query = query.where(lambda x: x.auth_role == AuthRoleEnum(criteria.auth_role)) # sort - if criteria.sort_column is not None and criteria.sort_column != '' and criteria.sort_direction is not None and criteria.sort_direction: + if ( + criteria.sort_column is not None + and criteria.sort_column != "" + and criteria.sort_direction is not None + and criteria.sort_direction + ): crit_sort_direction = criteria.sort_direction.lower() if crit_sort_direction == "desc" or crit_sort_direction == "descending": query = query.order_by_descending(lambda x: getattr(x, criteria.sort_column)) @@ -101,12 +113,12 @@ class AuthUserRepositoryService(AuthUserRepositoryABC): return result def get_auth_user_by_email(self, email: str) -> AuthUser: - self._logger.trace(__name__, f'Send SQL command: {AuthUser.get_select_by_email_string(email)}') + self._logger.trace(__name__, f"Send SQL command: {AuthUser.get_select_by_email_string(email)}") result = self._context.select(AuthUser.get_select_by_email_string(email))[0] return self._user_from_result(result) def find_auth_user_by_email(self, email: str) -> Optional[AuthUser]: - self._logger.trace(__name__, f'Send SQL command: {AuthUser.get_select_by_email_string(email)}') + self._logger.trace(__name__, f"Send SQL command: {AuthUser.get_select_by_email_string(email)}") result = self._context.select(AuthUser.get_select_by_email_string(email)) if result is None or len(result) == 0: return None @@ -116,7 +128,10 @@ class AuthUserRepositoryService(AuthUserRepositoryABC): return self._user_from_result(result) def find_auth_user_by_confirmation_id(self, id: str) -> Optional[AuthUser]: - self._logger.trace(__name__, f'Send SQL command: {AuthUser.get_select_by_confirmation_id_string(id)}') + self._logger.trace( + __name__, + f"Send SQL command: {AuthUser.get_select_by_confirmation_id_string(id)}", + ) result = self._context.select(AuthUser.get_select_by_confirmation_id_string(id)) if result is None or len(result) == 0: return None @@ -126,7 +141,10 @@ class AuthUserRepositoryService(AuthUserRepositoryABC): return self._user_from_result(result) def find_auth_user_by_forgot_password_id(self, id: str) -> Optional[AuthUser]: - self._logger.trace(__name__, f'Send SQL command: {AuthUser.get_select_by_forgot_password_id_string(id)}') + self._logger.trace( + __name__, + f"Send SQL command: {AuthUser.get_select_by_forgot_password_id_string(id)}", + ) result = self._context.select(AuthUser.get_select_by_forgot_password_id_string(id)) if result is None or len(result) == 0: return None @@ -136,25 +154,25 @@ class AuthUserRepositoryService(AuthUserRepositoryABC): return self._user_from_result(result) def add_auth_user(self, user: AuthUser): - self._logger.trace(__name__, f'Send SQL command: {user.insert_string}') + self._logger.trace(__name__, f"Send SQL command: {user.insert_string}") self._context.cursor.execute(user.insert_string) def update_auth_user(self, user: AuthUser): - self._logger.trace(__name__, f'Send SQL command: {user.udpate_string}') + self._logger.trace(__name__, f"Send SQL command: {user.udpate_string}") self._context.cursor.execute(user.udpate_string) def delete_auth_user(self, user: AuthUser): - self._logger.trace(__name__, f'Send SQL command: {user.delete_string}') + self._logger.trace(__name__, f"Send SQL command: {user.delete_string}") self._context.cursor.execute(user.delete_string) def add_auth_user_user_rel(self, rel: AuthUserUsersRelation): - self._logger.trace(__name__, f'Send SQL command: {rel.insert_string}') + self._logger.trace(__name__, f"Send SQL command: {rel.insert_string}") self._context.cursor.execute(rel.insert_string) def update_auth_user_user_rel(self, rel: AuthUserUsersRelation): - self._logger.trace(__name__, f'Send SQL command: {rel.udpate_string}') + self._logger.trace(__name__, f"Send SQL command: {rel.udpate_string}") self._context.cursor.execute(rel.udpate_string) def delete_auth_user_user_rel(self, rel: AuthUserUsersRelation): - self._logger.trace(__name__, f'Send SQL command: {rel.delete_string}') + self._logger.trace(__name__, f"Send SQL command: {rel.delete_string}") self._context.cursor.execute(rel.delete_string) diff --git a/kdb-bot/src/bot_data/service/auto_role_repository_service.py b/kdb-bot/src/bot_data/service/auto_role_repository_service.py index dd554772..b9d51e12 100644 --- a/kdb-bot/src/bot_data/service/auto_role_repository_service.py +++ b/kdb-bot/src/bot_data/service/auto_role_repository_service.py @@ -10,7 +10,6 @@ from bot_data.model.auto_role_rule import AutoRoleRule class AutoRoleRepositoryService(AutoRoleRepositoryABC): - def __init__(self, logger: DatabaseLogger, db_context: DatabaseContextABC): self._logger = logger self._context = db_context @@ -19,158 +18,104 @@ class AutoRoleRepositoryService(AutoRoleRepositoryABC): def get_auto_roles(self) -> List[AutoRole]: auto_roles = List(AutoRole) - self._logger.trace(__name__, f'Send SQL command: {AutoRole.get_select_all_string()}') + self._logger.trace(__name__, f"Send SQL command: {AutoRole.get_select_all_string()}") results = self._context.select(AutoRole.get_select_all_string()) for result in results: - auto_roles.append(AutoRole( - result[1], - result[2], - result[3], - result[4], - result[5], - id=result[0] - )) + auto_roles.append(AutoRole(result[1], result[2], result[3], result[4], result[5], id=result[0])) return auto_roles def get_auto_role_by_id(self, id: int) -> AutoRole: - self._logger.trace(__name__, f'Send SQL command: {AutoRole.get_select_by_id_string(id)}') + self._logger.trace(__name__, f"Send SQL command: {AutoRole.get_select_by_id_string(id)}") result = self._context.select(AutoRole.get_select_by_id_string(id))[0] - return AutoRole( - result[1], - result[2], - result[3], - result[4], - result[5], - id=result[0] - ) + return AutoRole(result[1], result[2], result[3], result[4], result[5], id=result[0]) def find_auto_role_by_id(self, id: int) -> Optional[AutoRole]: - self._logger.trace(__name__, f'Send SQL command: {AutoRole.get_select_by_id_string(id)}') + self._logger.trace(__name__, f"Send SQL command: {AutoRole.get_select_by_id_string(id)}") result = self._context.select(AutoRole.get_select_by_id_string(id)) if result is None or len(result) == 0: return None result = result[0] - return AutoRole( - result[1], - result[2], - result[3], - result[4], - result[5], - id=result[0] - ) + return AutoRole(result[1], result[2], result[3], result[4], result[5], id=result[0]) def get_auto_roles_by_server_id(self, id: int) -> List[AutoRole]: - self._logger.trace(__name__, f'Send SQL command: {AutoRole.get_select_by_server_id_string(id)}') + self._logger.trace(__name__, f"Send SQL command: {AutoRole.get_select_by_server_id_string(id)}") auto_roles = List(AutoRole) results = self._context.select(AutoRole.get_select_by_server_id_string(id)) for result in results: - auto_roles.append(AutoRole( - result[1], - result[2], - result[3], - result[4], - result[5], - id=result[0] - )) + auto_roles.append(AutoRole(result[1], result[2], result[3], result[4], result[5], id=result[0])) return auto_roles def get_auto_role_by_message_id(self, id: int) -> AutoRole: - self._logger.trace(__name__, f'Send SQL command: {AutoRole.get_select_by_message_id_string(id)}') - result = self._context.select(AutoRole.get_select_by_message_id_string(id))[0] - return AutoRole( - result[1], - result[2], - result[3], - result[4], - result[5], - id=result[0] + self._logger.trace( + __name__, + f"Send SQL command: {AutoRole.get_select_by_message_id_string(id)}", ) + result = self._context.select(AutoRole.get_select_by_message_id_string(id))[0] + return AutoRole(result[1], result[2], result[3], result[4], result[5], id=result[0]) def find_auto_role_by_message_id(self, id: int) -> Optional[AutoRole]: - self._logger.trace(__name__, f'Send SQL command: {AutoRole.get_select_by_message_id_string(id)}') + self._logger.trace( + __name__, + f"Send SQL command: {AutoRole.get_select_by_message_id_string(id)}", + ) result = self._context.select(AutoRole.get_select_by_message_id_string(id)) if result is None or len(result) == 0: return None result = result[0] - return AutoRole( - result[1], - result[2], - result[3], - result[4], - result[5], - id=result[0] - ) + return AutoRole(result[1], result[2], result[3], result[4], result[5], id=result[0]) def add_auto_role(self, auto_role: AutoRole): - self._logger.trace(__name__, f'Send SQL command: {auto_role.insert_string}') + self._logger.trace(__name__, f"Send SQL command: {auto_role.insert_string}") self._context.cursor.execute(auto_role.insert_string) def update_auto_role(self, auto_role: AutoRole): - self._logger.trace(__name__, f'Send SQL command: {auto_role.udpate_string}') + self._logger.trace(__name__, f"Send SQL command: {auto_role.udpate_string}") self._context.cursor.execute(auto_role.udpate_string) def delete_auto_role(self, auto_role: AutoRole): - self._logger.trace(__name__, f'Send SQL command: {auto_role.delete_string}') + self._logger.trace(__name__, f"Send SQL command: {auto_role.delete_string}") self._context.cursor.execute(auto_role.delete_string) def get_auto_role_rules(self) -> List[AutoRoleRule]: auto_role_rules = List(AutoRoleRule) - self._logger.trace(__name__, f'Send SQL command: {AutoRoleRule.get_select_all_string()}') + self._logger.trace(__name__, f"Send SQL command: {AutoRoleRule.get_select_all_string()}") results = self._context.select(AutoRoleRule.get_select_all_string()) for result in results: - auto_role_rules.append(AutoRoleRule( - result[1], - result[2], - result[3], - result[4], - result[5], - id=result[0] - )) + auto_role_rules.append(AutoRoleRule(result[1], result[2], result[3], result[4], result[5], id=result[0])) return auto_role_rules def get_auto_role_rule_by_id(self, id: int) -> AutoRoleRule: - self._logger.trace(__name__, f'Send SQL command: {AutoRoleRule.get_select_by_id_string(id)}') + self._logger.trace(__name__, f"Send SQL command: {AutoRoleRule.get_select_by_id_string(id)}") result = self._context.select(AutoRoleRule.get_select_by_id_string(id))[0] - return AutoRoleRule( - result[1], - result[2], - result[3], - result[4], - result[5], - id=result[0] - ) + return AutoRoleRule(result[1], result[2], result[3], result[4], result[5], id=result[0]) def get_auto_role_rules_by_auto_role_id(self, id: int) -> List[AutoRoleRule]: auto_role_rules = List(AutoRoleRule) - self._logger.trace(__name__, f'Send SQL command: {AutoRoleRule.get_select_by_auto_role_id_string(id)}') + self._logger.trace( + __name__, + f"Send SQL command: {AutoRoleRule.get_select_by_auto_role_id_string(id)}", + ) results = self._context.select(AutoRoleRule.get_select_by_auto_role_id_string(id)) for result in results: - auto_role_rules.append(AutoRoleRule( - result[1], - result[2], - result[3], - result[4], - result[5], - id=result[0] - )) + auto_role_rules.append(AutoRoleRule(result[1], result[2], result[3], result[4], result[5], id=result[0])) return auto_role_rules def add_auto_role_rule(self, auto_role_rule: AutoRoleRule): - self._logger.trace(__name__, f'Send SQL command: {auto_role_rule.insert_string}') + self._logger.trace(__name__, f"Send SQL command: {auto_role_rule.insert_string}") self._context.cursor.execute(auto_role_rule.insert_string) def update_auto_role_rule(self, auto_role_rule: AutoRoleRule): - self._logger.trace(__name__, f'Send SQL command: {auto_role_rule.udpate_string}') + self._logger.trace(__name__, f"Send SQL command: {auto_role_rule.udpate_string}") self._context.cursor.execute(auto_role_rule.udpate_string) def delete_auto_role_rule(self, auto_role_rule: AutoRoleRule): - self._logger.trace(__name__, f'Send SQL command: {auto_role_rule.delete_string}') + self._logger.trace(__name__, f"Send SQL command: {auto_role_rule.delete_string}") self._context.cursor.execute(auto_role_rule.delete_string) diff --git a/kdb-bot/src/bot_data/service/client_repository_service.py b/kdb-bot/src/bot_data/service/client_repository_service.py index ba875a25..85a4f51e 100644 --- a/kdb-bot/src/bot_data/service/client_repository_service.py +++ b/kdb-bot/src/bot_data/service/client_repository_service.py @@ -10,8 +10,12 @@ from bot_data.model.client import Client class ClientRepositoryService(ClientRepositoryABC): - - def __init__(self, logger: DatabaseLogger, db_context: DatabaseContextABC, servers: ServerRepositoryABC): + def __init__( + self, + logger: DatabaseLogger, + db_context: DatabaseContextABC, + servers: ServerRepositoryABC, + ): self._logger = logger self._context = db_context @@ -21,25 +25,27 @@ class ClientRepositoryService(ClientRepositoryABC): def get_clients(self) -> List[Client]: clients = List(Client) - self._logger.trace(__name__, f'Send SQL command: {Client.get_select_all_string()}') + self._logger.trace(__name__, f"Send SQL command: {Client.get_select_all_string()}") results = self._context.select(Client.get_select_all_string()) for result in results: - self._logger.trace(__name__, f'Get client with id {result[0]}') - clients.append(Client( - result[1], - result[2], - result[3], - result[4], - result[5], - result[6], - self._servers.get_server_by_id(result[7]), - id=result[0] - )) + self._logger.trace(__name__, f"Get client with id {result[0]}") + clients.append( + Client( + result[1], + result[2], + result[3], + result[4], + result[5], + result[6], + self._servers.get_server_by_id(result[7]), + id=result[0], + ) + ) return clients def get_client_by_id(self, client_id: int) -> Client: - self._logger.trace(__name__, f'Send SQL command: {Client.get_select_by_id_string(client_id)}') + self._logger.trace(__name__, f"Send SQL command: {Client.get_select_by_id_string(client_id)}") result = self._context.select(Client.get_select_by_id_string(client_id)) return Client( result[1], @@ -49,11 +55,14 @@ class ClientRepositoryService(ClientRepositoryABC): result[5], result[6], self._servers.get_server_by_id(result[7]), - id=result[0] + id=result[0], ) def get_client_by_discord_id(self, discord_id: int) -> Client: - self._logger.trace(__name__, f'Send SQL command: {Client.get_select_by_discord_id_string(discord_id)}') + self._logger.trace( + __name__, + f"Send SQL command: {Client.get_select_by_discord_id_string(discord_id)}", + ) result = self._context.select(Client.get_select_by_discord_id_string(discord_id))[0] return Client( result[1], @@ -63,17 +72,20 @@ class ClientRepositoryService(ClientRepositoryABC): result[5], result[6], self._servers.get_server_by_id(result[7]), - id=result[0] + id=result[0], ) def find_client_by_discord_id(self, discord_id: int) -> Optional[Client]: - self._logger.trace(__name__, f'Send SQL command: {Client.get_select_by_discord_id_string(discord_id)}') + self._logger.trace( + __name__, + f"Send SQL command: {Client.get_select_by_discord_id_string(discord_id)}", + ) result = self._context.select(Client.get_select_by_discord_id_string(discord_id)) if result is None or len(result) == 0: return None - + result = result[0] - + return Client( result[1], result[2], @@ -82,17 +94,20 @@ class ClientRepositoryService(ClientRepositoryABC): result[5], result[6], self._servers.get_server_by_id(result[7]), - id=result[0] + id=result[0], ) def find_client_by_server_id(self, discord_id: int) -> Optional[Client]: - self._logger.trace(__name__, f'Send SQL command: {Client.get_select_by_server_id_string(discord_id)}') + self._logger.trace( + __name__, + f"Send SQL command: {Client.get_select_by_server_id_string(discord_id)}", + ) result = self._context.select(Client.get_select_by_server_id_string(discord_id)) if result is None or len(result) == 0: return None - + result = result[0] - + return Client( result[1], result[2], @@ -101,17 +116,20 @@ class ClientRepositoryService(ClientRepositoryABC): result[5], result[6], self._servers.get_server_by_id(result[7]), - id=result[0] + id=result[0], ) def find_client_by_discord_id_and_server_id(self, discord_id: int, server_id: int) -> Optional[Client]: - self._logger.trace(__name__, f'Send SQL command: {Client.get_select_by_discord_id_and_server_id_string(discord_id, server_id)}') + self._logger.trace( + __name__, + f"Send SQL command: {Client.get_select_by_discord_id_and_server_id_string(discord_id, server_id)}", + ) result = self._context.select(Client.get_select_by_discord_id_and_server_id_string(discord_id, server_id)) if result is None or len(result) == 0: return None - + result = result[0] - + return Client( result[1], result[2], @@ -120,32 +138,32 @@ class ClientRepositoryService(ClientRepositoryABC): result[5], result[6], self._servers.get_server_by_id(result[7]), - id=result[0] + id=result[0], ) - + def add_client(self, client: Client): - self._logger.trace(__name__, f'Send SQL command: {client.insert_string}') + self._logger.trace(__name__, f"Send SQL command: {client.insert_string}") self._context.cursor.execute(client.insert_string) - + def update_client(self, client: Client): - self._logger.trace(__name__, f'Send SQL command: {client.udpate_string}') + self._logger.trace(__name__, f"Send SQL command: {client.udpate_string}") self._context.cursor.execute(client.udpate_string) - + def delete_client(self, client: Client): - self._logger.trace(__name__, f'Send SQL command: {client.delete_string}') + self._logger.trace(__name__, f"Send SQL command: {client.delete_string}") self._context.cursor.execute(client.delete_string) def _get_client_and_server(self, id: int, server_id: int) -> Client: server = self._servers.find_server_by_discord_id(server_id) if server is None: - self._logger.warn(__name__, f'Cannot find server by id {server_id}') - raise Exception('Value not found') - + self._logger.warn(__name__, f"Cannot find server by id {server_id}") + raise Exception("Value not found") + client = self.find_client_by_discord_id_and_server_id(id, server.server_id) if client is None: - self._logger.warn(__name__, f'Cannot find client by ids {id}@{server.server_id}') - raise Exception('Value not found') - + self._logger.warn(__name__, f"Cannot find client by ids {id}@{server.server_id}") + raise Exception("Value not found") + return client def append_sent_message_count(self, client_id: int, server_id: int, value: int): diff --git a/kdb-bot/src/bot_data/service/known_user_repository_service.py b/kdb-bot/src/bot_data/service/known_user_repository_service.py index fc112179..b7dc57e2 100644 --- a/kdb-bot/src/bot_data/service/known_user_repository_service.py +++ b/kdb-bot/src/bot_data/service/known_user_repository_service.py @@ -10,8 +10,12 @@ from bot_data.model.known_user import KnownUser class KnownUserRepositoryService(KnownUserRepositoryABC): - - def __init__(self, logger: DatabaseLogger, db_context: DatabaseContextABC, servers: ServerRepositoryABC): + def __init__( + self, + logger: DatabaseLogger, + db_context: DatabaseContextABC, + servers: ServerRepositoryABC, + ): self._logger = logger self._context = db_context @@ -21,58 +25,44 @@ class KnownUserRepositoryService(KnownUserRepositoryABC): def get_users(self) -> List[KnownUser]: users = List(KnownUser) - self._logger.trace(__name__, f'Send SQL command: {KnownUser.get_select_all_string()}') + self._logger.trace(__name__, f"Send SQL command: {KnownUser.get_select_all_string()}") results = self._context.select(KnownUser.get_select_all_string()) for result in results: - self._logger.trace(__name__, f'Get known_user with id {result[0]}') - users.append(KnownUser( - result[1], - result[2], - result[3], - id=result[0] - )) + self._logger.trace(__name__, f"Get known_user with id {result[0]}") + users.append(KnownUser(result[1], result[2], result[3], id=result[0])) return users def get_user_by_id(self, id: int) -> KnownUser: - self._logger.trace(__name__, f'Send SQL command: {KnownUser.get_select_by_id_string(id)}') + self._logger.trace(__name__, f"Send SQL command: {KnownUser.get_select_by_id_string(id)}") result = self._context.select(KnownUser.get_select_by_id_string(id)) - return KnownUser( - result[1], - result[2], - result[3], - id=result[0] - ) + return KnownUser(result[1], result[2], result[3], id=result[0]) def get_user_by_discord_id(self, discord_id: int) -> KnownUser: - self._logger.trace(__name__, f'Send SQL command: {KnownUser.get_select_by_discord_id_string(discord_id)}') - result = self._context.select(KnownUser.get_select_by_discord_id_string(discord_id))[0] - return KnownUser( - result[1], - result[2], - result[3], - id=result[0] + self._logger.trace( + __name__, + f"Send SQL command: {KnownUser.get_select_by_discord_id_string(discord_id)}", ) + result = self._context.select(KnownUser.get_select_by_discord_id_string(discord_id))[0] + return KnownUser(result[1], result[2], result[3], id=result[0]) def find_user_by_discord_id(self, discord_id: int) -> Optional[KnownUser]: - self._logger.trace(__name__, f'Send SQL command: {KnownUser.get_select_by_discord_id_string(discord_id)}') + self._logger.trace( + __name__, + f"Send SQL command: {KnownUser.get_select_by_discord_id_string(discord_id)}", + ) result = self._context.select(KnownUser.get_select_by_discord_id_string(discord_id)) if result is None or len(result) == 0: return None - + result = result[0] - - return KnownUser( - result[1], - result[2], - result[3], - id=result[0] - ) - + + return KnownUser(result[1], result[2], result[3], id=result[0]) + def add_user(self, known_user: KnownUser): - self._logger.trace(__name__, f'Send SQL command: {known_user.insert_string}') + self._logger.trace(__name__, f"Send SQL command: {known_user.insert_string}") self._context.cursor.execute(known_user.insert_string) - + def delete_user(self, known_user: KnownUser): - self._logger.trace(__name__, f'Send SQL command: {known_user.delete_string}') + self._logger.trace(__name__, f"Send SQL command: {known_user.delete_string}") self._context.cursor.execute(known_user.delete_string) diff --git a/kdb-bot/src/bot_data/service/level_repository_service.py b/kdb-bot/src/bot_data/service/level_repository_service.py index 3e41fc1b..c713c0da 100644 --- a/kdb-bot/src/bot_data/service/level_repository_service.py +++ b/kdb-bot/src/bot_data/service/level_repository_service.py @@ -10,8 +10,12 @@ from bot_data.model.level import Level class LevelRepositoryService(LevelRepositoryABC): - - def __init__(self, logger: DatabaseLogger, db_context: DatabaseContextABC, servers: ServerRepositoryABC): + def __init__( + self, + logger: DatabaseLogger, + db_context: DatabaseContextABC, + servers: ServerRepositoryABC, + ): self._logger = logger self._context = db_context @@ -21,7 +25,7 @@ class LevelRepositoryService(LevelRepositoryABC): @staticmethod def _get_value_from_result(value: any) -> Optional[any]: - if isinstance(value, str) and 'NULL' in value: + if isinstance(value, str) and "NULL" in value: return None return value @@ -33,27 +37,27 @@ class LevelRepositoryService(LevelRepositoryABC): int(self._get_value_from_result(sql_result[3])), # min xp int(self._get_value_from_result(sql_result[4])), # permissions self._servers.get_server_by_id(sql_result[5]), # server - id=self._get_value_from_result(sql_result[0]) # id + id=self._get_value_from_result(sql_result[0]), # id ) def get_levels(self) -> List[Level]: levels = List(Level) - self._logger.trace(__name__, f'Send SQL command: {Level.get_select_all_string()}') + self._logger.trace(__name__, f"Send SQL command: {Level.get_select_all_string()}") results = self._context.select(Level.get_select_all_string()) for result in results: - self._logger.trace(__name__, f'Get level with id {result[0]}') + self._logger.trace(__name__, f"Get level with id {result[0]}") levels.append(self._level_from_result(result)) return levels def get_level_by_id(self, id: int) -> Level: - self._logger.trace(__name__, f'Send SQL command: {Level.get_select_by_id_string(id)}') + self._logger.trace(__name__, f"Send SQL command: {Level.get_select_by_id_string(id)}") result = self._context.select(Level.get_select_by_id_string(id))[0] return self._level_from_result(result) def find_level_by_id(self, id: int) -> Optional[Level]: - self._logger.trace(__name__, f'Send SQL command: {Level.get_select_by_id_string(id)}') + self._logger.trace(__name__, f"Send SQL command: {Level.get_select_by_id_string(id)}") result = self._context.select(Level.get_select_by_id_string(id)) if result is None or len(result) == 0: return None @@ -62,36 +66,42 @@ class LevelRepositoryService(LevelRepositoryABC): def get_levels_by_server_id(self, server_id: int) -> List[Level]: levels = List(Level) - self._logger.trace(__name__, f'Send SQL command: {Level.get_select_by_server_id_string(server_id)}') + self._logger.trace( + __name__, + f"Send SQL command: {Level.get_select_by_server_id_string(server_id)}", + ) results = self._context.select(Level.get_select_by_server_id_string(server_id)) for result in results: - self._logger.trace(__name__, f'Get level with id {result[0]}') + self._logger.trace(__name__, f"Get level with id {result[0]}") levels.append(self._level_from_result(result)) return levels def find_levels_by_server_id(self, server_id: int) -> Optional[List[Level]]: levels = List(Level) - self._logger.trace(__name__, f'Send SQL command: {Level.get_select_by_server_id_string(server_id)}') + self._logger.trace( + __name__, + f"Send SQL command: {Level.get_select_by_server_id_string(server_id)}", + ) results = self._context.select(Level.get_select_by_server_id_string(server_id)) if results is None or len(results) == 0: return None for result in results: - self._logger.trace(__name__, f'Get level with id {result[0]}') + self._logger.trace(__name__, f"Get level with id {result[0]}") levels.append(self._level_from_result(result)) return levels def add_level(self, level: Level): - self._logger.trace(__name__, f'Send SQL command: {level.insert_string}') + self._logger.trace(__name__, f"Send SQL command: {level.insert_string}") self._context.cursor.execute(level.insert_string) def update_level(self, level: Level): - self._logger.trace(__name__, f'Send SQL command: {level.udpate_string}') + self._logger.trace(__name__, f"Send SQL command: {level.udpate_string}") self._context.cursor.execute(level.udpate_string) def delete_level(self, level: Level): - self._logger.trace(__name__, f'Send SQL command: {level.delete_string}') + self._logger.trace(__name__, f"Send SQL command: {level.delete_string}") self._context.cursor.execute(level.delete_string) diff --git a/kdb-bot/src/bot_data/service/migration_service.py b/kdb-bot/src/bot_data/service/migration_service.py index 9df395bf..7b924f90 100644 --- a/kdb-bot/src/bot_data/service/migration_service.py +++ b/kdb-bot/src/bot_data/service/migration_service.py @@ -10,16 +10,20 @@ from bot_data.model.migration_history import MigrationHistory class MigrationService: - - def __init__(self, logger: DatabaseLogger, services: ServiceProviderABC, db: DatabaseContextABC): + def __init__( + self, + logger: DatabaseLogger, + services: ServiceProviderABC, + db: DatabaseContextABC, + ): self._logger = logger self._services = services - + self._db = db self._cursor = db.cursor self._migrations = List(type, MigrationABC.__subclasses__()).order_by(lambda x: x.name) - + def migrate(self): self._logger.info(__name__, f"Running Migrations") for migration in self._migrations: @@ -30,11 +34,14 @@ class MigrationService: result = self._cursor.fetchone() if result: # there is a table named "tableName" - self._logger.trace(__name__, f"Running SQL Command: {MigrationHistory.get_select_by_id_string(migration_id)}") + self._logger.trace( + __name__, + f"Running SQL Command: {MigrationHistory.get_select_by_id_string(migration_id)}", + ) migration_from_db = self._db.select(MigrationHistory.get_select_by_id_string(migration_id)) if migration_from_db is not None and len(migration_from_db) > 0: continue - + self._logger.debug(__name__, f"Running Migration {migration_id}") migration_as_service: MigrationABC = self._services.get_service(migration) migration_as_service.upgrade() @@ -42,4 +49,4 @@ class MigrationService: self._db.save_changes() except Exception as e: - self._logger.error(__name__, f'Cannot get migration with id {migration}', e) + self._logger.error(__name__, f"Cannot get migration with id {migration}", e) diff --git a/kdb-bot/src/bot_data/service/seeder_service.py b/kdb-bot/src/bot_data/service/seeder_service.py index 6d0f9b7d..04e999cc 100644 --- a/kdb-bot/src/bot_data/service/seeder_service.py +++ b/kdb-bot/src/bot_data/service/seeder_service.py @@ -7,8 +7,12 @@ from bot_data.abc.data_seeder_abc import DataSeederABC class SeederService: - - def __init__(self, logger: DatabaseLogger, services: ServiceProviderABC, db: DatabaseContextABC): + def __init__( + self, + logger: DatabaseLogger, + services: ServiceProviderABC, + db: DatabaseContextABC, + ): self._logger = logger self._services = services diff --git a/kdb-bot/src/bot_data/service/server_repository_service.py b/kdb-bot/src/bot_data/service/server_repository_service.py index 210a6dee..ab6fbe84 100644 --- a/kdb-bot/src/bot_data/service/server_repository_service.py +++ b/kdb-bot/src/bot_data/service/server_repository_service.py @@ -11,7 +11,6 @@ from bot_data.model.server import Server class ServerRepositoryService(ServerRepositoryABC): - def __init__(self, logger: DatabaseLogger, db_context: DatabaseContextABC): self._logger = logger self._context = db_context @@ -20,23 +19,25 @@ class ServerRepositoryService(ServerRepositoryABC): def get_servers(self) -> List[Server]: servers = List(Server) - self._logger.trace(__name__, f'Send SQL command: {Server.get_select_all_string()}') + self._logger.trace(__name__, f"Send SQL command: {Server.get_select_all_string()}") results = self._context.select(Server.get_select_all_string()) for result in results: - servers.append(Server( - result[1], - id=result[0] - )) + servers.append(Server(result[1], id=result[0])) return servers def get_filtered_servers(self, criteria: ServerSelectCriteria) -> FilteredResult: servers = self.get_servers() - self._logger.trace(__name__, f'Send SQL command: {Server.get_select_all_string()}') + self._logger.trace(__name__, f"Send SQL command: {Server.get_select_all_string()}") query = servers # sort - if criteria.sort_column is not None and criteria.sort_column != '' and criteria.sort_direction is not None and criteria.sort_direction: + if ( + criteria.sort_column is not None + and criteria.sort_column != "" + and criteria.sort_direction is not None + and criteria.sort_direction + ): crit_sort_direction = criteria.sort_direction.lower() if crit_sort_direction == "desc" or crit_sort_direction == "descending": query = query.order_by_descending(lambda x: getattr(x, criteria.sort_column)) @@ -51,44 +52,39 @@ class ServerRepositoryService(ServerRepositoryABC): return result def get_server_by_id(self, server_id: int) -> Server: - self._logger.trace(__name__, f'Send SQL command: {Server.get_select_by_id_string(server_id)}') + self._logger.trace(__name__, f"Send SQL command: {Server.get_select_by_id_string(server_id)}") result = self._context.select(Server.get_select_by_id_string(server_id))[0] - return Server( - result[1], - id=result[0] - ) + return Server(result[1], id=result[0]) def get_server_by_discord_id(self, discord_id: int) -> Server: - self._logger.trace(__name__, f'Send SQL command: {Server.get_select_by_discord_id_string(discord_id)}') - result = self._context.select(Server.get_select_by_discord_id_string(discord_id))[0] - return Server( - result[1], - id=result[0] + self._logger.trace( + __name__, + f"Send SQL command: {Server.get_select_by_discord_id_string(discord_id)}", ) + result = self._context.select(Server.get_select_by_discord_id_string(discord_id))[0] + return Server(result[1], id=result[0]) def find_server_by_discord_id(self, discord_id: int) -> Optional[Server]: - self._logger.trace(__name__, f'Send SQL command: {Server.get_select_by_discord_id_string(discord_id)}') + self._logger.trace( + __name__, + f"Send SQL command: {Server.get_select_by_discord_id_string(discord_id)}", + ) result = self._context.select(Server.get_select_by_discord_id_string(discord_id)) if result is None or len(result) == 0: return None - + result = result[0] - - return Server( - result[1], - result[2], - result[3], - id=result[0] - ) - + + return Server(result[1], result[2], result[3], id=result[0]) + def add_server(self, server: Server): - self._logger.trace(__name__, f'Send SQL command: {server.insert_string}') + self._logger.trace(__name__, f"Send SQL command: {server.insert_string}") self._context.cursor.execute(server.insert_string) - + def update_server(self, server: Server): - self._logger.trace(__name__, f'Send SQL command: {server.udpate_string}') + self._logger.trace(__name__, f"Send SQL command: {server.udpate_string}") self._context.cursor.execute(server.udpate_string) - + def delete_server(self, server: Server): - self._logger.trace(__name__, f'Send SQL command: {server.delete_string}') + self._logger.trace(__name__, f"Send SQL command: {server.delete_string}") self._context.cursor.execute(server.delete_string) diff --git a/kdb-bot/src/bot_data/service/statistic_repository_service.py b/kdb-bot/src/bot_data/service/statistic_repository_service.py index 8f31dbe2..b425605e 100644 --- a/kdb-bot/src/bot_data/service/statistic_repository_service.py +++ b/kdb-bot/src/bot_data/service/statistic_repository_service.py @@ -11,8 +11,12 @@ from bot_data.model.statistic import Statistic class StatisticRepositoryService(StatisticRepositoryABC): - - def __init__(self, logger: DatabaseLogger, db_context: DatabaseContextABC, statistics: ServerRepositoryABC): + def __init__( + self, + logger: DatabaseLogger, + db_context: DatabaseContextABC, + statistics: ServerRepositoryABC, + ): self._logger = logger self._context = db_context @@ -22,7 +26,7 @@ class StatisticRepositoryService(StatisticRepositoryABC): @staticmethod def _get_value_from_result(value: any) -> Optional[any]: - if isinstance(value, str) and 'NULL' in value: + if isinstance(value, str) and "NULL" in value: return None return value @@ -37,14 +41,14 @@ class StatisticRepositoryService(StatisticRepositoryABC): self._get_value_from_result(sql_result[2]), code, self._statistics.get_server_by_id(sql_result[4]), - id=self._get_value_from_result(sql_result[0]) + id=self._get_value_from_result(sql_result[0]), ) return statistic def get_statistics(self) -> List[Statistic]: statistics = List(Statistic) - self._logger.trace(__name__, f'Send SQL command: {Statistic.get_select_all_string()}') + self._logger.trace(__name__, f"Send SQL command: {Statistic.get_select_all_string()}") results = self._context.select(Statistic.get_select_all_string()) for result in results: statistics.append(self._statistic_from_result(result)) @@ -53,7 +57,10 @@ class StatisticRepositoryService(StatisticRepositoryABC): def get_statistics_by_server_id(self, server_id: int) -> List[Statistic]: statistics = List(Statistic) - self._logger.trace(__name__, f'Send SQL command: {Statistic.get_select_by_server_string(server_id)}') + self._logger.trace( + __name__, + f"Send SQL command: {Statistic.get_select_by_server_string(server_id)}", + ) results = self._context.select(Statistic.get_select_by_server_string(server_id)) for result in results: statistics.append(self._statistic_from_result(result)) @@ -61,17 +68,23 @@ class StatisticRepositoryService(StatisticRepositoryABC): return statistics def get_statistic_by_id(self, id: int) -> Statistic: - self._logger.trace(__name__, f'Send SQL command: {Statistic.get_select_by_id_string(id)}') + self._logger.trace(__name__, f"Send SQL command: {Statistic.get_select_by_id_string(id)}") result = self._context.select(Statistic.get_select_by_id_string(id))[0] return self._statistic_from_result(result) def get_statistic_by_name(self, name: str, server_id: int) -> Statistic: - self._logger.trace(__name__, f'Send SQL command: {Statistic.get_select_by_name_string(name, server_id)}') + self._logger.trace( + __name__, + f"Send SQL command: {Statistic.get_select_by_name_string(name, server_id)}", + ) result = self._context.select(Statistic.get_select_by_name_string(name, server_id))[0] return self._statistic_from_result(result) def find_statistic_by_name(self, name: str, server_id: int) -> Optional[Statistic]: - self._logger.trace(__name__, f'Send SQL command: {Statistic.get_select_by_name_string(name, server_id)}') + self._logger.trace( + __name__, + f"Send SQL command: {Statistic.get_select_by_name_string(name, server_id)}", + ) result = self._context.select(Statistic.get_select_by_name_string(name, server_id)) if result is None or len(result) == 0: return None @@ -81,13 +94,13 @@ class StatisticRepositoryService(StatisticRepositoryABC): return self._statistic_from_result(result) def add_statistic(self, statistic: Statistic): - self._logger.trace(__name__, f'Send SQL command: {statistic.insert_string}') + self._logger.trace(__name__, f"Send SQL command: {statistic.insert_string}") self._context.cursor.execute(statistic.insert_string) def update_statistic(self, statistic: Statistic): - self._logger.trace(__name__, f'Send SQL command: {statistic.udpate_string}') + self._logger.trace(__name__, f"Send SQL command: {statistic.udpate_string}") self._context.cursor.execute(statistic.udpate_string) def delete_statistic(self, statistic: Statistic): - self._logger.trace(__name__, f'Send SQL command: {statistic.delete_string}') + self._logger.trace(__name__, f"Send SQL command: {statistic.delete_string}") self._context.cursor.execute(statistic.delete_string) diff --git a/kdb-bot/src/bot_data/service/user_joined_server_repository_service.py b/kdb-bot/src/bot_data/service/user_joined_server_repository_service.py index 29f4e50b..3c8a9d4b 100644 --- a/kdb-bot/src/bot_data/service/user_joined_server_repository_service.py +++ b/kdb-bot/src/bot_data/service/user_joined_server_repository_service.py @@ -4,15 +4,18 @@ from cpl_core.database.context import DatabaseContextABC from cpl_query.extension import List from bot_core.logging.database_logger import DatabaseLogger -from bot_data.abc.user_joined_server_repository_abc import \ - UserJoinedServerRepositoryABC +from bot_data.abc.user_joined_server_repository_abc import UserJoinedServerRepositoryABC from bot_data.abc.user_repository_abc import UserRepositoryABC from bot_data.model.user_joined_server import UserJoinedServer class UserJoinedServerRepositoryService(UserJoinedServerRepositoryABC): - - def __init__(self, logger: DatabaseLogger, db_context: DatabaseContextABC, users: UserRepositoryABC): + def __init__( + self, + logger: DatabaseLogger, + db_context: DatabaseContextABC, + users: UserRepositoryABC, + ): self._logger = logger self._context = db_context @@ -22,23 +25,28 @@ class UserJoinedServerRepositoryService(UserJoinedServerRepositoryABC): def get_user_joined_servers(self) -> List[UserJoinedServer]: joins = List(UserJoinedServer) - self._logger.trace(__name__, f'Send SQL command: {UserJoinedServer.get_select_all_string()}') + self._logger.trace(__name__, f"Send SQL command: {UserJoinedServer.get_select_all_string()}") results = self._context.select(UserJoinedServer.get_select_all_string()) for result in results: - self._logger.trace(__name__, f'Get user-joined-server with id {result[0]}') - joins.append(UserJoinedServer( - self._users.get_user_by_id(result[1]), - result[2], - result[3], - result[4], - result[5], - id=result[0] - )) + self._logger.trace(__name__, f"Get user-joined-server with id {result[0]}") + joins.append( + UserJoinedServer( + self._users.get_user_by_id(result[1]), + result[2], + result[3], + result[4], + result[5], + id=result[0], + ) + ) return joins - + def get_user_joined_server_by_id(self, id: int) -> UserJoinedServer: - self._logger.trace(__name__, f'Send SQL command: {UserJoinedServer.get_select_by_id_string(id)}') + self._logger.trace( + __name__, + f"Send SQL command: {UserJoinedServer.get_select_by_id_string(id)}", + ) result = self._context.select(UserJoinedServer.get_select_by_id_string(id))[0] return UserJoinedServer( self._users.get_user_by_id(result[1]), @@ -46,27 +54,35 @@ class UserJoinedServerRepositoryService(UserJoinedServerRepositoryABC): result[3], result[4], result[5], - id=result[0] + id=result[0], ) - + def get_user_joined_servers_by_user_id(self, user_id: int) -> List[UserJoinedServer]: joins = List(UserJoinedServer) - self._logger.trace(__name__, f'Send SQL command: {UserJoinedServer.get_select_by_user_id_string(user_id)}') + self._logger.trace( + __name__, + f"Send SQL command: {UserJoinedServer.get_select_by_user_id_string(user_id)}", + ) results = self._context.select(UserJoinedServer.get_select_by_user_id_string(user_id)) for result in results: - joins.append(UserJoinedServer( - self._users.get_user_by_id(result[1]), - result[2], - result[3], - result[4], - result[5], - id=result[0] - )) - + joins.append( + UserJoinedServer( + self._users.get_user_by_id(result[1]), + result[2], + result[3], + result[4], + result[5], + id=result[0], + ) + ) + return joins - + def get_active_user_joined_server_by_user_id(self, user_id: int) -> UserJoinedServer: - self._logger.trace(__name__, f'Send SQL command: {UserJoinedServer.get_select_by_user_id_string(user_id)}') + self._logger.trace( + __name__, + f"Send SQL command: {UserJoinedServer.get_select_by_user_id_string(user_id)}", + ) result = self._context.select(UserJoinedServer.get_select_active_by_user_id_string(user_id))[0] return UserJoinedServer( self._users.get_user_by_id(result[1]), @@ -74,11 +90,14 @@ class UserJoinedServerRepositoryService(UserJoinedServerRepositoryABC): result[3], result[4], result[5], - id=result[0] + id=result[0], ) - + def find_active_user_joined_server_by_user_id(self, user_id: int) -> Optional[UserJoinedServer]: - self._logger.trace(__name__, f'Send SQL command: {UserJoinedServer.get_select_by_user_id_string(user_id)}') + self._logger.trace( + __name__, + f"Send SQL command: {UserJoinedServer.get_select_by_user_id_string(user_id)}", + ) result = self._context.select(UserJoinedServer.get_select_active_by_user_id_string(user_id)) if result is None or len(result) == 0: return None @@ -91,17 +110,17 @@ class UserJoinedServerRepositoryService(UserJoinedServerRepositoryABC): result[3], result[4], result[5], - id=result[0] + id=result[0], ) - + def add_user_joined_server(self, user_joined_server: UserJoinedServer): - self._logger.trace(__name__, f'Send SQL command: {user_joined_server.insert_string}') + self._logger.trace(__name__, f"Send SQL command: {user_joined_server.insert_string}") self._context.cursor.execute(user_joined_server.insert_string) - + def update_user_joined_server(self, user_joined_server: UserJoinedServer): - self._logger.trace(__name__, f'Send SQL command: {user_joined_server.udpate_string}') + self._logger.trace(__name__, f"Send SQL command: {user_joined_server.udpate_string}") self._context.cursor.execute(user_joined_server.udpate_string) - + def delete_user_joined_server(self, user_joined_server: UserJoinedServer): - self._logger.trace(__name__, f'Send SQL command: {user_joined_server.delete_string}') + self._logger.trace(__name__, f"Send SQL command: {user_joined_server.delete_string}") self._context.cursor.execute(user_joined_server.delete_string) diff --git a/kdb-bot/src/bot_data/service/user_joined_voice_channel_service.py b/kdb-bot/src/bot_data/service/user_joined_voice_channel_repository_service.py similarity index 55% rename from kdb-bot/src/bot_data/service/user_joined_voice_channel_service.py rename to kdb-bot/src/bot_data/service/user_joined_voice_channel_repository_service.py index 919b2ee5..c441d26a 100644 --- a/kdb-bot/src/bot_data/service/user_joined_voice_channel_service.py +++ b/kdb-bot/src/bot_data/service/user_joined_voice_channel_repository_service.py @@ -4,14 +4,20 @@ from cpl_core.database.context import DatabaseContextABC from cpl_query.extension import List from bot_core.logging.database_logger import DatabaseLogger -from bot_data.abc.user_joined_voice_channel_abc import UserJoinedVoiceChannelRepositoryABC +from bot_data.abc.user_joined_voice_channel_repository_abc import ( + UserJoinedVoiceChannelRepositoryABC, +) from bot_data.abc.user_repository_abc import UserRepositoryABC from bot_data.model.user_joined_voice_channel import UserJoinedVoiceChannel class UserJoinedVoiceChannelRepositoryService(UserJoinedVoiceChannelRepositoryABC): - - def __init__(self, logger: DatabaseLogger, db_context: DatabaseContextABC, users: UserRepositoryABC): + def __init__( + self, + logger: DatabaseLogger, + db_context: DatabaseContextABC, + users: UserRepositoryABC, + ): self._logger = logger self._context = db_context @@ -21,23 +27,31 @@ class UserJoinedVoiceChannelRepositoryService(UserJoinedVoiceChannelRepositoryAB def get_user_joined_voice_channels(self) -> List[UserJoinedVoiceChannel]: joins = List(UserJoinedVoiceChannel) - self._logger.trace(__name__, f'Send SQL command: {UserJoinedVoiceChannel.get_select_all_string()}') + self._logger.trace( + __name__, + f"Send SQL command: {UserJoinedVoiceChannel.get_select_all_string()}", + ) results = self._context.select(UserJoinedVoiceChannel.get_select_all_string()) for result in results: - self._logger.trace(__name__, f'Get user-joined-voice-channel with id {result[0]}') - joins.append(UserJoinedVoiceChannel( - self._users.get_user_by_id(result[1]), - result[2], - result[3], - result[4], - result[5], - id=result[0] - )) + self._logger.trace(__name__, f"Get user-joined-voice-channel with id {result[0]}") + joins.append( + UserJoinedVoiceChannel( + self._users.get_user_by_id(result[1]), + result[2], + result[3], + result[4], + result[5], + id=result[0], + ) + ) return joins - + def get_user_joined_voice_channel_by_id(self, id: int) -> UserJoinedVoiceChannel: - self._logger.trace(__name__, f'Send SQL command: {UserJoinedVoiceChannel.get_select_by_id_string(id)}') + self._logger.trace( + __name__, + f"Send SQL command: {UserJoinedVoiceChannel.get_select_by_id_string(id)}", + ) result = self._context.select(UserJoinedVoiceChannel.get_select_by_id_string(id))[0] return UserJoinedVoiceChannel( self._users.get_user_by_id(result[1]), @@ -45,27 +59,35 @@ class UserJoinedVoiceChannelRepositoryService(UserJoinedVoiceChannelRepositoryAB result[3], result[4], result[5], - id=result[0] + id=result[0], ) - + def get_user_joined_voice_channels_by_user_id(self, user_id: int) -> List[UserJoinedVoiceChannel]: joins = List(UserJoinedVoiceChannel) - self._logger.trace(__name__, f'Send SQL command: {UserJoinedVoiceChannel.get_select_by_user_id_string(user_id)}') + self._logger.trace( + __name__, + f"Send SQL command: {UserJoinedVoiceChannel.get_select_by_user_id_string(user_id)}", + ) results = self._context.select(UserJoinedVoiceChannel.get_select_by_user_id_string(user_id)) for result in results: - joins.append(UserJoinedVoiceChannel( - self._users.get_user_by_id(result[1]), - result[2], - result[3], - result[4], - result[5], - id=result[0] - )) - + joins.append( + UserJoinedVoiceChannel( + self._users.get_user_by_id(result[1]), + result[2], + result[3], + result[4], + result[5], + id=result[0], + ) + ) + return joins - + def get_active_user_joined_voice_channel_by_user_id(self, user_id: int) -> UserJoinedVoiceChannel: - self._logger.trace(__name__, f'Send SQL command: {UserJoinedVoiceChannel.get_select_by_user_id_string(user_id)}') + self._logger.trace( + __name__, + f"Send SQL command: {UserJoinedVoiceChannel.get_select_by_user_id_string(user_id)}", + ) result = self._context.select(UserJoinedVoiceChannel.get_select_active_by_user_id_string(user_id))[0] return UserJoinedVoiceChannel( self._users.get_user_by_id(result[1]), @@ -73,11 +95,14 @@ class UserJoinedVoiceChannelRepositoryService(UserJoinedVoiceChannelRepositoryAB result[3], result[4], result[5], - id=result[0] + id=result[0], ) - + def find_active_user_joined_voice_channel_by_user_id(self, user_id: int) -> Optional[UserJoinedVoiceChannel]: - self._logger.trace(__name__, f'Send SQL command: {UserJoinedVoiceChannel.get_select_by_user_id_string(user_id)}') + self._logger.trace( + __name__, + f"Send SQL command: {UserJoinedVoiceChannel.get_select_by_user_id_string(user_id)}", + ) result = self._context.select(UserJoinedVoiceChannel.get_select_active_by_user_id_string(user_id)) if result is None or len(result) == 0: return None @@ -90,38 +115,46 @@ class UserJoinedVoiceChannelRepositoryService(UserJoinedVoiceChannelRepositoryAB result[3], result[4], result[5], - id=result[0] + id=result[0], ) def find_active_user_joined_voice_channels_by_user_id(self, user_id: int) -> List[Optional[UserJoinedVoiceChannel]]: - self._logger.trace(__name__, f'Send SQL command: {UserJoinedVoiceChannel.get_select_by_user_id_string(user_id)}') + self._logger.trace( + __name__, + f"Send SQL command: {UserJoinedVoiceChannel.get_select_active_by_user_id_string(user_id)}", + ) result = List(UserJoinedVoiceChannel) db_results = self._context.select(UserJoinedVoiceChannel.get_select_active_by_user_id_string(user_id)) for db_result in db_results: - result.append(UserJoinedVoiceChannel( - self._users.get_user_by_id(db_result[1]), - db_result[2], - db_result[3], - db_result[4], - db_result[5], - id=db_result[0] - )) + result.append( + UserJoinedVoiceChannel( + self._users.get_user_by_id(db_result[1]), + db_result[2], + db_result[3], + db_result[4], + db_result[5], + id=db_result[0], + ) + ) return result - + def add_user_joined_voice_channel(self, user_joined_voice_channel: UserJoinedVoiceChannel): - self._logger.trace(__name__, f'Send SQL command: {user_joined_voice_channel.insert_string}') + self._logger.trace(__name__, f"Send SQL command: {user_joined_voice_channel.insert_string}") self._context.cursor.execute(user_joined_voice_channel.insert_string) - + def update_user_joined_voice_channel(self, user_joined_voice_channel: UserJoinedVoiceChannel): - self._logger.trace(__name__, f'Send SQL command: {user_joined_voice_channel.udpate_string}') + self._logger.trace(__name__, f"Send SQL command: {user_joined_voice_channel.udpate_string}") self._context.cursor.execute(user_joined_voice_channel.udpate_string) - + def delete_user_joined_voice_channel(self, user_joined_voice_channel: UserJoinedVoiceChannel): - self._logger.trace(__name__, f'Send SQL command: {user_joined_voice_channel.delete_string}') + self._logger.trace(__name__, f"Send SQL command: {user_joined_voice_channel.delete_string}") self._context.cursor.execute(user_joined_voice_channel.delete_string) def delete_user_joined_voice_channel_by_user_id(self, user_id: int): - self._logger.trace(__name__, f'Send SQL command: {UserJoinedVoiceChannel.delete_by_user_id_string}') + self._logger.trace( + __name__, + f"Send SQL command: {UserJoinedVoiceChannel.delete_by_user_id_string}", + ) self._context.cursor.execute(UserJoinedVoiceChannel.delete_by_user_id_string(user_id)) diff --git a/kdb-bot/src/bot_data/service/user_message_count_per_hour_repository_service.py b/kdb-bot/src/bot_data/service/user_message_count_per_hour_repository_service.py new file mode 100644 index 00000000..e63db818 --- /dev/null +++ b/kdb-bot/src/bot_data/service/user_message_count_per_hour_repository_service.py @@ -0,0 +1,107 @@ +from datetime import datetime +from typing import Optional + +from cpl_core.database.context import DatabaseContextABC +from cpl_query.extension import List + +from bot_core.logging.database_logger import DatabaseLogger +from bot_data.abc.user_message_count_per_hour_repository_abc import ( + UserMessageCountPerHourRepositoryABC, +) +from bot_data.abc.user_repository_abc import UserRepositoryABC +from bot_data.model.user_message_count_per_hour import UserMessageCountPerHour + + +class UserMessageCountPerHourRepositoryService(UserMessageCountPerHourRepositoryABC): + def __init__( + self, + logger: DatabaseLogger, + db_context: DatabaseContextABC, + users: UserRepositoryABC, + ): + UserMessageCountPerHourRepositoryABC.__init__(self) + + self._logger = logger + self._context = db_context + self._users = users + + @staticmethod + def _get_value_from_result(value: any) -> Optional[any]: + if isinstance(value, str) and "NULL" in value: + return None + + return value + + def _from_result(self, result: tuple) -> UserMessageCountPerHour: + return UserMessageCountPerHour( + self._get_value_from_result(result[1]), + self._get_value_from_result(result[2]), + self._get_value_from_result(result[3]), + self._users.get_user_by_id(self._get_value_from_result(result[4])), + self._get_value_from_result(result[5]), + self._get_value_from_result(result[6]), + id=self._get_value_from_result(result[0]), + ) + + def get_user_message_count_per_hours(self) -> List[UserMessageCountPerHour]: + umcphs = List(UserMessageCountPerHour) + self._logger.trace( + __name__, + f"Send SQL command: {UserMessageCountPerHour.get_select_all_string()}", + ) + results = self._context.select(UserMessageCountPerHour.get_select_all_string()) + for result in results: + self._logger.trace(__name__, f"Get user message count per hour with id {result[0]}") + umcphs.append(self._from_result(result)) + + return umcphs + + def find_user_message_count_per_hour_by_user_id(self, user_id: int) -> List[Optional[UserMessageCountPerHour]]: + umcphs = List(UserMessageCountPerHour) + sql = UserMessageCountPerHour.get_select_by_user_id_string(user_id) + self._logger.trace(__name__, f"Send SQL command: {sql}") + results = self._context.select(sql) + if results is None or len(results) == 0: + return umcphs + + for result in results: + self._logger.trace(__name__, f"Get user message count per hour with id {result[0]}") + umcphs.append(self._from_result(result)) + + return umcphs + + def get_user_message_count_per_hour_by_user_id_and_date( + self, user_id: int, date: datetime + ) -> UserMessageCountPerHour: + sql = UserMessageCountPerHour.get_select_by_user_id_and_date_string(user_id, date) + self._logger.trace(__name__, f"Send SQL command: {sql}") + result = self._context.select(sql)[0] + return self._from_result(result) + + def find_user_message_count_per_hour_by_user_id_and_date( + self, user_id: int, date: datetime + ) -> Optional[UserMessageCountPerHour]: + sql = UserMessageCountPerHour.get_select_by_user_id_and_date_string(user_id, date) + self._logger.trace(__name__, f"Send SQL command: {sql}") + result = self._context.select(sql) + if result is None or len(result) == 0: + return None + + return self._from_result(result[0]) + + def add_user_message_count_per_hour(self, umcph: UserMessageCountPerHour): + self._logger.trace(__name__, f"Send SQL command: {umcph.insert_string}") + self._context.cursor.execute(umcph.insert_string) + + def update_user_message_count_per_hour(self, umcph: UserMessageCountPerHour): + self._logger.trace(__name__, f"Send SQL command: {umcph.udpate_string}") + self._context.cursor.execute(umcph.udpate_string) + + def delete_user_message_count_per_hour(self, umcph: UserMessageCountPerHour): + self._logger.trace(__name__, f"Send SQL command: {umcph.delete_string}") + self._context.cursor.execute(umcph.delete_string) + + def delete_user_message_count_per_hour_by_user_id(self, user_id: int): + sql = UserMessageCountPerHour.delete_by_user_id_string(user_id) + self._logger.trace(__name__, f"Send SQL command: {sql}") + self._context.cursor.execute(sql) diff --git a/kdb-bot/src/bot_data/service/user_repository_service.py b/kdb-bot/src/bot_data/service/user_repository_service.py index 83f98627..00ee4a64 100644 --- a/kdb-bot/src/bot_data/service/user_repository_service.py +++ b/kdb-bot/src/bot_data/service/user_repository_service.py @@ -10,8 +10,12 @@ from bot_data.model.user import User class UserRepositoryService(UserRepositoryABC): - - def __init__(self, logger: DatabaseLogger, db_context: DatabaseContextABC, servers: ServerRepositoryABC): + def __init__( + self, + logger: DatabaseLogger, + db_context: DatabaseContextABC, + servers: ServerRepositoryABC, + ): self._logger = logger self._context = db_context @@ -21,32 +25,34 @@ class UserRepositoryService(UserRepositoryABC): def get_users(self) -> List[User]: users = List(User) - self._logger.trace(__name__, f'Send SQL command: {User.get_select_all_string()}') + self._logger.trace(__name__, f"Send SQL command: {User.get_select_all_string()}") results = self._context.select(User.get_select_all_string()) for result in results: - self._logger.trace(__name__, f'Get user with id {result[0]}') - users.append(User( - result[1], - result[2], - self._servers.get_server_by_id(result[3]), - id=result[0] - )) + self._logger.trace(__name__, f"Get user with id {result[0]}") + users.append( + User( + result[1], + result[2], + self._servers.get_server_by_id(result[3]), + id=result[0], + ) + ) return users def get_user_by_id(self, id: int) -> User: - self._logger.trace(__name__, f'Send SQL command: {User.get_select_by_id_string(id)}') + self._logger.trace(__name__, f"Send SQL command: {User.get_select_by_id_string(id)}") result = self._context.select(User.get_select_by_id_string(id))[0] return User( result[1], result[2], self._servers.get_server_by_id(result[3]), - id=result[0] + id=result[0], ) def find_user_by_id(self, id: int) -> Optional[User]: - self._logger.trace(__name__, f'Send SQL command: {User.get_select_by_id_string(id)}') + self._logger.trace(__name__, f"Send SQL command: {User.get_select_by_id_string(id)}") result = self._context.select(User.get_select_by_id_string(id)) if result is None or len(result) == 0: return None @@ -57,59 +63,70 @@ class UserRepositoryService(UserRepositoryABC): result[1], result[2], self._servers.get_server_by_id(result[3]), - id=result[0] + id=result[0], ) - + def get_users_by_discord_id(self, discord_id: int) -> List[User]: users = List(User) - self._logger.trace(__name__, f'Send SQL command: {User.get_select_by_discord_id_string(discord_id)}') + self._logger.trace( + __name__, + f"Send SQL command: {User.get_select_by_discord_id_string(discord_id)}", + ) results = self._context.select(User.get_select_by_discord_id_string(discord_id)) for result in results: - users.append(User( - result[1], - result[2], - self._servers.get_server_by_id(result[3]), - id=result[0] - )) + users.append( + User( + result[1], + result[2], + self._servers.get_server_by_id(result[3]), + id=result[0], + ) + ) return users def get_user_by_discord_id_and_server_id(self, discord_id: int, server_id: int) -> User: - self._logger.trace(__name__, f'Send SQL command: {User.get_select_by_discord_id_and_server_id_string(discord_id, server_id)}') + self._logger.trace( + __name__, + f"Send SQL command: {User.get_select_by_discord_id_and_server_id_string(discord_id, server_id)}", + ) result = self._context.select(User.get_select_by_discord_id_and_server_id_string(discord_id, server_id))[0] - + return User( result[1], result[2], self._servers.get_server_by_id(result[3]), - id=result[0] + id=result[0], ) def find_user_by_discord_id_and_server_id(self, discord_id: int, server_id: int) -> Optional[User]: - self._logger.trace(__name__, f'Send SQL command: {User.get_select_by_discord_id_and_server_id_string(discord_id, server_id)}') + self._logger.trace( + __name__, + f"Send SQL command: {User.get_select_by_discord_id_and_server_id_string(discord_id, server_id)}", + ) result = self._context.select(User.get_select_by_discord_id_and_server_id_string(discord_id, server_id)) if result is None or len(result) == 0: return None - + result = result[0] - + return User( result[1], result[2], self._servers.get_server_by_id(result[3]), result[4], result[5], - id=result[0] + id=result[0], ) - + def add_user(self, user: User): - self._logger.trace(__name__, f'Send SQL command: {user.insert_string}') + self._logger.trace(__name__, f"Send SQL command: {user.insert_string}") self._context.cursor.execute(user.insert_string) - + def update_user(self, user: User): - self._logger.trace(__name__, f'Send SQL command: {user.udpate_string}') + self._logger.trace(__name__, f"Send SQL command: {user.udpate_string}") self._context.cursor.execute(user.udpate_string) - + def delete_user(self, user: User): - self._logger.trace(__name__, f'Send SQL command: {user.delete_string}') + self._logger.trace(__name__, f"Send SQL command: {user.delete_string}") self._context.cursor.execute(user.delete_string) diff --git a/kdb-bot/src/modules/auto_role/__init__.py b/kdb-bot/src/modules/auto_role/__init__.py index bb9a5a5f..26774771 100644 --- a/kdb-bot/src/modules/auto_role/__init__.py +++ b/kdb-bot/src/modules/auto_role/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'modules.auto_role' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "modules.auto_role" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple -# imports: +# imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/modules/auto_role/auto-role.json b/kdb-bot/src/modules/auto_role/auto-role.json index 2bbe5511..ef61114c 100644 --- a/kdb-bot/src/modules/auto_role/auto-role.json +++ b/kdb-bot/src/modules/auto_role/auto-role.json @@ -4,7 +4,7 @@ "Version": { "Major": "0", "Minor": "3", - "Micro": "0" + "Micro": "1" }, "Author": "", "AuthorEmail": "", diff --git a/kdb-bot/src/modules/auto_role/auto_role_module.py b/kdb-bot/src/modules/auto_role/auto_role_module.py index f4528625..e23085f3 100644 --- a/kdb-bot/src/modules/auto_role/auto_role_module.py +++ b/kdb-bot/src/modules/auto_role/auto_role_module.py @@ -7,13 +7,16 @@ from cpl_discord.service.discord_collection_abc import DiscordCollectionABC from bot_core.abc.module_abc import ModuleABC from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum from modules.auto_role.command.auto_role_group import AutoRoleGroup -from modules.auto_role.events.auto_role_on_raw_reaction_add import AutoRoleOnRawReactionAddEvent -from modules.auto_role.events.auto_role_on_raw_reaction_remove import AutoRoleOnRawReactionRemoveEvent +from modules.auto_role.events.auto_role_on_raw_reaction_add import ( + AutoRoleOnRawReactionAddEvent, +) +from modules.auto_role.events.auto_role_on_raw_reaction_remove import ( + AutoRoleOnRawReactionRemoveEvent, +) from modules.auto_role.helper.auto_role_reaction_handler import AutoRoleReactionHandler class AutoRoleModule(ModuleABC): - def __init__(self, dc: DiscordCollectionABC): ModuleABC.__init__(self, dc, FeatureFlagsEnum.auto_role_module) @@ -25,5 +28,11 @@ class AutoRoleModule(ModuleABC): # commands self._dc.add_command(AutoRoleGroup) # events - self._dc.add_event(DiscordEventTypesEnum.on_raw_reaction_add.value, AutoRoleOnRawReactionAddEvent) - self._dc.add_event(DiscordEventTypesEnum.on_raw_reaction_remove.value, AutoRoleOnRawReactionRemoveEvent) + self._dc.add_event( + DiscordEventTypesEnum.on_raw_reaction_add.value, + AutoRoleOnRawReactionAddEvent, + ) + self._dc.add_event( + DiscordEventTypesEnum.on_raw_reaction_remove.value, + AutoRoleOnRawReactionRemoveEvent, + ) diff --git a/kdb-bot/src/modules/auto_role/command/__init__.py b/kdb-bot/src/modules/auto_role/command/__init__.py index 580fe9f1..b43b61ee 100644 --- a/kdb-bot/src/modules/auto_role/command/__init__.py +++ b/kdb-bot/src/modules/auto_role/command/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'modules.auto_role.command' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "modules.auto_role.command" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/modules/auto_role/command/auto_role_group.py b/kdb-bot/src/modules/auto_role/command/auto_role_group.py index fd636bf3..947dc8bd 100644 --- a/kdb-bot/src/modules/auto_role/command/auto_role_group.py +++ b/kdb-bot/src/modules/auto_role/command/auto_role_group.py @@ -11,7 +11,7 @@ from discord import app_commands, Guild from discord.ext import commands from discord.ext.commands import Context -from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC +from bot_core.abc.client_utils_abc import ClientUtilsABC from bot_core.abc.message_service_abc import MessageServiceABC from bot_core.helper.command_checks import CommandChecks from bot_core.logging.command_logger import CommandLogger @@ -23,18 +23,17 @@ from modules.permission.abc.permission_service_abc import PermissionServiceABC class AutoRoleGroup(DiscordCommandABC): - def __init__( - self, - logger: CommandLogger, - message_service: MessageServiceABC, - bot: DiscordBotServiceABC, - client_utils: ClientUtilsServiceABC, - translate: TranslatePipe, - servers: ServerRepositoryABC, - auto_roles: AutoRoleRepositoryABC, - db_context: DatabaseContextABC, - permission_service: PermissionServiceABC, + self, + logger: CommandLogger, + message_service: MessageServiceABC, + bot: DiscordBotServiceABC, + client_utils: ClientUtilsABC, + translate: TranslatePipe, + servers: ServerRepositoryABC, + auto_roles: AutoRoleRepositoryABC, + db_context: DatabaseContextABC, + permission_service: PermissionServiceABC, ): DiscordCommandABC.__init__(self) @@ -48,83 +47,111 @@ class AutoRoleGroup(DiscordCommandABC): self._db_context = db_context self._permissions = permission_service - self._logger.trace(__name__, f'Loaded command service: {type(self).__name__}') + self._logger.trace(__name__, f"Loaded command service: {type(self).__name__}") - async def _auto_role_auto_complete(self, interaction: discord.Interaction, current: str) -> TList[app_commands.Choice[str]]: + async def _auto_role_auto_complete( + self, interaction: discord.Interaction, current: str + ) -> TList[app_commands.Choice[str]]: server = self._servers.get_server_by_discord_id(interaction.guild.id) auto_roles = self._auto_roles.get_auto_roles_by_server_id(server.server_id).select(lambda x: x.auto_role_id) - return [app_commands.Choice(name=auto_role, value=auto_role) for auto_role in self._client_utils.get_auto_complete_list(auto_roles, current)] + return [ + app_commands.Choice(name=auto_role, value=auto_role) + for auto_role in self._client_utils.get_auto_complete_list(auto_roles, current) + ] @commands.hybrid_group(name="auto-role") @commands.guild_only() async def auto_role(self, ctx: Context): pass - @auto_role.command(alias='auto-roles') + @auto_role.command(alias="auto-roles") @commands.guild_only() @CommandChecks.check_is_ready() @CommandChecks.check_is_member_moderator() async def list(self, ctx: Context, wait: int = None): - self._logger.debug(__name__, f'Received command auto-role list {ctx}') + self._logger.debug(__name__, f"Received command auto-role list {ctx}") if ctx.guild is None: return embed = discord.Embed( - title=self._t.transform('modules.auto_role.list.title'), - description=self._t.transform('modules.auto_role.list.description'), - color=int('ef9d0d', 16) + title=self._t.transform("modules.auto_role.list.title"), + description=self._t.transform("modules.auto_role.list.description"), + color=int("ef9d0d", 16), ) server = self._servers.get_server_by_discord_id(ctx.guild.id) auto_roles = self._auto_roles.get_auto_roles_by_server_id(server.server_id) if auto_roles.count() < 1: - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.auto_role.error.nothing_found')) - self._logger.trace(__name__, f'Finished command auto-role list') + await self._message_service.send_ctx_msg(ctx, self._t.transform("modules.auto_role.error.nothing_found")) + self._logger.trace(__name__, f"Finished command auto-role list") return - auto_role_id = '' - message_id = '' + auto_role_id = "" + message_id = "" for auto_role in auto_roles: - auto_role_id += f'\n{auto_role.auto_role_id}' - message_id += f'\n{auto_role.discord_message_id}' + auto_role_id += f"\n{auto_role.auto_role_id}" + message_id += f"\n{auto_role.discord_message_id}" - embed.add_field(name=self._t.transform('modules.auto_role.list.auto_role_id'), value=auto_role_id, inline=True) - embed.add_field(name=self._t.transform('modules.auto_role.list.message_id'), value=message_id, inline=True) + embed.add_field( + name=self._t.transform("modules.auto_role.list.auto_role_id"), + value=auto_role_id, + inline=True, + ) + embed.add_field( + name=self._t.transform("modules.auto_role.list.message_id"), + value=message_id, + inline=True, + ) await self._message_service.send_ctx_msg(ctx, embed, wait_before_delete=wait) - self._logger.trace(__name__, f'Finished command auto-role list') + self._logger.trace(__name__, f"Finished command auto-role list") @auto_role.command() @commands.guild_only() @CommandChecks.check_is_ready() @CommandChecks.check_is_member_moderator() async def add(self, ctx: Context, channel: discord.TextChannel, message_id: str): - self._logger.debug(__name__, f'Received command auto-role add {ctx} {message_id}') + self._logger.debug(__name__, f"Received command auto-role add {ctx} {message_id}") - message = List(discord.Message, [message async for message in channel.history(limit=50)]).where(lambda m: m.id == int(message_id)).single_or_default() + message = ( + List( + discord.Message, + [message async for message in channel.history(limit=50)], + ) + .where(lambda m: m.id == int(message_id)) + .single_or_default() + ) if message is None: - self._logger.debug(__name__, f'Message with id {message_id} not found in {channel.name}') - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.auto_role.add.error.not_found').format(message_id, channel.mention)) - self._logger.trace(__name__, f'Finished command auto-role add') + self._logger.debug(__name__, f"Message with id {message_id} not found in {channel.name}") + await self._message_service.send_ctx_msg( + ctx, + self._t.transform("modules.auto_role.add.error.not_found").format(message_id, channel.mention), + ) + self._logger.trace(__name__, f"Finished command auto-role add") return if self._auto_roles.find_auto_role_by_message_id(int(message_id)) is not None: - self._logger.debug(__name__, f'auto-role for message {message_id} already exists') - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.auto_role.add.error.already_exists').format(message_id)) - self._logger.trace(__name__, f'Finished command auto-role add') + self._logger.debug(__name__, f"auto-role for message {message_id} already exists") + await self._message_service.send_ctx_msg( + ctx, + self._t.transform("modules.auto_role.add.error.already_exists").format(message_id), + ) + self._logger.trace(__name__, f"Finished command auto-role add") return server_id = self._servers.get_server_by_discord_id(ctx.guild.id).server_id self._auto_roles.add_auto_role(AutoRole(server_id, int(channel.id), int(message_id))) self._db_context.save_changes() - self._logger.info(__name__, f'Saved auto-role for message {message_id} at server {server_id}') - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.auto_role.add.success').format(message_id)) - self._logger.trace(__name__, f'Finished command auto-role add') + self._logger.info(__name__, f"Saved auto-role for message {message_id} at server {server_id}") + await self._message_service.send_ctx_msg( + ctx, self._t.transform("modules.auto_role.add.success").format(message_id) + ) + self._logger.trace(__name__, f"Finished command auto-role add") - @add.autocomplete('message_id') + @add.autocomplete("message_id") async def add_autocomplete(self, interaction: discord.Interaction, current: str) -> TList[app_commands.Choice[str]]: channel = discord.utils.get(interaction.guild.text_channels, id=interaction.channel_id) try: - channel_from_data = interaction.data['options'][0]['options'][0]['value'] + channel_from_data = interaction.data["options"][0]["options"][0]["value"] found_channel = discord.utils.get(interaction.guild.text_channels, id=int(channel_from_data)) if found_channel is not None: channel = found_channel @@ -132,34 +159,45 @@ class AutoRoleGroup(DiscordCommandABC): pass messages = [message async for message in channel.history(limit=10)] - return [app_commands.Choice(name=f'{message.author}@{message.created_at}', value=str(message.id)) for message in messages if current in str(message.id)] + return [ + app_commands.Choice(name=f"{message.author}@{message.created_at}", value=str(message.id)) + for message in messages + if current in str(message.id) + ] @auto_role.command() @commands.guild_only() @CommandChecks.check_is_ready() @CommandChecks.check_is_member_moderator() async def remove(self, ctx: Context, auto_role: int): - self._logger.debug(__name__, f'Received command auto-role remove {ctx} {auto_role}') + self._logger.debug(__name__, f"Received command auto-role remove {ctx} {auto_role}") auto_role_from_db = self._auto_roles.find_auto_role_by_id(auto_role) if auto_role_from_db is None: - self._logger.debug(__name__, f'auto-role {auto_role} not found') - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.auto_role.remove.error.not_found').format(auto_role)) - self._logger.trace(__name__, f'Finished command auto-role remove') + self._logger.debug(__name__, f"auto-role {auto_role} not found") + await self._message_service.send_ctx_msg( + ctx, + self._t.transform("modules.auto_role.remove.error.not_found").format(auto_role), + ) + self._logger.trace(__name__, f"Finished command auto-role remove") return for rule in self._auto_roles.get_auto_role_rules_by_auto_role_id(auto_role_from_db.auto_role_id): self._auto_roles.delete_auto_role_rule(rule) - self._logger.info(__name__, f'Removed auto-role rule {rule.role_id}') + self._logger.info(__name__, f"Removed auto-role rule {rule.role_id}") self._auto_roles.delete_auto_role(auto_role_from_db) self._db_context.save_changes() - self._logger.info(__name__, f'Removed auto-role {auto_role}') - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.auto_role.remove.success').format(auto_role)) - self._logger.trace(__name__, f'Finished command auto-role remove') + self._logger.info(__name__, f"Removed auto-role {auto_role}") + await self._message_service.send_ctx_msg( + ctx, self._t.transform("modules.auto_role.remove.success").format(auto_role) + ) + self._logger.trace(__name__, f"Finished command auto-role remove") - @remove.autocomplete('auto_role') - async def remove_autocomplete(self, interaction: discord.Interaction, current: str) -> TList[app_commands.Choice[str]]: + @remove.autocomplete("auto_role") + async def remove_autocomplete( + self, interaction: discord.Interaction, current: str + ) -> TList[app_commands.Choice[str]]: return await self._auto_role_auto_complete(interaction, current) @auto_role.group() @@ -167,40 +205,56 @@ class AutoRoleGroup(DiscordCommandABC): async def rule(self, ctx: Context): pass - @rule.command(alias='rules') + @rule.command(alias="rules") @commands.guild_only() @CommandChecks.check_is_ready() @CommandChecks.check_is_member_moderator() async def list(self, ctx: Context, auto_role: int, wait: int = None): - self._logger.debug(__name__, f'Received command auto-role rule list {ctx}') + self._logger.debug(__name__, f"Received command auto-role rule list {ctx}") embed = discord.Embed( - title=self._t.transform('modules.auto_role.list.title'), - description=self._t.transform('modules.auto_role.list.description'), - color=int('ef9d0d', 16) + title=self._t.transform("modules.auto_role.list.title"), + description=self._t.transform("modules.auto_role.list.description"), + color=int("ef9d0d", 16), ) rules = self._auto_roles.get_auto_role_rules_by_auto_role_id(auto_role) if rules.count() < 1: - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.auto_role.rule.error.id_not_found')) - self._logger.trace(__name__, f'Finished command auto-role rule list') + await self._message_service.send_ctx_msg( + ctx, self._t.transform("modules.auto_role.rule.error.id_not_found") + ) + self._logger.trace(__name__, f"Finished command auto-role rule list") return - auto_role_rule_id = '' - emoji = '' - role = '' + auto_role_rule_id = "" + emoji = "" + role = "" for rule in rules: - auto_role_rule_id += f'\n{rule.role_id}' - emoji += f'\n{rule.emoji_name}' - role += f'\n{ctx.guild.get_role(rule.role_id)}' + auto_role_rule_id += f"\n{rule.role_id}" + emoji += f"\n{rule.emoji_name}" + role += f"\n{ctx.guild.get_role(rule.role_id)}" - embed.add_field(name=self._t.transform('modules.auto_role.rule.list.auto_role_rule_id'), value=auto_role_rule_id, inline=True) - embed.add_field(name=self._t.transform('modules.auto_role.rule.list.emoji'), value=emoji, inline=True) - embed.add_field(name=self._t.transform('modules.auto_role.rule.list.role'), value=role, inline=True) + embed.add_field( + name=self._t.transform("modules.auto_role.rule.list.auto_role_rule_id"), + value=auto_role_rule_id, + inline=True, + ) + embed.add_field( + name=self._t.transform("modules.auto_role.rule.list.emoji"), + value=emoji, + inline=True, + ) + embed.add_field( + name=self._t.transform("modules.auto_role.rule.list.role"), + value=role, + inline=True, + ) await self._message_service.send_ctx_msg(ctx, embed, wait_before_delete=wait) - self._logger.trace(__name__, f'Finished command auto-role rule list') + self._logger.trace(__name__, f"Finished command auto-role rule list") - @list.autocomplete('auto_role') - async def list_autocomplete(self, interaction: discord.Interaction, current: str) -> TList[app_commands.Choice[str]]: + @list.autocomplete("auto_role") + async def list_autocomplete( + self, interaction: discord.Interaction, current: str + ) -> TList[app_commands.Choice[str]]: return await self._auto_role_auto_complete(interaction, current) @rule.command() @@ -208,36 +262,57 @@ class AutoRoleGroup(DiscordCommandABC): @CommandChecks.check_is_ready() @CommandChecks.check_is_member_moderator() async def add(self, ctx: Context, auto_role: int, emoji_name: str, role_id: str): - self._logger.debug(__name__, f'Received command auto-role add {ctx} {auto_role}') + self._logger.debug(__name__, f"Received command auto-role add {ctx} {auto_role}") emoji = discord.utils.get(self._bot.emojis, name=emoji_name) if emoji is None: - self._logger.debug(__name__, f'auto-role rule add emoji {emoji_name} not found') - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.auto_role.rule.add.error.emoji_not_found').format(emoji_name, auto_role)) - self._logger.trace(__name__, f'Finished command auto-role add') + self._logger.debug(__name__, f"auto-role rule add emoji {emoji_name} not found") + await self._message_service.send_ctx_msg( + ctx, + self._t.transform("modules.auto_role.rule.add.error.emoji_not_found").format(emoji_name, auto_role), + ) + self._logger.trace(__name__, f"Finished command auto-role add") return role = ctx.guild.get_role(int(role_id)) if role is None: - self._logger.debug(__name__, f'auto-role rule add role {role_id} not found') - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.auto_role.rule.add.error.role_not_found').format(role_id, auto_role)) - self._logger.trace(__name__, f'Finished command auto-role add') + self._logger.debug(__name__, f"auto-role rule add role {role_id} not found") + await self._message_service.send_ctx_msg( + ctx, + self._t.transform("modules.auto_role.rule.add.error.role_not_found").format(role_id, auto_role), + ) + self._logger.trace(__name__, f"Finished command auto-role add") return auto_role_from_db = self._auto_roles.get_auto_role_by_id(auto_role) if auto_role_from_db is None: - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.auto_role.remove.error.not_found').format(auto_role)) - self._logger.trace(__name__, f'Finished command auto-role rule add') + await self._message_service.send_ctx_msg( + ctx, + self._t.transform("modules.auto_role.remove.error.not_found").format(auto_role), + ) + self._logger.trace(__name__, f"Finished command auto-role rule add") return - if self._auto_roles.get_auto_role_rules_by_auto_role_id(auto_role).where(lambda r: r.emoji_name == emoji.name and int(role_id) == role.id).first_or_default() is not None: - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.auto_role.add.error.already_exists').format(auto_role)) - self._logger.trace(__name__, f'Finished command auto-role rule add') + if ( + self._auto_roles.get_auto_role_rules_by_auto_role_id(auto_role) + .where(lambda r: r.emoji_name == emoji.name and int(role_id) == role.id) + .first_or_default() + is not None + ): + await self._message_service.send_ctx_msg( + ctx, + self._t.transform("modules.auto_role.add.error.already_exists").format(auto_role), + ) + self._logger.trace(__name__, f"Finished command auto-role rule add") return self._auto_roles.add_auto_role_rule(AutoRoleRule(auto_role, emoji_name, int(role_id))) self._db_context.save_changes() - rule = self._auto_roles.get_auto_role_rules_by_auto_role_id(auto_role).where(lambda r: r.emoji_name == emoji.name and int(role_id) == role.id).single() + rule = ( + self._auto_roles.get_auto_role_rules_by_auto_role_id(auto_role) + .where(lambda r: r.emoji_name == emoji.name and int(role_id) == role.id) + .single() + ) try: guild: Guild = self._bot.guilds.where(lambda g: g == ctx.guild).single() channel = guild.get_channel(auto_role_from_db.discord_channel_id) @@ -245,59 +320,85 @@ class AutoRoleGroup(DiscordCommandABC): emoji = List(discord.Emoji, guild.emojis).where(lambda x: x.name == rule.emoji_name).single() if emoji is None: - self._logger.debug(__name__, f'Emoji {rule.emoji_name} not found') + self._logger.debug(__name__, f"Emoji {rule.emoji_name} not found") return await message.add_reaction(emoji) - self._logger.debug(__name__, f'Added reaction {rule.emoji_name} to message: {auto_role_from_db.discord_message_id}') + self._logger.debug( + __name__, + f"Added reaction {rule.emoji_name} to message: {auto_role_from_db.discord_message_id}", + ) except Exception as e: - self._logger.error(__name__, f'Cannot add reaction {rule.emoji_name} to message: {auto_role_from_db.discord_message_id}', e) + self._logger.error( + __name__, + f"Cannot add reaction {rule.emoji_name} to message: {auto_role_from_db.discord_message_id}", + e, + ) - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.auto_role.rule.add.success').format(emoji, role.mention, auto_role)) - self._logger.trace(__name__, f'Finished command auto-role rule add') + await self._message_service.send_ctx_msg( + ctx, + self._t.transform("modules.auto_role.rule.add.success").format(emoji, role.mention, auto_role), + ) + self._logger.trace(__name__, f"Finished command auto-role rule add") - @add.autocomplete('auto_role') + @add.autocomplete("auto_role") async def add_autocomplete(self, interaction: discord.Interaction, current: str) -> TList[app_commands.Choice[str]]: return await self._auto_role_auto_complete(interaction, current) - @add.autocomplete('emoji_name') + @add.autocomplete("emoji_name") async def add_autocomplete(self, interaction: discord.Interaction, current: str) -> TList[app_commands.Choice[str]]: emojis = List(discord.Emoji, interaction.guild.emojis) - return [app_commands.Choice(name=emoji.name, value=emoji.name) for emoji in self._client_utils.get_auto_complete_list(emojis, current, lambda e: e.name)] + return [ + app_commands.Choice(name=emoji.name, value=emoji.name) + for emoji in self._client_utils.get_auto_complete_list(emojis, current, lambda e: e.name) + ] - @add.autocomplete('role_id') - async def rule_add_autocomplete(self, interaction: discord.Interaction, current: str) -> TList[app_commands.Choice[str]]: + @add.autocomplete("role_id") + async def rule_add_autocomplete( + self, interaction: discord.Interaction, current: str + ) -> TList[app_commands.Choice[str]]: roles = List(discord.Role, interaction.guild.roles) - return [app_commands.Choice(name=role.name, value=str(role.id)) for role in self._client_utils.get_auto_complete_list(roles, current, lambda r: r.name)] + return [ + app_commands.Choice(name=role.name, value=str(role.id)) + for role in self._client_utils.get_auto_complete_list(roles, current, lambda r: r.name) + ] @rule.command() @commands.guild_only() @CommandChecks.check_is_ready() @CommandChecks.check_is_member_moderator() async def remove(self, ctx: Context, auto_role_rule: int): - self._logger.debug(__name__, f'Received command auto-role remove {ctx} {auto_role_rule}') + self._logger.debug(__name__, f"Received command auto-role remove {ctx} {auto_role_rule}") auto_role_from_db = self._auto_roles.get_auto_role_rule_by_id(auto_role_rule) if auto_role_from_db is None: - self._logger.debug(__name__, f'auto-role rule {auto_role_rule} not found') - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.auto_role.remove.error.not_found').format(auto_role_rule)) - self._logger.trace(__name__, f'Finished command auto-role rule remove') + self._logger.debug(__name__, f"auto-role rule {auto_role_rule} not found") + await self._message_service.send_ctx_msg( + ctx, + self._t.transform("modules.auto_role.remove.error.not_found").format(auto_role_rule), + ) + self._logger.trace(__name__, f"Finished command auto-role rule remove") return self._auto_roles.delete_auto_role_rule(auto_role_from_db) self._db_context.save_changes() - self._logger.info(__name__, f'Removed auto-role rule {auto_role_rule}') - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.auto_role.rule.remove.success').format(auto_role_rule)) - self._logger.trace(__name__, f'Finished command auto-role remove') + self._logger.info(__name__, f"Removed auto-role rule {auto_role_rule}") + await self._message_service.send_ctx_msg( + ctx, + self._t.transform("modules.auto_role.rule.remove.success").format(auto_role_rule), + ) + self._logger.trace(__name__, f"Finished command auto-role remove") - @remove.autocomplete('auto_role_rule') - async def remove_autocomplete(self, interaction: discord.Interaction, current: str) -> TList[app_commands.Choice[str]]: + @remove.autocomplete("auto_role_rule") + async def remove_autocomplete( + self, interaction: discord.Interaction, current: str + ) -> TList[app_commands.Choice[str]]: server = self._servers.get_server_by_discord_id(interaction.guild.id) auto_roles = self._auto_roles.get_auto_roles_by_server_id(server.server_id).select(lambda x: x.auto_role_id) rules = auto_roles.select_many(lambda ar: self._auto_roles.get_auto_role_rules_by_auto_role_id(ar)) return [ app_commands.Choice( - name=f'{rule.auto_role_rule_id} {rule.emoji_name} {interaction.guild.get_role(int(rule.role_id))}', - value=rule.auto_role_rule_id + name=f"{rule.auto_role_rule_id} {rule.emoji_name} {interaction.guild.get_role(int(rule.role_id))}", + value=rule.auto_role_rule_id, ) for rule in self._client_utils.get_auto_complete_list(rules, current, lambda r: r.auto_role_rule_id) ] diff --git a/kdb-bot/src/modules/auto_role/events/__init__.py b/kdb-bot/src/modules/auto_role/events/__init__.py index 727f90b8..e6346405 100644 --- a/kdb-bot/src/modules/auto_role/events/__init__.py +++ b/kdb-bot/src/modules/auto_role/events/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'modules.auto_role.events' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "modules.auto_role.events" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/modules/auto_role/events/auto_role_on_raw_reaction_add.py b/kdb-bot/src/modules/auto_role/events/auto_role_on_raw_reaction_add.py index 5c891c02..72566c40 100644 --- a/kdb-bot/src/modules/auto_role/events/auto_role_on_raw_reaction_add.py +++ b/kdb-bot/src/modules/auto_role/events/auto_role_on_raw_reaction_add.py @@ -10,14 +10,13 @@ from modules.auto_role.helper.auto_role_reaction_handler import AutoRoleReaction class AutoRoleOnRawReactionAddEvent(OnRawReactionAddABC): - def __init__( - self, - logger: LoggerABC, - bot: DiscordBotServiceABC, - servers: ServerRepositoryABC, - auto_roles: AutoRoleRepositoryABC, - reaction_handler: AutoRoleReactionHandler + self, + logger: LoggerABC, + bot: DiscordBotServiceABC, + servers: ServerRepositoryABC, + auto_roles: AutoRoleRepositoryABC, + reaction_handler: AutoRoleReactionHandler, ): OnRawReactionAddABC.__init__(self) @@ -29,8 +28,8 @@ class AutoRoleOnRawReactionAddEvent(OnRawReactionAddABC): @EventChecks.check_is_ready() async def on_raw_reaction_add(self, payload: RawReactionActionEvent): - self._logger.debug(__name__, f'Module {type(self)} started') + self._logger.debug(__name__, f"Module {type(self)} started") - await self._reaction_handler.handle(payload, 'add') + await self._reaction_handler.handle(payload, "add") - self._logger.debug(__name__, f'Module {type(self)} stopped') + self._logger.debug(__name__, f"Module {type(self)} stopped") diff --git a/kdb-bot/src/modules/auto_role/events/auto_role_on_raw_reaction_remove.py b/kdb-bot/src/modules/auto_role/events/auto_role_on_raw_reaction_remove.py index 5e85f740..394c9578 100644 --- a/kdb-bot/src/modules/auto_role/events/auto_role_on_raw_reaction_remove.py +++ b/kdb-bot/src/modules/auto_role/events/auto_role_on_raw_reaction_remove.py @@ -10,14 +10,13 @@ from modules.auto_role.helper.auto_role_reaction_handler import AutoRoleReaction class AutoRoleOnRawReactionRemoveEvent(OnRawReactionRemoveABC): - def __init__( - self, - logger: LoggerABC, - bot: DiscordBotServiceABC, - servers: ServerRepositoryABC, - auto_roles: AutoRoleRepositoryABC, - reaction_handler: AutoRoleReactionHandler + self, + logger: LoggerABC, + bot: DiscordBotServiceABC, + servers: ServerRepositoryABC, + auto_roles: AutoRoleRepositoryABC, + reaction_handler: AutoRoleReactionHandler, ): OnRawReactionRemoveABC.__init__(self) @@ -29,8 +28,8 @@ class AutoRoleOnRawReactionRemoveEvent(OnRawReactionRemoveABC): @EventChecks.check_is_ready() async def on_raw_reaction_remove(self, payload: RawReactionActionEvent): - self._logger.debug(__name__, f'Module {type(self)} started') + self._logger.debug(__name__, f"Module {type(self)} started") - await self._reaction_handler.handle(payload, 'remove') + await self._reaction_handler.handle(payload, "remove") - self._logger.debug(__name__, f'Module {type(self)} stopped') + self._logger.debug(__name__, f"Module {type(self)} stopped") diff --git a/kdb-bot/src/modules/auto_role/helper/__init__.py b/kdb-bot/src/modules/auto_role/helper/__init__.py index c0d58dcd..80f08582 100644 --- a/kdb-bot/src/modules/auto_role/helper/__init__.py +++ b/kdb-bot/src/modules/auto_role/helper/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'modules.auto_role.helper' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "modules.auto_role.helper" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/modules/auto_role/helper/auto_role_reaction_handler.py b/kdb-bot/src/modules/auto_role/helper/auto_role_reaction_handler.py index 713af5cc..c9ae6e7f 100644 --- a/kdb-bot/src/modules/auto_role/helper/auto_role_reaction_handler.py +++ b/kdb-bot/src/modules/auto_role/helper/auto_role_reaction_handler.py @@ -11,13 +11,12 @@ from bot_data.model.auto_role_rule import AutoRoleRule class AutoRoleReactionHandler: - def __init__( - self, - logger: LoggerABC, - bot: DiscordBotServiceABC, - servers: ServerRepositoryABC, - auto_roles: AutoRoleRepositoryABC + self, + logger: LoggerABC, + bot: DiscordBotServiceABC, + servers: ServerRepositoryABC, + auto_roles: AutoRoleRepositoryABC, ): self._logger = logger self._bot = bot @@ -28,43 +27,45 @@ class AutoRoleReactionHandler: self._roles = self._auto_roles.get_auto_roles() async def handle(self, payload: RawReactionActionEvent, r_type=None) -> None: - self._logger.trace(__name__, f'Handle reaction {payload} {r_type}') + self._logger.trace(__name__, f"Handle reaction {payload} {r_type}") if payload.message_id not in self._message_ids: - self._logger.debug(__name__, f'Message not in auto-roles - skipping') + self._logger.debug(__name__, f"Message not in auto-roles - skipping") return guild = self._bot.get_guild(payload.guild_id) user = guild.get_member(payload.user_id) if user is None: - self._logger.warn(__name__, f'User {payload.user_id} in {guild.name} not found - skipping') + self._logger.warn(__name__, f"User {payload.user_id} in {guild.name} not found - skipping") return if user.bot: - self._logger.debug(__name__, f'User is bot - skipping') + self._logger.debug(__name__, f"User is bot - skipping") return emoji = payload.emoji.name - auto_role: AutoRole = self._roles.where(lambda x: x.discord_message_id == payload.message_id).single_or_default() + auto_role: AutoRole = self._roles.where( + lambda x: x.discord_message_id == payload.message_id + ).single_or_default() if auto_role is None: - self._logger.debug(__name__, f'auto-role for message not found - skipping') + self._logger.debug(__name__, f"auto-role for message not found - skipping") return rules: List[AutoRoleRule] = self._auto_roles.get_auto_role_rules_by_auto_role_id(auto_role.auto_role_id) if rules.count() == 0: - self._logger.debug(__name__, f'auto-role rules not found - skipping') + self._logger.debug(__name__, f"auto-role rules not found - skipping") return for rule in rules: if emoji != rule.emoji_name: continue - if r_type == 'add': + if r_type == "add": role = guild.get_role(rule.role_id) - self._logger.debug(__name__, f'Assign role {role.name} to {user.name}') + self._logger.debug(__name__, f"Assign role {role.name} to {user.name}") await user.add_roles(role) - elif r_type == 'remove': + elif r_type == "remove": role = guild.get_role(rule.role_id) - self._logger.debug(__name__, f'Remove role {role.name} to {user.name}') + self._logger.debug(__name__, f"Remove role {role.name} to {user.name}") await user.remove_roles(role) else: - self._logger.warn(__name__, f'Invalid reaction type {r_type}') + self._logger.warn(__name__, f"Invalid reaction type {r_type}") diff --git a/kdb-bot/src/modules/base/__init__.py b/kdb-bot/src/modules/base/__init__.py index e3cb6607..5cc8b12a 100644 --- a/kdb-bot/src/modules/base/__init__.py +++ b/kdb-bot/src/modules/base/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'modules.base' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "modules.base" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/modules/base/abc/__init__.py b/kdb-bot/src/modules/base/abc/__init__.py index a5b10a34..99963885 100644 --- a/kdb-bot/src/modules/base/abc/__init__.py +++ b/kdb-bot/src/modules/base/abc/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'modules.base.abc' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "modules.base.abc" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/modules/base/abc/base_helper_abc.py b/kdb-bot/src/modules/base/abc/base_helper_abc.py index 44384a7e..c62fe210 100644 --- a/kdb-bot/src/modules/base/abc/base_helper_abc.py +++ b/kdb-bot/src/modules/base/abc/base_helper_abc.py @@ -4,9 +4,9 @@ from modules.base.configuration.base_server_settings import BaseServerSettings class BaseHelperABC(ABC): - def __init__(self): ABC.__init__(self) @abstractmethod - def get_config(self, g_id: int) -> BaseServerSettings: pass + def get_config(self, g_id: int) -> BaseServerSettings: + pass diff --git a/kdb-bot/src/modules/base/base.json b/kdb-bot/src/modules/base/base.json index c0519d0d..217fb702 100644 --- a/kdb-bot/src/modules/base/base.json +++ b/kdb-bot/src/modules/base/base.json @@ -4,7 +4,7 @@ "Version": { "Major": "0", "Minor": "3", - "Micro": "0" + "Micro": "1" }, "Author": "", "AuthorEmail": "", diff --git a/kdb-bot/src/modules/base/base_module.py b/kdb-bot/src/modules/base/base_module.py index 7477d701..9377c6e9 100644 --- a/kdb-bot/src/modules/base/base_module.py +++ b/kdb-bot/src/modules/base/base_module.py @@ -19,17 +19,21 @@ from modules.base.events.base_on_command_error_event import BaseOnCommandErrorEv from modules.base.events.base_on_command_event import BaseOnCommandEvent 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_delete_event import BaseOnMessageDeleteEvent from modules.base.events.base_on_message_event import BaseOnMessageEvent from modules.base.events.base_on_raw_reaction_add import BaseOnRawReactionAddEvent from modules.base.events.base_on_raw_reaction_remove import BaseOnRawReactionRemoveEvent -from modules.base.events.base_on_voice_state_update_event import BaseOnVoiceStateUpdateEvent -from modules.base.events.base_on_voice_state_update_event_help_channel import BaseOnVoiceStateUpdateEventHelpChannel +from modules.base.events.base_on_voice_state_update_event import ( + BaseOnVoiceStateUpdateEvent, +) +from modules.base.events.base_on_voice_state_update_event_help_channel import ( + BaseOnVoiceStateUpdateEventHelpChannel, +) from modules.base.helper.base_reaction_handler import BaseReactionHandler from modules.base.service.base_helper_service import BaseHelperService class BaseModule(ModuleABC): - def __init__(self, dc: DiscordCollectionABC): ModuleABC.__init__(self, dc, FeatureFlagsEnum.base_module) @@ -55,7 +59,17 @@ class BaseModule(ModuleABC): self._dc.add_event(DiscordEventTypesEnum.on_member_join.value, BaseOnMemberJoinEvent) self._dc.add_event(DiscordEventTypesEnum.on_member_remove.value, BaseOnMemberRemoveEvent) self._dc.add_event(DiscordEventTypesEnum.on_message.value, BaseOnMessageEvent) + self._dc.add_event(DiscordEventTypesEnum.on_message_delete.value, BaseOnMessageDeleteEvent) self._dc.add_event(DiscordEventTypesEnum.on_raw_reaction_add.value, BaseOnRawReactionAddEvent) - self._dc.add_event(DiscordEventTypesEnum.on_raw_reaction_remove.value, BaseOnRawReactionRemoveEvent) - self._dc.add_event(DiscordEventTypesEnum.on_voice_state_update.value, BaseOnVoiceStateUpdateEvent) - self._dc.add_event(DiscordEventTypesEnum.on_voice_state_update.value, BaseOnVoiceStateUpdateEventHelpChannel) + self._dc.add_event( + DiscordEventTypesEnum.on_raw_reaction_remove.value, + BaseOnRawReactionRemoveEvent, + ) + self._dc.add_event( + DiscordEventTypesEnum.on_voice_state_update.value, + BaseOnVoiceStateUpdateEvent, + ) + self._dc.add_event( + DiscordEventTypesEnum.on_voice_state_update.value, + BaseOnVoiceStateUpdateEventHelpChannel, + ) diff --git a/kdb-bot/src/modules/base/command/__init__.py b/kdb-bot/src/modules/base/command/__init__.py index 4ba0eba9..f6c4fd0a 100644 --- a/kdb-bot/src/modules/base/command/__init__.py +++ b/kdb-bot/src/modules/base/command/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'modules.base.command' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "modules.base.command" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/modules/base/command/afk_command.py b/kdb-bot/src/modules/base/command/afk_command.py index 234c24fe..7d05f712 100644 --- a/kdb-bot/src/modules/base/command/afk_command.py +++ b/kdb-bot/src/modules/base/command/afk_command.py @@ -6,7 +6,7 @@ from discord import VoiceChannel from discord.ext import commands from discord.ext.commands import Context -from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC +from bot_core.abc.client_utils_abc import ClientUtilsABC from bot_core.abc.message_service_abc import MessageServiceABC from bot_core.helper.command_checks import CommandChecks from bot_core.logging.command_logger import CommandLogger @@ -14,15 +14,14 @@ from modules.base.configuration.base_server_settings import BaseServerSettings class AFKCommand(DiscordCommandABC): - def __init__( - self, - logger: CommandLogger, - config: ConfigurationABC, - message_service: MessageServiceABC, - bot: DiscordBotServiceABC, - client_utils: ClientUtilsServiceABC, - translate: TranslatePipe + self, + logger: CommandLogger, + config: ConfigurationABC, + message_service: MessageServiceABC, + bot: DiscordBotServiceABC, + client_utils: ClientUtilsABC, + translate: TranslatePipe, ): DiscordCommandABC.__init__(self) @@ -33,27 +32,36 @@ class AFKCommand(DiscordCommandABC): self._client_utils = client_utils self._t = translate - self._logger.trace(__name__, f'Loaded command service: {type(self).__name__}') + self._logger.trace(__name__, f"Loaded command service: {type(self).__name__}") @commands.hybrid_command() @commands.guild_only() @CommandChecks.check_is_ready() async def afk(self, ctx: Context): - self._logger.debug(__name__, f'Received command afk {ctx}') - settings: BaseServerSettings = self._config.get_configuration(f'BaseServerSettings_{ctx.guild.id}') + self._logger.debug(__name__, f"Received command afk {ctx}") + settings: BaseServerSettings = self._config.get_configuration(f"BaseServerSettings_{ctx.guild.id}") if ctx.author.voice is None or ctx.author.voice.channel is None: - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.base.afk_command_channel_missing_message')) - self._logger.trace(__name__, f'Finished afk command') + await self._message_service.send_ctx_msg( + ctx, + self._t.transform("modules.base.afk_command_channel_missing_message"), + ) + self._logger.trace(__name__, f"Finished afk command") return - self._bot.loop.create_task(self._message_service.send_ctx_msg(ctx, self._t.transform('modules.base.afk_command_move_message'))) + self._bot.loop.create_task( + self._message_service.send_ctx_msg(ctx, self._t.transform("modules.base.afk_command_move_message")) + ) channel: VoiceChannel = ctx.guild.get_channel(settings.afk_command_channel_id) try: await ctx.author.move_to(channel) self._client_utils.moved_user(ctx.guild.id) except Exception as e: - self._logger.error(__name__, f'Cannot move user {ctx.author.id} to channel {ctx.channel.id}', e) - await self._message_service.send_ctx_msg(ctx, self._t.transform('common.no_permission_message')) + self._logger.error( + __name__, + f"Cannot move user {ctx.author.id} to channel {ctx.channel.id}", + e, + ) + await self._message_service.send_ctx_msg(ctx, self._t.transform("common.no_permission_message")) - self._logger.trace(__name__, f'Finished afk command') + self._logger.trace(__name__, f"Finished afk command") diff --git a/kdb-bot/src/modules/base/command/help_command.py b/kdb-bot/src/modules/base/command/help_command.py index dd252740..9c37cf08 100644 --- a/kdb-bot/src/modules/base/command/help_command.py +++ b/kdb-bot/src/modules/base/command/help_command.py @@ -8,7 +8,7 @@ from discord import app_commands from discord.ext import commands from discord.ext.commands import Context -from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC +from bot_core.abc.client_utils_abc import ClientUtilsABC from bot_core.abc.message_service_abc import MessageServiceABC from bot_core.helper.command_checks import CommandChecks from bot_core.logging.command_logger import CommandLogger @@ -16,14 +16,13 @@ from modules.base.configuration.base_server_settings import BaseServerSettings class HelpCommand(DiscordCommandABC): - def __init__( - self, - config: ConfigurationABC, - logger: CommandLogger, - message_service: MessageServiceABC, - bot: DiscordBotServiceABC, - client_utils: ClientUtilsServiceABC + self, + config: ConfigurationABC, + logger: CommandLogger, + message_service: MessageServiceABC, + bot: DiscordBotServiceABC, + client_utils: ClientUtilsABC, ): DiscordCommandABC.__init__(self) @@ -33,19 +32,24 @@ class HelpCommand(DiscordCommandABC): self._bot = bot self._client_utils = client_utils - self._logger.trace(__name__, f'Loaded command service: {type(self).__name__}') + self._logger.trace(__name__, f"Loaded command service: {type(self).__name__}") @commands.hybrid_command() @commands.guild_only() @CommandChecks.check_is_ready() async def help(self, ctx: Context, persistent_flag: str = None): - self._logger.debug(__name__, f'Received command help {ctx}:{persistent_flag}') - settings: BaseServerSettings = self._config.get_configuration(f'BaseServerSettings_{ctx.guild.id}') - is_persistent = persistent_flag == '--stay' - await self._message_service.send_ctx_msg(ctx, settings.help_command_reference_url, is_persistent=is_persistent, is_public=True) - self._logger.trace(__name__, f'Finished help command') + self._logger.debug(__name__, f"Received command help {ctx}:{persistent_flag}") + settings: BaseServerSettings = self._config.get_configuration(f"BaseServerSettings_{ctx.guild.id}") + is_persistent = persistent_flag == "--stay" + await self._message_service.send_ctx_msg( + ctx, + settings.help_command_reference_url, + is_persistent=is_persistent, + is_public=True, + ) + self._logger.trace(__name__, f"Finished help command") - @help.autocomplete('persistent_flag') + @help.autocomplete("persistent_flag") async def help_autocomplete(self, interaction: discord.Interaction, current: str) -> List[app_commands.Choice[str]]: - flags = ['--stay'] + flags = ["--stay"] return [app_commands.Choice(name=key, value=key) for key in flags] diff --git a/kdb-bot/src/modules/base/command/info_command.py b/kdb-bot/src/modules/base/command/info_command.py index 974bc491..e228be84 100644 --- a/kdb-bot/src/modules/base/command/info_command.py +++ b/kdb-bot/src/modules/base/command/info_command.py @@ -9,22 +9,21 @@ from discord.ext import commands from discord.ext.commands import Context import bot -from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC +from bot_core.abc.client_utils_abc import ClientUtilsABC from bot_core.abc.message_service_abc import MessageServiceABC from bot_core.helper.command_checks import CommandChecks from bot_core.logging.command_logger import CommandLogger class InfoCommand(DiscordCommandABC): - def __init__( - self, - config: ConfigurationABC, - logger: CommandLogger, - message_service: MessageServiceABC, - bot: DiscordBotServiceABC, - client_utils: ClientUtilsServiceABC, - translate: TranslatePipe + self, + config: ConfigurationABC, + logger: CommandLogger, + message_service: MessageServiceABC, + bot: DiscordBotServiceABC, + client_utils: ClientUtilsABC, + translate: TranslatePipe, ): DiscordCommandABC.__init__(self) @@ -35,34 +34,65 @@ class InfoCommand(DiscordCommandABC): self._client_utils = client_utils self._t = translate - self._logger.trace(__name__, f'Loaded command service: {type(self).__name__}') + self._logger.trace(__name__, f"Loaded command service: {type(self).__name__}") @commands.hybrid_command() @commands.guild_only() @CommandChecks.check_is_ready() async def info(self, ctx: Context, *, wait: int = None): - self._logger.debug(__name__, f'Received command info {ctx},{wait}') + self._logger.debug(__name__, f"Received command info {ctx},{wait}") client = self._client_utils.get_client(self._bot.user.id, ctx.guild.id) embed = discord.Embed( - title=self._t.transform('modules.base.info.title'), - description=self._t.transform('modules.base.info.description'), - color=int('ef9d0d', 16) + title=self._t.transform("modules.base.info.title"), + description=self._t.transform("modules.base.info.description"), + color=int("ef9d0d", 16), ) - embed.add_field(name=self._t.transform('modules.base.info.fields.version'), value=bot.__version__) - start_time = self._config.get_configuration('Bot_StartTime') - ontime = round((datetime.now() - datetime.strptime(start_time, '%Y-%m-%d %H:%M:%S.%f')).total_seconds() / 3600, 2) - embed.add_field(name=self._t.transform('modules.base.info.fields.ontime'), value=f'{ontime}h') - embed.add_field(name=self._t.transform('modules.base.info.fields.sent_message_count'), value=client.sent_message_count, inline=False) - embed.add_field(name=self._t.transform('modules.base.info.fields.received_message_count'), value=client.received_message_count) - 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) + embed.add_field( + name=self._t.transform("modules.base.info.fields.version"), + value=bot.__version__, + ) + start_time = self._config.get_configuration("Bot_StartTime") + ontime = round( + (datetime.now() - datetime.strptime(start_time, "%Y-%m-%d %H:%M:%S.%f")).total_seconds() / 3600, + 2, + ) + embed.add_field( + name=self._t.transform("modules.base.info.fields.ontime"), + value=f"{ontime}h", + ) + embed.add_field( + name=self._t.transform("modules.base.info.fields.sent_message_count"), + value=client.sent_message_count, + inline=False, + ) + embed.add_field( + name=self._t.transform("modules.base.info.fields.received_message_count"), + value=client.received_message_count, + ) + 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, + ) from bot.module_list import ModuleList + modules = ModuleList.get_modules() - modules = modules.select(lambda x: x.__name__.replace('Module', '')) - embed.add_field(name=self._t.transform('modules.base.info.fields.modules'), value='\n'.join(modules), inline=False) + modules = modules.select(lambda x: x.__name__.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) - self._logger.trace(__name__, f'Finished info command') + self._logger.trace(__name__, f"Finished info command") diff --git a/kdb-bot/src/modules/base/command/mass_move_command.py b/kdb-bot/src/modules/base/command/mass_move_command.py index 85862a14..dca23d73 100644 --- a/kdb-bot/src/modules/base/command/mass_move_command.py +++ b/kdb-bot/src/modules/base/command/mass_move_command.py @@ -14,14 +14,13 @@ from bot_core.service.client_utils_service import ClientUtilsService class MassMoveCommand(DiscordCommandABC): - def __init__( - self, - logger: CommandLogger, - message_service: MessageServiceABC, - bot: DiscordBotServiceABC, - translate: TranslatePipe, - client_utils: ClientUtilsService + self, + logger: CommandLogger, + message_service: MessageServiceABC, + bot: DiscordBotServiceABC, + translate: TranslatePipe, + client_utils: ClientUtilsService, ): DiscordCommandABC.__init__(self) self._logger = logger @@ -30,15 +29,21 @@ class MassMoveCommand(DiscordCommandABC): self._t = translate self._client_utils = client_utils - @commands.hybrid_command(name='mass-move') + @commands.hybrid_command(name="mass-move") @CommandChecks.check_is_ready() @CommandChecks.check_is_member_moderator() - async def mass_move(self, ctx: Context, channel_to: discord.VoiceChannel, - channel_from: discord.VoiceChannel = None): - self._logger.debug(__name__, f'Received command mass-move {ctx}') + async def mass_move( + self, + ctx: Context, + channel_to: discord.VoiceChannel, + channel_from: discord.VoiceChannel = None, + ): + self._logger.debug(__name__, f"Received command mass-move {ctx}") if channel_from is None and ctx.author.voice is None: - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.base.mass_move.channel_from_error')) + await self._message_service.send_ctx_msg( + ctx, self._t.transform("modules.base.mass_move.channel_from_error") + ) return if channel_from is None: @@ -49,6 +54,9 @@ class MassMoveCommand(DiscordCommandABC): await asyncio.gather(*moves) self._client_utils.moved_users(ctx.guild.id, move_count) - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.base.mass_move.moved').format(channel_from.mention, channel_to.mention)) + await self._message_service.send_ctx_msg( + ctx, + self._t.transform("modules.base.mass_move.moved").format(channel_from.mention, channel_to.mention), + ) - self._logger.trace(__name__, f'Finished mass-move command') + self._logger.trace(__name__, f"Finished mass-move command") diff --git a/kdb-bot/src/modules/base/command/ping_command.py b/kdb-bot/src/modules/base/command/ping_command.py index 7633d8a0..9e223f9a 100644 --- a/kdb-bot/src/modules/base/command/ping_command.py +++ b/kdb-bot/src/modules/base/command/ping_command.py @@ -5,7 +5,7 @@ from cpl_translation import TranslatePipe from discord.ext import commands from discord.ext.commands import Context -from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC +from bot_core.abc.client_utils_abc import ClientUtilsABC from bot_core.abc.message_service_abc import MessageServiceABC from bot_core.helper.command_checks import CommandChecks from bot_core.logging.command_logger import CommandLogger @@ -16,17 +16,16 @@ from modules.permission.abc.permission_service_abc import PermissionServiceABC class PingCommand(DiscordCommandABC): - def __init__( - self, - logger: CommandLogger, - message_service: MessageServiceABC, - bot: DiscordBotServiceABC, - client_utils: ClientUtilsServiceABC, - translate: TranslatePipe, - permissions: PermissionServiceABC, - base_helper: BaseHelperABC, - servers: ServerRepositoryABC, + self, + logger: CommandLogger, + message_service: MessageServiceABC, + bot: DiscordBotServiceABC, + client_utils: ClientUtilsABC, + translate: TranslatePipe, + permissions: PermissionServiceABC, + base_helper: BaseHelperABC, + servers: ServerRepositoryABC, ): DiscordCommandABC.__init__(self) @@ -39,11 +38,12 @@ class PingCommand(DiscordCommandABC): self._base_helper = base_helper self._servers = servers - self._logger.trace(__name__, f'Loaded command service: {type(self).__name__}') + self._logger.trace(__name__, f"Loaded command service: {type(self).__name__}") @staticmethod def _get_ping(url: str) -> float: from icmplib import ping + ping_result = ping(url, count=4, interval=0.2, privileged=False) return ping_result.avg_rtt @@ -51,18 +51,18 @@ class PingCommand(DiscordCommandABC): @commands.guild_only() @CommandChecks.check_is_ready() async def ping(self, ctx: Context): - self._logger.debug(__name__, f'Received command ping {ctx}') + self._logger.debug(__name__, f"Received command ping {ctx}") if self._permissions.is_member_technician(ctx.author): embed = discord.Embed( - title=self._t.transform('modules.base.info.title'), - description=self._t.transform('modules.base.info.description'), - color=int('ef9d0d', 16) + title=self._t.transform("modules.base.info.title"), + description=self._t.transform("modules.base.info.description"), + color=int("ef9d0d", 16), ) server = self._servers.get_server_by_discord_id(ctx.guild.id) settings: BaseServerSettings = self._base_helper.get_config(server.discord_server_id) for server in settings.ping_urls: - embed.add_field(name=server, value=f'{self._get_ping(server)} ms', inline=False) + embed.add_field(name=server, value=f"{self._get_ping(server)} ms", inline=False) await self._message_service.send_ctx_msg(ctx, embed) else: - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.base.pong')) - self._logger.trace(__name__, f'Finished ping command') + await self._message_service.send_ctx_msg(ctx, self._t.transform("modules.base.pong")) + self._logger.trace(__name__, f"Finished ping command") diff --git a/kdb-bot/src/modules/base/command/presence_command.py b/kdb-bot/src/modules/base/command/presence_command.py index 99db2fca..a314b4aa 100644 --- a/kdb-bot/src/modules/base/command/presence_command.py +++ b/kdb-bot/src/modules/base/command/presence_command.py @@ -11,13 +11,12 @@ from bot_core.logging.command_logger import CommandLogger class PresenceCommand(DiscordCommandABC): - def __init__( - self, - logger: CommandLogger, - message_service: MessageServiceABC, - bot: DiscordBotServiceABC, - translate: TranslatePipe, + self, + logger: CommandLogger, + message_service: MessageServiceABC, + bot: DiscordBotServiceABC, + translate: TranslatePipe, ): DiscordCommandABC.__init__(self) @@ -30,19 +29,21 @@ class PresenceCommand(DiscordCommandABC): @commands.guild_only() @CommandChecks.check_is_ready() @CommandChecks.check_is_member_moderator() - async def presence(self, ctx: Context, text: str = ''): - self._logger.debug(__name__, f'Received command presence {ctx}') + async def presence(self, ctx: Context, text: str = ""): + self._logger.debug(__name__, f"Received command presence {ctx}") - if text == '': + if text == "": await self._bot.change_presence(activity=None) - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.base.presence.removed')) + await self._message_service.send_ctx_msg(ctx, self._t.transform("modules.base.presence.removed")) return if len(text) > 128: - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.base.presence.max_char_count_exceeded')) + await self._message_service.send_ctx_msg( + ctx, self._t.transform("modules.base.presence.max_char_count_exceeded") + ) return await self._bot.change_presence(activity=discord.Game(name=text)) - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.base.presence.changed')) + await self._message_service.send_ctx_msg(ctx, self._t.transform("modules.base.presence.changed")) - self._logger.trace(__name__, f'Finished presence command') + self._logger.trace(__name__, f"Finished presence command") diff --git a/kdb-bot/src/modules/base/command/purge_command.py b/kdb-bot/src/modules/base/command/purge_command.py index 8ec78eff..60a0ad23 100644 --- a/kdb-bot/src/modules/base/command/purge_command.py +++ b/kdb-bot/src/modules/base/command/purge_command.py @@ -6,7 +6,7 @@ from cpl_translation import TranslatePipe from discord.ext import commands from discord.ext.commands import Context -from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC +from bot_core.abc.client_utils_abc import ClientUtilsABC from bot_core.abc.message_service_abc import MessageServiceABC from bot_core.configuration.server_settings import ServerSettings from bot_core.helper.command_checks import CommandChecks @@ -15,15 +15,14 @@ from modules.permission.abc.permission_service_abc import PermissionServiceABC class PurgeCommand(DiscordCommandABC): - def __init__( - self, - logger: CommandLogger, - config: ConfigurationABC, - message_service: MessageServiceABC, - permissions: PermissionServiceABC, - client_utils: ClientUtilsServiceABC, - translate: TranslatePipe + self, + logger: CommandLogger, + config: ConfigurationABC, + message_service: MessageServiceABC, + permissions: PermissionServiceABC, + client_utils: ClientUtilsABC, + translate: TranslatePipe, ): DiscordCommandABC.__init__(self) @@ -34,22 +33,22 @@ class PurgeCommand(DiscordCommandABC): self._client_utils = client_utils self._t = translate - self._logger.trace(__name__, f'Loaded command service: {type(self).__name__}') + self._logger.trace(__name__, f"Loaded command service: {type(self).__name__}") @commands.hybrid_command() @commands.guild_only() @CommandChecks.check_is_ready() @CommandChecks.check_is_member_moderator() async def purge(self, ctx: Context): - self._logger.debug(__name__, f'Received command purge {ctx}') - server_settings: ServerSettings = self._config.get_configuration(f'ServerSettings_{ctx.guild.id}') + self._logger.debug(__name__, f"Received command purge {ctx}") + server_settings: ServerSettings = self._config.get_configuration(f"ServerSettings_{ctx.guild.id}") - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.moderator.purge_message')) + await self._message_service.send_ctx_msg(ctx, self._t.transform("modules.moderator.purge_message")) await asyncio.sleep(server_settings.message_delete_timer) try: await ctx.channel.purge() except Exception as e: - self._logger.error(__name__, f'Cannot purge channel {ctx.channel.id}', e) - await self._message_service.send_ctx_msg(ctx, self._t.transform('common.bot_has_no_permission_message')) + self._logger.error(__name__, f"Cannot purge channel {ctx.channel.id}", e) + await self._message_service.send_ctx_msg(ctx, self._t.transform("common.bot_has_no_permission_message")) - self._logger.trace(__name__, f'Finished purge command') + self._logger.trace(__name__, f"Finished purge command") diff --git a/kdb-bot/src/modules/base/command/user_group.py b/kdb-bot/src/modules/base/command/user_group.py index 5725e5b6..b76a0c06 100644 --- a/kdb-bot/src/modules/base/command/user_group.py +++ b/kdb-bot/src/modules/base/command/user_group.py @@ -9,39 +9,39 @@ from cpl_translation import TranslatePipe from discord import app_commands from discord.ext import commands from discord.ext.commands import Context -from mysql.connector.errors import DatabaseError -from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC +from bot_core.abc.client_utils_abc import ClientUtilsABC from bot_core.abc.message_service_abc import MessageServiceABC from bot_core.helper.command_checks import CommandChecks from bot_core.logging.command_logger import CommandLogger from bot_core.pipes.date_time_offset_pipe import DateTimeOffsetPipe 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_joined_voice_channel_repository_abc import ( + UserJoinedVoiceChannelRepositoryABC, +) from bot_data.abc.user_repository_abc import UserRepositoryABC from modules.level.service.level_service import LevelService from modules.permission.abc.permission_service_abc import PermissionServiceABC class UserGroup(DiscordCommandABC): - def __init__( - self, - config: ConfigurationABC, - logger: CommandLogger, - message_service: MessageServiceABC, - bot: DiscordBotServiceABC, - client_utils: ClientUtilsServiceABC, - permissions: PermissionServiceABC, - servers: ServerRepositoryABC, - db: DatabaseContextABC, - users: UserRepositoryABC, - user_joined_servers: UserJoinedServerRepositoryABC, - user_joined_voice_channel: UserJoinedVoiceChannelRepositoryABC, - translate: TranslatePipe, - date: DateTimeOffsetPipe, - level: LevelService + self, + config: ConfigurationABC, + logger: CommandLogger, + message_service: MessageServiceABC, + bot: DiscordBotServiceABC, + client_utils: ClientUtilsABC, + permissions: PermissionServiceABC, + servers: ServerRepositoryABC, + db: DatabaseContextABC, + users: UserRepositoryABC, + user_joined_servers: UserJoinedServerRepositoryABC, + user_joined_voice_channel: UserJoinedVoiceChannelRepositoryABC, + translate: TranslatePipe, + date: DateTimeOffsetPipe, + level: LevelService, ): DiscordCommandABC.__init__(self) @@ -60,15 +60,51 @@ class UserGroup(DiscordCommandABC): self._date = date self._level = level - self._logger.trace(__name__, f'Loaded command service: {type(self).__name__}') + self._logger.trace(__name__, f"Loaded command service: {type(self).__name__}") self._atr_dict = { - "xp": self._t.transform('modules.base.user.atr.xp'), - 'ontime': self._t.transform('modules.base.user.atr.ontime') + "xp": self._t.transform("modules.base.user.atr.xp"), + "ontime": self._t.transform("modules.base.user.atr.ontime"), } self._atr_list = [(key, self._atr_dict[key]) for key in self._atr_dict] + async def _handle_atr_calc( + self, + ctx: Context, + atr: str, + value: int, + member: discord.Member, + is_remove=False, + ): + if member is None or not isinstance(member, discord.Member): + member = ctx.author + + server = self._servers.find_server_by_discord_id(ctx.guild.id) + user = self._users.find_user_by_discord_id_and_server_id(member.id, server.server_id) + + if atr == "xp": + if is_remove: + user.xp -= value + else: + user.xp += value + self._users.update_user(user) + self._db.save_changes() + await self._level.check_level(member) + + else: + await self._message_service.send_interaction_msg( + ctx.interaction, + self._t.transform("modules.base.user.error.atr_not_found").format(atr), + ) + return + + type = "add" if not is_remove else "remove" + await self._message_service.send_interaction_msg( + ctx.interaction, + self._t.transform(f"modules.base.user.{type}.{atr.lower()}").format(atr, value, member.mention), + ) + @commands.hybrid_group() @commands.guild_only() async def user(self, ctx: Context): @@ -78,11 +114,11 @@ class UserGroup(DiscordCommandABC): @commands.guild_only() @CommandChecks.check_is_ready() async def info(self, ctx: Context, member: Optional[discord.Member] = None, *, wait: int = None): - self._logger.debug(__name__, f'Received command user-info {ctx}:{member},{wait}') + self._logger.debug(__name__, f"Received command user-info {ctx}:{member},{wait}") is_mod = self._permissions.is_member_moderator(ctx.author) if member is not None and not is_mod: - await self._message_service.send_ctx_msg(ctx, self._t.transform('common.no_permission_message')) + await self._message_service.send_ctx_msg(ctx, self._t.transform("common.no_permission_message")) return if member is None or not isinstance(member, discord.Member): @@ -92,64 +128,78 @@ class UserGroup(DiscordCommandABC): user = self._users.find_user_by_discord_id_and_server_id(member.id, server.server_id) joins = self._user_joined_servers.get_user_joined_servers_by_user_id(user.user_id) - embed = discord.Embed( - title=member.name, - description=member.name, - color=int('ef9d0d', 16) + embed = discord.Embed(title=member.name, description=member.name, color=int("ef9d0d", 16)) + + embed.add_field(name=self._t.transform("modules.base.user.atr.id"), value=member.id) + embed.add_field(name=self._t.transform("modules.base.user.atr.name"), value=member.name) + embed.add_field( + name=self._t.transform("modules.base.user.atr.discord_join"), + value=self._date.transform(member.created_at), + inline=False, + ) + embed.add_field( + name=self._t.transform("modules.base.user.atr.last_join"), + value=self._date.transform(member.joined_at), + inline=False, + ) + embed.add_field(name=self._t.transform("modules.base.user.atr.xp"), value=str(user.xp)) + embed.add_field( + name=self._t.transform("modules.base.user.atr.ontime"), + value=str(self._client_utils.get_ontime_for_user(user)), ) - ontime = self._user_joined_voice_channel.get_user_joined_voice_channels_by_user_id(user.user_id)\ - .where(lambda x: x.leaved_on is not None and x.joined_on is not None)\ - .sum(lambda join: round((join.leaved_on - join.joined_on).total_seconds() / 3600, 2)) - - embed.add_field(name=self._t.transform('modules.base.user.atr.id'), value=member.id) - embed.add_field(name=self._t.transform('modules.base.user.atr.name'), value=member.name) - embed.add_field(name=self._t.transform('modules.base.user.atr.discord_join'), - value=self._date.transform(member.created_at), inline=False) - embed.add_field(name=self._t.transform('modules.base.user.atr.last_join'), - value=self._date.transform(member.joined_at), inline=False) - embed.add_field(name=self._t.transform('modules.base.user.atr.xp'), value=str(user.xp)) - embed.add_field(name=self._t.transform('modules.base.user.atr.ontime'), value=str(ontime)) - - roles = '' + roles = "" for role in member.roles: - roles += f'{role.name}\n' - embed.add_field(name=self._t.transform('modules.base.user.atr.roles'), value=roles, inline=False) + roles += f"{role.name}\n" + embed.add_field( + name=self._t.transform("modules.base.user.atr.roles"), + value=roles, + inline=False, + ) if is_mod or member == ctx.author: - joins_string = '' + joins_string = "" for join in joins: - joins_string += f'{self._date.transform(join.joined_on)}\n' - embed.add_field(name=self._t.transform('modules.base.user.atr.joins'), value=joins_string) + joins_string += f"{self._date.transform(join.joined_on)}\n" + embed.add_field( + name=self._t.transform("modules.base.user.atr.joins"), + value=joins_string, + ) if is_mod or member == ctx.author: - lefts_string = '' + lefts_string = "" for join in joins: if join.leaved_on is None: - if lefts_string == '': - lefts_string = '/' + if lefts_string == "": + lefts_string = "/" continue - lefts_string += f'{self._date.transform(join.leaved_on)}\n' + lefts_string += f"{self._date.transform(join.leaved_on)}\n" - embed.add_field(name=self._t.transform('modules.base.user.atr.lefts'), value=lefts_string) + embed.add_field( + name=self._t.transform("modules.base.user.atr.lefts"), + value=lefts_string, + ) if is_mod or member == ctx.author: - embed.add_field(name=self._t.transform('modules.base.user.atr.warnings'), - value=self._t.transform('common.not_implemented_yet'), inline=False) + embed.add_field( + name=self._t.transform("modules.base.user.atr.warnings"), + value=self._t.transform("common.not_implemented_yet"), + inline=False, + ) # send to interaction because of sensitive data await self._message_service.send_interaction_msg(ctx.interaction, embed, wait_before_delete=wait) - self._logger.trace(__name__, f'Finished user-info command') + self._logger.trace(__name__, f"Finished user-info command") @user.command() @commands.guild_only() @CommandChecks.check_is_ready() async def get(self, ctx: Context, atr: str, member: discord.Member = None): - self._logger.debug(__name__, f'Received command user-get {atr} {ctx}:{member}') + self._logger.debug(__name__, f"Received command user-get {atr} {ctx}:{member}") is_mod = self._permissions.is_member_moderator(ctx.author) if member is not None and not is_mod: - await self._message_service.send_ctx_msg(ctx, self._t.transform('common.no_permission_message')) + await self._message_service.send_ctx_msg(ctx, self._t.transform("common.no_permission_message")) return if member is None or not isinstance(member, discord.Member): @@ -158,26 +208,25 @@ class UserGroup(DiscordCommandABC): server = self._servers.find_server_by_discord_id(ctx.guild.id) user = self._users.find_user_by_discord_id_and_server_id(member.id, server.server_id) - if atr == 'xp': + if atr == "xp": value = str(user.xp) - elif atr == 'ontime': - value = str(round( - self._user_joined_voice_channel.get_user_joined_voice_channels_by_user_id(user.user_id) - .sum(lambda join: (join.leaved_on - join.joined_on).total_seconds() / 3600), - 2 - )) + elif atr == "ontime": + value = str(self._client_utils.get_ontime_for_user(user)) else: - await self._message_service.send_interaction_msg(ctx.interaction, self._t.transform('modules.base.user.error.atr_not_found').format(atr)) + await self._message_service.send_interaction_msg( + ctx.interaction, + self._t.transform("modules.base.user.error.atr_not_found").format(atr), + ) return await self._message_service.send_interaction_msg( ctx.interaction, - self._t.transform(f'modules.base.user.get.{atr.lower()}').format(member.mention, value) + self._t.transform(f"modules.base.user.get.{atr.lower()}").format(member.mention, value), ) - @get.autocomplete('atr') + @get.autocomplete("atr") async def get_autocomplete(self, interaction: discord.Interaction, current: str) -> List[app_commands.Choice[str]]: return [app_commands.Choice(name=value, value=key) for key, value in self._atr_list] @@ -185,8 +234,8 @@ class UserGroup(DiscordCommandABC): @commands.guild_only() @CommandChecks.check_is_ready() @CommandChecks.check_is_member_moderator() - async def set(self, ctx: Context, atr: str, value: str, member: discord.Member = None): - self._logger.debug(__name__, f'Received command user-set {atr} {ctx}:{member}') + async def set(self, ctx: Context, atr: str, value: int, member: discord.Member = None): + self._logger.debug(__name__, f"Received command user-set {atr} {ctx}:{member}") if member is None or not isinstance(member, discord.Member): member = ctx.author @@ -194,16 +243,15 @@ class UserGroup(DiscordCommandABC): server = self._servers.find_server_by_discord_id(ctx.guild.id) user = self._users.find_user_by_discord_id_and_server_id(member.id, server.server_id) - if atr == 'xp': - if not value.isnumeric(): - await self._message_service.send_interaction_msg(ctx.interaction, self._t.transform('modules.base.user.set.error.value_type_not_numeric')) - return - + if atr == "xp": try: - user.xp = int(value) + user.xp = value except TypeError as te: - self._logger.error(__name__, f'String value couldn\'t be converted to int', te) - await self._message_service.send_interaction_msg(ctx.interaction, self._t.transform('modules.base.user.set.error.type_error')) + self._logger.error(__name__, f"String value couldn't be converted to int", te) + await self._message_service.send_interaction_msg( + ctx.interaction, + self._t.transform("modules.base.user.set.error.type_error"), + ) return else: self._users.update_user(user) @@ -211,22 +259,54 @@ class UserGroup(DiscordCommandABC): await self._level.check_level(member) else: - await self._message_service.send_interaction_msg(ctx.interaction, self._t.transform('modules.base.user.error.atr_not_found').format(atr)) + await self._message_service.send_interaction_msg( + ctx.interaction, + self._t.transform("modules.base.user.error.atr_not_found").format(atr), + ) return - await self._message_service.send_interaction_msg(ctx.interaction, self._t.transform(f'modules.base.user.set.{atr.lower()}').format(member.mention, value)) + await self._message_service.send_interaction_msg( + ctx.interaction, + self._t.transform(f"modules.base.user.set.{atr.lower()}").format(member.mention, value), + ) - @set.autocomplete('atr') + @set.autocomplete("atr") async def set_autocomplete(self, interaction: discord.Interaction, current: str) -> List[app_commands.Choice[str]]: - atr_list = [('xp', self._atr_dict['xp'])] + atr_list = [("xp", self._atr_dict["xp"])] return [app_commands.Choice(name=value, value=key) for key, value in atr_list] @user.command() @commands.guild_only() @CommandChecks.check_is_ready() @CommandChecks.check_is_member_moderator() - async def remove(self, ctx: Context, atr: str, member: discord.Member = None): - self._logger.debug(__name__, f'Received command user-remove {atr} {ctx}:{member}') + async def add(self, ctx: Context, atr: str, value: int, member: discord.Member = None): + self._logger.debug(__name__, f"Received command user-add {atr}-={value} {ctx}:{member}") + await self._handle_atr_calc(ctx, atr, value, member) + + @add.autocomplete("atr") + async def set_autocomplete(self, interaction: discord.Interaction, current: str) -> List[app_commands.Choice[str]]: + atr_list = [("xp", self._atr_dict["xp"])] + return [app_commands.Choice(name=value, value=key) for key, value in atr_list] + + @user.command() + @commands.guild_only() + @CommandChecks.check_is_ready() + @CommandChecks.check_is_member_moderator() + async def remove(self, ctx: Context, atr: str, value: int, member: discord.Member = None): + self._logger.debug(__name__, f"Received command user-remove {atr}-={value} {ctx}:{member}") + await self._handle_atr_calc(ctx, atr, value, member, is_remove=True) + + @remove.autocomplete("atr") + async def set_autocomplete(self, interaction: discord.Interaction, current: str) -> List[app_commands.Choice[str]]: + atr_list = [("xp", self._atr_dict["xp"])] + return [app_commands.Choice(name=value, value=key) for key, value in atr_list] + + @user.command() + @commands.guild_only() + @CommandChecks.check_is_ready() + @CommandChecks.check_is_member_moderator() + async def reset(self, ctx: Context, atr: str, member: discord.Member = None): + self._logger.debug(__name__, f"Received command user-reset {atr} {ctx}:{member}") if member is None or not isinstance(member, discord.Member): member = ctx.author @@ -234,25 +314,30 @@ class UserGroup(DiscordCommandABC): server = self._servers.find_server_by_discord_id(ctx.guild.id) user = self._users.find_user_by_discord_id_and_server_id(member.id, server.server_id) - if atr == 'xp': + if atr == "xp": user.xp = 0 self._users.update_user(user) self._db.save_changes() await self._level.check_level(member) - elif atr == 'ontime': + elif atr == "ontime": self._user_joined_voice_channel.delete_user_joined_voice_channel_by_user_id(user.user_id) self._db.save_changes() else: - await self._message_service.send_interaction_msg(ctx.interaction, self._t.transform('modules.base.user.error.atr_not_found').format(atr)) + await self._message_service.send_interaction_msg( + ctx.interaction, + self._t.transform("modules.base.user.error.atr_not_found").format(atr), + ) return await self._message_service.send_interaction_msg( ctx.interaction, - self._t.transform(f'modules.base.user.remove.{atr.lower()}').format(atr, member.mention) + self._t.transform(f"modules.base.user.reset.{atr.lower()}").format(atr, member.mention), ) - @remove.autocomplete('atr') - async def remove_autocomplete(self, interaction: discord.Interaction, current: str) -> List[app_commands.Choice[str]]: + @reset.autocomplete("atr") + async def reset_autocomplete( + self, interaction: discord.Interaction, current: str + ) -> List[app_commands.Choice[str]]: return [app_commands.Choice(name=value, value=key) for key, value in self._atr_list] diff --git a/kdb-bot/src/modules/base/configuration/__init__.py b/kdb-bot/src/modules/base/configuration/__init__.py index bd2cc24d..6178ed32 100644 --- a/kdb-bot/src/modules/base/configuration/__init__.py +++ b/kdb-bot/src/modules/base/configuration/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'modules.base.configuration' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "modules.base.configuration" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/modules/base/configuration/base_server_settings.py b/kdb-bot/src/modules/base/configuration/base_server_settings.py index b5838633..531e44c9 100644 --- a/kdb-bot/src/modules/base/configuration/base_server_settings.py +++ b/kdb-bot/src/modules/base/configuration/base_server_settings.py @@ -6,7 +6,6 @@ from cpl_query.extension import List class BaseServerSettings(ConfigurationModelABC): - def __init__(self): ConfigurationModelABC.__init__(self) @@ -14,10 +13,11 @@ class BaseServerSettings(ConfigurationModelABC): self._max_voice_state_hours: int = 0 self._xp_per_message: int = 0 self._xp_per_reaction: int = 0 + self._max_message_xp_per_hour: int = 0 self._xp_per_ontime_hour: int = 0 self._afk_channel_ids: List[int] = List(int) self._afk_command_channel_id: int = 0 - self._help_command_reference_url: str = '' + self._help_command_reference_url: str = "" self._help_voice_channel_id: int = 0 self._ping_urls = List(str) @@ -37,6 +37,10 @@ class BaseServerSettings(ConfigurationModelABC): def xp_per_reaction(self) -> int: return self._xp_per_reaction + @property + def max_message_xp_per_hour(self) -> int: + return self._max_message_xp_per_hour + @property def xp_per_ontime_hour(self) -> int: return self._xp_per_ontime_hour @@ -63,18 +67,19 @@ class BaseServerSettings(ConfigurationModelABC): def from_dict(self, settings: dict): try: - self._id = int(settings['Id']) - self._max_voice_state_hours = int(settings['MaxVoiceStateHours']) - self._xp_per_message = int(settings['XpPerMessage']) - self._xp_per_reaction = int(settings['XpPerReaction']) - self._xp_per_ontime_hour = int(settings['XpPerOntimeHour']) - for index in settings['AFKChannelIds']: + self._id = int(settings["Id"]) + self._max_voice_state_hours = int(settings["MaxVoiceStateHours"]) + self._xp_per_message = int(settings["XpPerMessage"]) + self._xp_per_reaction = int(settings["XpPerReaction"]) + self._max_message_xp_per_hour = int(settings["MaxMessageXpPerHour"]) + self._xp_per_ontime_hour = int(settings["XpPerOntimeHour"]) + for index in settings["AFKChannelIds"]: self._afk_channel_ids.append(int(index)) - self._afk_command_channel_id = settings['AFKCommandChannelId'] - self._help_command_reference_url = settings['HelpCommandReferenceUrl'] - self._help_voice_channel_id = settings['HelpVoiceChannelId'] - for url in settings['PingURLs']: + self._afk_command_channel_id = settings["AFKCommandChannelId"] + self._help_command_reference_url = settings["HelpCommandReferenceUrl"] + self._help_voice_channel_id = settings["HelpVoiceChannelId"] + for url in settings["PingURLs"]: self._ping_urls.append(url) except Exception as e: - Console.error(f'[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings') - Console.error(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}') + Console.error(f"[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings") + Console.error(f"[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}") diff --git a/kdb-bot/src/modules/base/configuration/base_settings.py b/kdb-bot/src/modules/base/configuration/base_settings.py index 4bd57cb0..0c74132c 100644 --- a/kdb-bot/src/modules/base/configuration/base_settings.py +++ b/kdb-bot/src/modules/base/configuration/base_settings.py @@ -8,12 +8,11 @@ from modules.base.configuration.base_server_settings import BaseServerSettings class BaseSettings(ConfigurationModelABC): - def __init__(self): ConfigurationModelABC.__init__(self) self._servers: List[BaseServerSettings] = List() - + @property def servers(self) -> List[BaseServerSettings]: return self._servers @@ -23,10 +22,10 @@ class BaseSettings(ConfigurationModelABC): servers = List(BaseServerSettings) for s in settings: st = BaseServerSettings() - settings[s]['Id'] = s + settings[s]["Id"] = s st.from_dict(settings[s]) servers.append(st) self._servers = servers except Exception as e: - Console.error(f'[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings') - Console.error(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}') + Console.error(f"[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings") + Console.error(f"[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}") diff --git a/kdb-bot/src/modules/base/events/__init__.py b/kdb-bot/src/modules/base/events/__init__.py index 04f7a371..9e355bd8 100644 --- a/kdb-bot/src/modules/base/events/__init__.py +++ b/kdb-bot/src/modules/base/events/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'modules.base.events' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "modules.base.events" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/modules/base/events/base_on_command_error_event.py b/kdb-bot/src/modules/base/events/base_on_command_error_event.py index 6233d978..c9c4dcc8 100644 --- a/kdb-bot/src/modules/base/events/base_on_command_error_event.py +++ b/kdb-bot/src/modules/base/events/base_on_command_error_event.py @@ -17,15 +17,14 @@ from bot_core.exception.check_error import CheckError class BaseOnCommandErrorEvent(OnCommandErrorABC): - def __init__( - self, - logger: LoggerABC, - bot: DiscordBotServiceABC, - messenger: MessageServiceABC, - bot_settings: BotSettings, - time_format_settings: TimeFormatSettings, - translate: TranslatePipe + self, + logger: LoggerABC, + bot: DiscordBotServiceABC, + messenger: MessageServiceABC, + bot_settings: BotSettings, + time_format_settings: TimeFormatSettings, + translate: TranslatePipe, ): OnCommandErrorABC.__init__(self) self._logger = logger @@ -39,111 +38,235 @@ class BaseOnCommandErrorEvent(OnCommandErrorABC): if isinstance(error, CheckError): return - error = getattr(error, 'original', error) + error = getattr(error, "original", error) uid = uuid.uuid4() - self._logger.error(__name__, f'Got error: {type(error).__name__} UID: {uid}') + self._logger.error(__name__, f"Got error: {type(error).__name__} UID: {uid}") if isinstance(error, commands.MissingRequiredArgument): - await self._messenger.send_ctx_msg(ctx, self._t.transform('common.errors.missing_required_argument'), without_tracking=True) + await self._messenger.send_ctx_msg( + ctx, + self._t.transform("common.errors.missing_required_argument"), + without_tracking=True, + ) elif isinstance(error, commands.ArgumentParsingError): - await self._messenger.send_ctx_msg(ctx, self._t.transform('common.errors.argument_parsing_error'), without_tracking=True) + await self._messenger.send_ctx_msg( + ctx, + self._t.transform("common.errors.argument_parsing_error"), + without_tracking=True, + ) elif isinstance(error, commands.UnexpectedQuoteError): - await self._messenger.send_ctx_msg(ctx, self._t.transform('common.errors.unexpected_quote_error'), without_tracking=True) + await self._messenger.send_ctx_msg( + ctx, + self._t.transform("common.errors.unexpected_quote_error"), + without_tracking=True, + ) elif isinstance(error, commands.InvalidEndOfQuotedStringError): - await self._messenger.send_ctx_msg(ctx, self._t.transform('common.errors.invalid_end_of_quoted_string_error'), without_tracking=True) + await self._messenger.send_ctx_msg( + ctx, + self._t.transform("common.errors.invalid_end_of_quoted_string_error"), + without_tracking=True, + ) elif isinstance(error, commands.ExpectedClosingQuoteError): - await self._messenger.send_ctx_msg(ctx, self._t.transform('common.errors.expected_closing_quote_error'), without_tracking=True) + await self._messenger.send_ctx_msg( + ctx, + self._t.transform("common.errors.expected_closing_quote_error"), + without_tracking=True, + ) elif isinstance(error, commands.BadArgument): - await self._messenger.send_ctx_msg(ctx, self._t.transform('common.errors.bad_argument'), without_tracking=True) + await self._messenger.send_ctx_msg( + ctx, + self._t.transform("common.errors.bad_argument"), + without_tracking=True, + ) elif isinstance(error, commands.BadUnionArgument): - await self._messenger.send_ctx_msg(ctx, self._t.transform('common.errors.bad_union_argument'), without_tracking=True) + await self._messenger.send_ctx_msg( + ctx, + self._t.transform("common.errors.bad_union_argument"), + without_tracking=True, + ) elif isinstance(error, commands.PrivateMessageOnly): - await self._messenger.send_ctx_msg(ctx, self._t.transform('common.errors.private_message_only'), without_tracking=True) + await self._messenger.send_ctx_msg( + ctx, + self._t.transform("common.errors.private_message_only"), + without_tracking=True, + ) elif isinstance(error, commands.NoPrivateMessage): - await self._messenger.send_ctx_msg(ctx, self._t.transform('common.errors.no_private_message'), without_tracking=True) + await self._messenger.send_ctx_msg( + ctx, + self._t.transform("common.errors.no_private_message"), + without_tracking=True, + ) elif isinstance(error, commands.CheckFailure): - await self._messenger.send_ctx_msg(ctx, self._t.transform('common.errors.check_failure'), without_tracking=True) + await self._messenger.send_ctx_msg( + ctx, + self._t.transform("common.errors.check_failure"), + without_tracking=True, + ) elif isinstance(error, commands.CheckAnyFailure): - await self._messenger.send_ctx_msg(ctx, self._t.transform('common.errors.check_any_failure'), without_tracking=True) + await self._messenger.send_ctx_msg( + ctx, + self._t.transform("common.errors.check_any_failure"), + without_tracking=True, + ) elif isinstance(error, commands.CommandNotFound): - await self._messenger.send_ctx_msg(ctx, self._t.transform('common.errors.command_not_found'), without_tracking=True) + await self._messenger.send_ctx_msg( + ctx, + self._t.transform("common.errors.command_not_found"), + without_tracking=True, + ) elif isinstance(error, commands.DisabledCommand): - await self._messenger.send_ctx_msg(ctx, self._t.transform('common.errors.disabled_command'), without_tracking=True) + await self._messenger.send_ctx_msg( + ctx, + self._t.transform("common.errors.disabled_command"), + without_tracking=True, + ) elif isinstance(error, commands.CommandInvokeError): - await self._messenger.send_ctx_msg(ctx, self._t.transform('common.errors.command_invoke_error'), without_tracking=True) + await self._messenger.send_ctx_msg( + ctx, + self._t.transform("common.errors.command_invoke_error"), + without_tracking=True, + ) elif isinstance(error, commands.TooManyArguments): - await self._messenger.send_ctx_msg(ctx, self._t.transform('common.errors.too_many_arguments'), without_tracking=True) + await self._messenger.send_ctx_msg( + ctx, + self._t.transform("common.errors.too_many_arguments"), + without_tracking=True, + ) elif isinstance(error, commands.UserInputError): - await self._messenger.send_ctx_msg(ctx, self._t.transform('common.errors.user_input_error'), without_tracking=True) + await self._messenger.send_ctx_msg( + ctx, + self._t.transform("common.errors.user_input_error"), + without_tracking=True, + ) elif isinstance(error, commands.CommandOnCooldown): - await self._messenger.send_ctx_msg(ctx, self._t.transform('common.errors.command_on_cooldown'), without_tracking=True) + await self._messenger.send_ctx_msg( + ctx, + self._t.transform("common.errors.command_on_cooldown"), + without_tracking=True, + ) elif isinstance(error, commands.MaxConcurrencyReached): - await self._messenger.send_ctx_msg(ctx, self._t.transform('common.errors.max_concurrency_reached'), without_tracking=True) + await self._messenger.send_ctx_msg( + ctx, + self._t.transform("common.errors.max_concurrency_reached"), + without_tracking=True, + ) elif isinstance(error, commands.NotOwner): - await self._messenger.send_ctx_msg(ctx, self._t.transform('common.errors.not_owner'), without_tracking=True) + await self._messenger.send_ctx_msg(ctx, self._t.transform("common.errors.not_owner"), without_tracking=True) elif isinstance(error, commands.MissingPermissions): - await self._messenger.send_ctx_msg(ctx, self._t.transform('common.errors.missing_permissions'), without_tracking=True) + await self._messenger.send_ctx_msg( + ctx, + self._t.transform("common.errors.missing_permissions"), + without_tracking=True, + ) elif isinstance(error, commands.BotMissingPermissions): - await self._messenger.send_ctx_msg(ctx, self._t.transform('common.errors.bot_missing_permissions'), without_tracking=True) + await self._messenger.send_ctx_msg( + ctx, + self._t.transform("common.errors.bot_missing_permissions"), + without_tracking=True, + ) elif isinstance(error, commands.MissingRole): - await self._messenger.send_ctx_msg(ctx, self._t.transform('common.errors.missing_role'), without_tracking=True) + await self._messenger.send_ctx_msg( + ctx, + self._t.transform("common.errors.missing_role"), + without_tracking=True, + ) elif isinstance(error, commands.BotMissingRole): - await self._messenger.send_ctx_msg(ctx, self._t.transform('common.errors.bot_missing_role'), without_tracking=True) + await self._messenger.send_ctx_msg( + ctx, + self._t.transform("common.errors.bot_missing_role"), + without_tracking=True, + ) elif isinstance(error, commands.MissingAnyRole): - await self._messenger.send_ctx_msg(ctx, self._t.transform('common.errors.missing_any_role'), without_tracking=True) + await self._messenger.send_ctx_msg( + ctx, + self._t.transform("common.errors.missing_any_role"), + without_tracking=True, + ) elif isinstance(error, commands.BotMissingAnyRole): - await self._messenger.send_ctx_msg(ctx, self._t.transform('common.errors.bot_missing_any_role'), without_tracking=True) + await self._messenger.send_ctx_msg( + ctx, + self._t.transform("common.errors.bot_missing_any_role"), + without_tracking=True, + ) elif isinstance(error, commands.NSFWChannelRequired): - await self._messenger.send_ctx_msg(ctx, self._t.transform('common.errors.nsfw_channel_required'), without_tracking=True) + await self._messenger.send_ctx_msg( + ctx, + self._t.transform("common.errors.nsfw_channel_required"), + without_tracking=True, + ) elif isinstance(error, commands.ExtensionError): - await self._messenger.send_ctx_msg(ctx, self._t.transform('common.errors.extension_error'), without_tracking=True) + await self._messenger.send_ctx_msg( + ctx, + self._t.transform("common.errors.extension_error"), + without_tracking=True, + ) elif isinstance(error, commands.ExtensionAlreadyLoaded): - await self._messenger.send_ctx_msg(ctx, self._t.transform('common.errors.extension_already_loaded'), without_tracking=True) + await self._messenger.send_ctx_msg( + ctx, + self._t.transform("common.errors.extension_already_loaded"), + without_tracking=True, + ) elif isinstance(error, commands.ExtensionNotLoaded): - await self._messenger.send_ctx_msg(ctx, self._t.transform('common.errors.extension_not_loaded'), without_tracking=True) + await self._messenger.send_ctx_msg( + ctx, + self._t.transform("common.errors.extension_not_loaded"), + without_tracking=True, + ) elif isinstance(error, commands.NoEntryPointError): - await self._messenger.send_ctx_msg(ctx, self._t.transform('common.errors.no_entry_point_error'), without_tracking=True) + await self._messenger.send_ctx_msg( + ctx, + self._t.transform("common.errors.no_entry_point_error"), + without_tracking=True, + ) elif isinstance(error, commands.ExtensionFailed): - await self._messenger.send_ctx_msg(ctx, self._t.transform('common.errors.extension_failed'), without_tracking=True) + await self._messenger.send_ctx_msg( + ctx, + self._t.transform("common.errors.extension_failed"), + without_tracking=True, + ) else: - await self._messenger.send_ctx_msg(ctx, self._t.transform('common.errors.command_error'), without_tracking=True) - message = self._t.transform('modules.base.technician_command_error_message').format( + await self._messenger.send_ctx_msg( + ctx, + self._t.transform("common.errors.command_error"), + without_tracking=True, + ) + message = self._t.transform("modules.base.technician_command_error_message").format( ctx.command, ctx.author, error, datetime.datetime.now().strftime(self._time_format_settings.date_time_format), - uid + uid, ) for t in self._bot_settings.technicians: member = self._bot.get_user(t) diff --git a/kdb-bot/src/modules/base/events/base_on_command_event.py b/kdb-bot/src/modules/base/events/base_on_command_event.py index 348e9e4c..7b46564b 100644 --- a/kdb-bot/src/modules/base/events/base_on_command_event.py +++ b/kdb-bot/src/modules/base/events/base_on_command_event.py @@ -20,20 +20,19 @@ from modules.base.configuration.base_server_settings import BaseServerSettings class BaseOnCommandEvent(OnCommandABC): - def __init__( - self, - logger: CommandLogger, - bot: DiscordBotServiceABC, - messenger: MessageServiceABC, - bot_settings: BotSettings, - time_format_settings: TimeFormatSettings, - translate: TranslatePipe, - bhs: BaseHelperABC, - db: DatabaseContextABC, - users: UserRepositoryABC, - clients: ClientRepositoryABC, - servers: ServerRepositoryABC, + self, + logger: CommandLogger, + bot: DiscordBotServiceABC, + messenger: MessageServiceABC, + bot_settings: BotSettings, + time_format_settings: TimeFormatSettings, + translate: TranslatePipe, + bhs: BaseHelperABC, + db: DatabaseContextABC, + users: UserRepositoryABC, + clients: ClientRepositoryABC, + servers: ServerRepositoryABC, ): OnCommandABC.__init__(self) self._logger = logger @@ -53,25 +52,25 @@ class BaseOnCommandEvent(OnCommandABC): self._clients.append_received_command_count(self._bot.user.id, g_id, 1) self._db.save_changes() except Exception as e: - self._logger.error(__name__, f'Cannot edit client {self._bot.user.id}@{g_id}', e) + self._logger.error(__name__, f"Cannot edit client {self._bot.user.id}@{g_id}", e) def _handle_message_for_xp(self, message: discord.Message): dc_user_id = message.author.id try: server = self._servers.get_server_by_discord_id(message.guild.id) except Exception as e: - self._logger.error(__name__, f'Cannot get server {message.guild.id}', e) + self._logger.error(__name__, f"Cannot get server {message.guild.id}", e) return user: Optional[User] = None try: user = self._users.get_user_by_discord_id_and_server_id(dc_user_id, server.server_id) except Exception as e: - self._logger.error(__name__, f'Cannot get user {dc_user_id}', e) + self._logger.error(__name__, f"Cannot get user {dc_user_id}", e) return if user is None: - self._logger.error(__name__, f'User not found {dc_user_id}') + self._logger.error(__name__, f"User not found {dc_user_id}") return settings: BaseServerSettings = self._base_helper.get_config(message.guild.id) @@ -80,11 +79,11 @@ class BaseOnCommandEvent(OnCommandABC): self._users.update_user(user) self._db.save_changes() - self._logger.debug(__name__, f'User {user} sent message. xp: from {old_xp} to {user.xp}') + self._logger.debug(__name__, f"User {user} sent message. xp: from {old_xp} to {user.xp}") async def on_command(self, ctx: Context): - self._logger.debug(__name__, f'Module {type(self)} started') - self._logger.info(__name__, f'Received command: {ctx.command} from {ctx.channel}') + self._logger.debug(__name__, f"Module {type(self)} started") + self._logger.info(__name__, f"Received command: {ctx.command} from {ctx.channel}") if ctx is None or ctx.guild is None: return self._append_received_command_count(ctx.guild.id) diff --git a/kdb-bot/src/modules/base/events/base_on_member_join_event.py b/kdb-bot/src/modules/base/events/base_on_member_join_event.py index 94b0bcb6..1913532a 100644 --- a/kdb-bot/src/modules/base/events/base_on_member_join_event.py +++ b/kdb-bot/src/modules/base/events/base_on_member_join_event.py @@ -23,20 +23,19 @@ from modules.permission.abc.permission_service_abc import PermissionServiceABC class BaseOnMemberJoinEvent(OnMemberJoinABC): - def __init__( - self, - config: ConfigurationABC, - logger: LoggerABC, - base_helper: BaseHelperABC, - messenger: MessageServiceABC, - permissions: PermissionServiceABC, - db: DatabaseContextABC, - known_users: KnownUserRepositoryABC, - users: UserRepositoryABC, - servers: ServerRepositoryABC, - user_joins: UserJoinedServerRepositoryABC, - translate: TranslatePipe + self, + config: ConfigurationABC, + logger: LoggerABC, + base_helper: BaseHelperABC, + messenger: MessageServiceABC, + permissions: PermissionServiceABC, + db: DatabaseContextABC, + known_users: KnownUserRepositoryABC, + users: UserRepositoryABC, + servers: ServerRepositoryABC, + user_joins: UserJoinedServerRepositoryABC, + translate: TranslatePipe, ): OnMemberJoinABC.__init__(self) self._config = config @@ -52,28 +51,37 @@ class BaseOnMemberJoinEvent(OnMemberJoinABC): self._t = translate def _check_for_known_user(self, member: Union[discord.User, discord.Member]): - self._logger.debug(__name__, f'Check if user is already known {member}') + self._logger.debug(__name__, f"Check if user is already known {member}") try: user = self._known_users.find_user_by_discord_id(member.id) if user is not None: return - self._logger.debug(__name__, f'Add user: {member.id}') + self._logger.debug(__name__, f"Add user: {member.id}") self._known_users.add_user(KnownUser(member.id)) self._db.save_changes() except Exception as e: - self._logger.error(__name__, f'Cannot get user {member.id}', e) + self._logger.error(__name__, f"Cannot get user {member.id}", e) async def _add_if_not_exists_user_async(self, member: Union[discord.User, discord.Member]): - self._logger.debug(__name__, f'Check if user exists {member}') + self._logger.debug(__name__, f"Check if user exists {member}") settings: BaseServerSettings = self._base_helper.get_config(member.guild.id) - await self._messenger.send_dm_message(self._t.transform('modules.base.welcome_message').format(member.guild.name), member) + await self._messenger.send_dm_message( + self._t.transform("modules.base.welcome_message").format(member.guild.name), + member, + ) for admin in self._permission_service.get_admins(member.guild.id): - await self._messenger.send_dm_message(self._t.transform('modules.base.welcome_message_for_team').format(member.mention), admin) + await self._messenger.send_dm_message( + self._t.transform("modules.base.welcome_message_for_team").format(member.mention), + admin, + ) for moderator in self._permission_service.get_moderators(member.guild.id): - await self._messenger.send_dm_message(self._t.transform('modules.base.welcome_message_for_team').format(member.mention), moderator) + await self._messenger.send_dm_message( + self._t.transform("modules.base.welcome_message_for_team").format(member.mention), + moderator, + ) try: server = self._servers.get_server_by_discord_id(member.guild.id) @@ -83,17 +91,17 @@ class BaseOnMemberJoinEvent(OnMemberJoinABC): self._db.save_changes() return - self._logger.debug(__name__, f'Add user: {member.id}') + self._logger.debug(__name__, f"Add user: {member.id}") self._users.add_user(User(member.id, 0, server)) self._db.save_changes() user = self._users.get_user_by_discord_id_and_server_id(member.id, server.server_id) self._user_joins.add_user_joined_server(UserJoinedServer(user, datetime.now())) self._db.save_changes() except Exception as e: - self._logger.error(__name__, f'Cannot get user {member.id}', e) + self._logger.error(__name__, f"Cannot get user {member.id}", e) @EventChecks.check_is_ready() async def on_member_join(self, member: discord.Member): - self._logger.debug(__name__, f'Module {type(self)} started') + self._logger.debug(__name__, f"Module {type(self)} started") self._check_for_known_user(member) await self._add_if_not_exists_user_async(member) diff --git a/kdb-bot/src/modules/base/events/base_on_member_remove_event.py b/kdb-bot/src/modules/base/events/base_on_member_remove_event.py index e9987fc6..ba9217f0 100644 --- a/kdb-bot/src/modules/base/events/base_on_member_remove_event.py +++ b/kdb-bot/src/modules/base/events/base_on_member_remove_event.py @@ -17,17 +17,16 @@ from modules.base.configuration.base_server_settings import BaseServerSettings class BaseOnMemberRemoveEvent(OnMemberRemoveABC): - def __init__( - self, - logger: LoggerABC, - base_helper: BaseHelperABC, - db: DatabaseContextABC, - messenger: MessageServiceABC, - users: UserRepositoryABC, - servers: ServerRepositoryABC, - user_joins: UserJoinedServerRepositoryABC, - translate: TranslatePipe + self, + logger: LoggerABC, + base_helper: BaseHelperABC, + db: DatabaseContextABC, + messenger: MessageServiceABC, + users: UserRepositoryABC, + servers: ServerRepositoryABC, + user_joins: UserJoinedServerRepositoryABC, + translate: TranslatePipe, ): OnMemberRemoveABC.__init__(self) @@ -41,16 +40,16 @@ class BaseOnMemberRemoveEvent(OnMemberRemoveABC): self._t = translate async def _remove_user(self, member: Union[discord.User, discord.Member]): - self._logger.debug(__name__, f'Remove user {member}') + self._logger.debug(__name__, f"Remove user {member}") settings: BaseServerSettings = self._base_helper.get_config(member.guild.id) - await self._messenger.send_dm_message(self._t.transform('modules.base.goodbye_message'), member) + await self._messenger.send_dm_message(self._t.transform("modules.base.goodbye_message"), member) try: server = self._servers.get_server_by_discord_id(member.guild.id) user = self._users.find_user_by_discord_id_and_server_id(member.id, server.server_id) if user is None: - self._logger.error(__name__, f'Cannot find user {member}') + self._logger.error(__name__, f"Cannot find user {member}") return join = self._user_joins.get_active_user_joined_server_by_user_id(user.user_id) @@ -58,9 +57,9 @@ class BaseOnMemberRemoveEvent(OnMemberRemoveABC): self._user_joins.update_user_joined_server(join) self._db.save_changes() except Exception as e: - self._logger.error(__name__, f'Cannot get user {member.id}', e) + self._logger.error(__name__, f"Cannot get user {member.id}", e) @EventChecks.check_is_ready() async def on_member_remove(self, member: discord.Member): - self._logger.debug(__name__, f'Module {type(self)} started') + self._logger.debug(__name__, f"Module {type(self)} started") await self._remove_user(member) diff --git a/kdb-bot/src/modules/base/events/base_on_message_delete_event.py b/kdb-bot/src/modules/base/events/base_on_message_delete_event.py new file mode 100644 index 00000000..2ae8172a --- /dev/null +++ b/kdb-bot/src/modules/base/events/base_on_message_delete_event.py @@ -0,0 +1,85 @@ +from typing import Optional + +import discord +from cpl_core.database.context import DatabaseContextABC +from cpl_discord.events import OnMessageDeleteABC +from cpl_discord.service import DiscordBotServiceABC + +from bot_core.helper.log_message_helper import LogMessageHelper +from bot_core.logging.message_logger import MessageLogger +from bot_data.abc.client_repository_abc import ClientRepositoryABC +from bot_data.abc.server_repository_abc import ServerRepositoryABC +from bot_data.abc.user_repository_abc import UserRepositoryABC +from bot_data.model.user import User +from modules.base.abc.base_helper_abc import BaseHelperABC +from modules.base.configuration.base_server_settings import BaseServerSettings + + +class BaseOnMessageDeleteEvent(OnMessageDeleteABC): + def __init__( + self, + logger: MessageLogger, + bhs: BaseHelperABC, + db: DatabaseContextABC, + bot: DiscordBotServiceABC, + users: UserRepositoryABC, + clients: ClientRepositoryABC, + servers: ServerRepositoryABC, + ): + OnMessageDeleteABC.__init__(self) + self._logger = logger + self._base_helper = bhs + self._db = db + self._bot = bot + self._users = users + self._clients = clients + self._servers = servers + + def _append_deleted_message_count(self, g_id: int): + try: + self._clients.append_deleted_message_count(self._bot.user.id, g_id, 1) + self._db.save_changes() + except Exception as e: + self._logger.error(__name__, f"Cannot edit client {self._bot.user.id}@{g_id}", e) + + def _handle_message_delete(self, message: discord.Message): + dc_user_id = message.author.id + try: + server = self._servers.get_server_by_discord_id(message.guild.id) + except Exception as e: + self._logger.error(__name__, f"Cannot get server {message.guild.id}", e) + return + + user: Optional[User] = None + try: + user = self._users.find_user_by_discord_id_and_server_id(dc_user_id, server.server_id) + except Exception as e: + self._logger.error(__name__, f"Cannot get user {dc_user_id}", e) + return + + if user is None: + self._logger.error(__name__, f"User not found {dc_user_id}") + return + + settings: BaseServerSettings = self._base_helper.get_config(message.guild.id) + old_xp = user.xp + user.xp -= settings.xp_per_message + self._users.update_user(user) + self._db.save_changes() + + self._logger.debug( + __name__, + f"Removed message from user {user}. xp: from {old_xp} to {user.xp}", + ) + + async def on_message_delete(self, message: discord.Message): + self._logger.debug(__name__, f"Module {type(self)} started") + if message is None or message.guild is None: + return + + self._logger.info(__name__, f"Received message: {LogMessageHelper.get_log_string(message)}") + self._append_deleted_message_count(message.guild.id) + + if not message.author.bot: + self._handle_message_delete(message) + self._logger.debug(__name__, f"Module {type(self)} stopped") diff --git a/kdb-bot/src/modules/base/events/base_on_message_event.py b/kdb-bot/src/modules/base/events/base_on_message_event.py index 2d562c66..85578fda 100644 --- a/kdb-bot/src/modules/base/events/base_on_message_event.py +++ b/kdb-bot/src/modules/base/events/base_on_message_event.py @@ -8,6 +8,7 @@ from cpl_discord.service import DiscordBotServiceABC from bot_core.helper.event_checks import EventChecks from bot_core.helper.log_message_helper import LogMessageHelper from bot_core.logging.message_logger import MessageLogger +from bot_core.service.client_utils_service import ClientUtilsService from bot_data.abc.client_repository_abc import ClientRepositoryABC from bot_data.abc.server_repository_abc import ServerRepositoryABC from bot_data.abc.user_repository_abc import UserRepositoryABC @@ -17,20 +18,22 @@ from modules.base.configuration.base_server_settings import BaseServerSettings class BaseOnMessageEvent(OnMessageABC): - def __init__( - self, - logger: MessageLogger, - bhs: BaseHelperABC, - db: DatabaseContextABC, - bot: DiscordBotServiceABC, - users: UserRepositoryABC, - clients: ClientRepositoryABC, - servers: ServerRepositoryABC, + self, + logger: MessageLogger, + bhs: BaseHelperABC, + client_utils: ClientUtilsService, + db: DatabaseContextABC, + bot: DiscordBotServiceABC, + users: UserRepositoryABC, + clients: ClientRepositoryABC, + servers: ServerRepositoryABC, ): OnMessageABC.__init__(self) self._logger = logger self._base_helper = bhs + self._client_utils = client_utils + self._bot = bot self._db = db self._bot = bot self._users = users @@ -42,42 +45,49 @@ class BaseOnMessageEvent(OnMessageABC): self._clients.append_received_message_count(self._bot.user.id, g_id, 1) self._db.save_changes() except Exception as e: - self._logger.error(__name__, f'Cannot edit client {self._bot.user.id}@{g_id}', e) + self._logger.error(__name__, f"Cannot edit client {self._bot.user.id}@{g_id}", e) def _handle_message_for_xp(self, message: discord.Message): dc_user_id = message.author.id try: server = self._servers.get_server_by_discord_id(message.guild.id) except Exception as e: - self._logger.error(__name__, f'Cannot get server {message.guild.id}', e) + self._logger.error(__name__, f"Cannot get server {message.guild.id}", e) return user: Optional[User] = None try: user = self._users.find_user_by_discord_id_and_server_id(dc_user_id, server.server_id) except Exception as e: - self._logger.error(__name__, f'Cannot get user {dc_user_id}', e) + self._logger.error(__name__, f"Cannot get user {dc_user_id}", e) return if user is None: - self._logger.error(__name__, f'User not found {dc_user_id}') + self._logger.error(__name__, f"User not found {dc_user_id}") return settings: BaseServerSettings = self._base_helper.get_config(message.guild.id) + if self._client_utils.is_message_xp_count_by_hour_higher_that_max_message_count_per_hour( + message.created_at, user, settings + ): + return + old_xp = user.xp user.xp += settings.xp_per_message self._users.update_user(user) self._db.save_changes() - self._logger.debug(__name__, f'User {user} sent message. xp: from {old_xp} to {user.xp}') + self._logger.debug(__name__, f"User {user} sent message. xp: from {old_xp} to {user.xp}") @EventChecks.check_is_ready() async def on_message(self, message: discord.Message): - self._logger.debug(__name__, f'Module {type(self)} started') - self._logger.info(__name__, f'Received message: {LogMessageHelper.get_log_string(message)}') + self._logger.debug(__name__, f"Module {type(self)} started") if message is None or message.guild is None: return + + self._logger.info(__name__, f"Received message: {LogMessageHelper.get_log_string(message)}") self._append_received_message_count(message.guild.id) if not message.author.bot: self._handle_message_for_xp(message) + self._logger.debug(__name__, f"Module {type(self)} stopped") diff --git a/kdb-bot/src/modules/base/events/base_on_raw_reaction_add.py b/kdb-bot/src/modules/base/events/base_on_raw_reaction_add.py index b8fe597b..4591959e 100644 --- a/kdb-bot/src/modules/base/events/base_on_raw_reaction_add.py +++ b/kdb-bot/src/modules/base/events/base_on_raw_reaction_add.py @@ -10,14 +10,13 @@ from modules.base.helper.base_reaction_handler import BaseReactionHandler class BaseOnRawReactionAddEvent(OnRawReactionAddABC): - def __init__( - self, - logger: LoggerABC, - bot: DiscordBotServiceABC, - servers: ServerRepositoryABC, - auto_roles: AutoRoleRepositoryABC, - reaction_handler: BaseReactionHandler + self, + logger: LoggerABC, + bot: DiscordBotServiceABC, + servers: ServerRepositoryABC, + auto_roles: AutoRoleRepositoryABC, + reaction_handler: BaseReactionHandler, ): OnRawReactionAddABC.__init__(self) @@ -29,8 +28,8 @@ class BaseOnRawReactionAddEvent(OnRawReactionAddABC): @EventChecks.check_is_ready() async def on_raw_reaction_add(self, payload: RawReactionActionEvent): - self._logger.debug(__name__, f'Module {type(self)} started') + self._logger.debug(__name__, f"Module {type(self)} started") - await self._reaction_handler.handle(payload, 'add') + await self._reaction_handler.handle(payload, "add") - self._logger.debug(__name__, f'Module {type(self)} stopped') + self._logger.debug(__name__, f"Module {type(self)} stopped") diff --git a/kdb-bot/src/modules/base/events/base_on_raw_reaction_remove.py b/kdb-bot/src/modules/base/events/base_on_raw_reaction_remove.py index 4f2f0bb7..9b32cbb1 100644 --- a/kdb-bot/src/modules/base/events/base_on_raw_reaction_remove.py +++ b/kdb-bot/src/modules/base/events/base_on_raw_reaction_remove.py @@ -10,14 +10,13 @@ from modules.base.helper.base_reaction_handler import BaseReactionHandler class BaseOnRawReactionRemoveEvent(OnRawReactionRemoveABC): - def __init__( - self, - logger: LoggerABC, - bot: DiscordBotServiceABC, - servers: ServerRepositoryABC, - auto_roles: AutoRoleRepositoryABC, - reaction_handler: BaseReactionHandler, + self, + logger: LoggerABC, + bot: DiscordBotServiceABC, + servers: ServerRepositoryABC, + auto_roles: AutoRoleRepositoryABC, + reaction_handler: BaseReactionHandler, ): OnRawReactionRemoveABC.__init__(self) @@ -29,8 +28,8 @@ class BaseOnRawReactionRemoveEvent(OnRawReactionRemoveABC): @EventChecks.check_is_ready() async def on_raw_reaction_remove(self, payload: RawReactionActionEvent): - self._logger.debug(__name__, f'Module {type(self)} started') + self._logger.debug(__name__, f"Module {type(self)} started") - await self._reaction_handler.handle(payload, 'remove') + await self._reaction_handler.handle(payload, "remove") - self._logger.debug(__name__, f'Module {type(self)} stopped') + self._logger.debug(__name__, f"Module {type(self)} stopped") diff --git a/kdb-bot/src/modules/base/events/base_on_voice_state_update_event.py b/kdb-bot/src/modules/base/events/base_on_voice_state_update_event.py index 176977a9..30d8439e 100644 --- a/kdb-bot/src/modules/base/events/base_on_voice_state_update_event.py +++ b/kdb-bot/src/modules/base/events/base_on_voice_state_update_event.py @@ -11,7 +11,9 @@ from bot_core.helper.event_checks import EventChecks 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_joined_voice_channel_repository_abc import ( + UserJoinedVoiceChannelRepositoryABC, +) from bot_data.abc.user_repository_abc import UserRepositoryABC from bot_data.model.server import Server from bot_data.model.user import User @@ -21,18 +23,17 @@ from modules.base.configuration.base_server_settings import BaseServerSettings class BaseOnVoiceStateUpdateEvent(OnVoiceStateUpdateABC): - def __init__( - self, - config: ConfigurationABC, - logger: LoggerABC, - base_helper: BaseHelperABC, - servers: ServerRepositoryABC, - known_users: KnownUserRepositoryABC, - users: UserRepositoryABC, - user_joins: UserJoinedServerRepositoryABC, - user_joins_vc: UserJoinedVoiceChannelRepositoryABC, - db: DatabaseContextABC, + self, + config: ConfigurationABC, + logger: LoggerABC, + base_helper: BaseHelperABC, + servers: ServerRepositoryABC, + known_users: KnownUserRepositoryABC, + users: UserRepositoryABC, + user_joins: UserJoinedServerRepositoryABC, + user_joins_vc: UserJoinedVoiceChannelRepositoryABC, + db: DatabaseContextABC, ): OnVoiceStateUpdateABC.__init__(self) self._config = config @@ -45,18 +46,18 @@ class BaseOnVoiceStateUpdateEvent(OnVoiceStateUpdateABC): self._user_joins_vc = user_joins_vc self._db = db - self._logger.info(__name__, f'Module {type(self)} loaded') + self._logger.info(__name__, f"Module {type(self)} loaded") def _update_voice_state(self, joined: bool, dc_user_id: int, dc_channel_id: int, server: Server): user: Optional[User] = None try: user = self._users.get_user_by_discord_id_and_server_id(dc_user_id, server.server_id) except Exception as e: - self._logger.error(__name__, f'Cannot get user {dc_user_id}', e) + self._logger.error(__name__, f"Cannot get user {dc_user_id}", e) return if user is None: - self._logger.error(__name__, f'User not found {dc_user_id}') + self._logger.error(__name__, f"User not found {dc_user_id}") return try: @@ -80,41 +81,62 @@ class BaseOnVoiceStateUpdateEvent(OnVoiceStateUpdateABC): self._users.update_user(user) self._db.save_changes() - self._logger.debug(__name__, f'User {user} leaved_on {join.leaved_on}. Ontime: {ontime}h | xp: from {old_xp} to {user.xp}') + self._logger.debug( + __name__, + f"User {user} leaved_on {join.leaved_on}. Ontime: {ontime}h | xp: from {old_xp} to {user.xp}", + ) except Exception as e: - self._logger.error(__name__, f'Ontime validation failed', e) + self._logger.error(__name__, f"Ontime validation failed", e) @EventChecks.check_is_ready() - async def on_voice_state_update(self, member: discord.Member, before: discord.VoiceState, after: discord.VoiceState): - self._logger.debug(__name__, f'Module {type(self)} started') - self._logger.trace(__name__, f'Detected on_voice_state_update {member.id} from {before} to {after}') + async def on_voice_state_update( + self, + member: discord.Member, + before: discord.VoiceState, + after: discord.VoiceState, + ): + self._logger.debug(__name__, f"Module {type(self)} started") + self._logger.trace( + __name__, + f"Detected on_voice_state_update {member.id} from {before} to {after}", + ) settings: BaseServerSettings = self._base_helper.get_config(member.guild.id) server = self._servers.get_server_by_discord_id(member.guild.id) try: # join - if before.channel is None and after.channel is not None and after.channel.id not in settings.afk_channel_ids: - self._logger.trace(__name__, f'User {member.id} joined {after.channel}') + if ( + before.channel is None + and after.channel is not None + and after.channel.id not in settings.afk_channel_ids + ): + self._logger.trace(__name__, f"User {member.id} joined {after.channel}") self._update_voice_state(True, member.id, after.channel.id, server) # leave - elif before.channel is not None and after.channel is None and before.channel.id not in settings.afk_channel_ids: - self._logger.trace(__name__, f'User {member.id} left {before.channel}') + elif ( + before.channel is not None + and after.channel is None + and before.channel.id not in settings.afk_channel_ids + ): + self._logger.trace(__name__, f"User {member.id} left {before.channel}") self._update_voice_state(False, member.id, before.channel.id, server) # channel to channel elif before.channel is not None and after.channel is not None: # joined if before.channel.id in settings.afk_channel_ids and after.channel.id not in settings.afk_channel_ids: - self._logger.trace(__name__, f'User {member.id} joined {after.channel}') + self._logger.trace(__name__, f"User {member.id} joined {after.channel}") self._update_voice_state(True, member.id, after.channel.id, server) # left elif after.channel.id in settings.afk_channel_ids and before.channel.id not in settings.afk_channel_ids: - self._logger.trace(__name__, f'User {member.id} left {before.channel}') + self._logger.trace(__name__, f"User {member.id} left {before.channel}") self._update_voice_state(False, member.id, before.channel.id, server) else: - self._logger.trace(__name__, f'User {member.id} switched to {after.channel}') + self._logger.trace(__name__, f"User {member.id} switched to {after.channel}") + self._update_voice_state(False, member.id, before.channel.id, server) + self._update_voice_state(True, member.id, after.channel.id, server) except Exception as e: - self._logger.error(__name__, f'Cannot handle voice state for user {member.id}', e) + self._logger.error(__name__, f"Cannot handle voice state for user {member.id}", e) diff --git a/kdb-bot/src/modules/base/events/base_on_voice_state_update_event_help_channel.py b/kdb-bot/src/modules/base/events/base_on_voice_state_update_event_help_channel.py index b2b98f37..15405cc8 100644 --- a/kdb-bot/src/modules/base/events/base_on_voice_state_update_event_help_channel.py +++ b/kdb-bot/src/modules/base/events/base_on_voice_state_update_event_help_channel.py @@ -13,16 +13,15 @@ from modules.permission.abc.permission_service_abc import PermissionServiceABC class BaseOnVoiceStateUpdateEventHelpChannel(OnVoiceStateUpdateABC): - def __init__( - self, - config: ConfigurationABC, - logger: LoggerABC, - base_helper: BaseHelperABC, - servers: ServerRepositoryABC, - permissions: PermissionServiceABC, - message_service: MessageServiceABC, - t: TranslatePipe, + self, + config: ConfigurationABC, + logger: LoggerABC, + base_helper: BaseHelperABC, + servers: ServerRepositoryABC, + permissions: PermissionServiceABC, + message_service: MessageServiceABC, + t: TranslatePipe, ): OnVoiceStateUpdateABC.__init__(self) self._config = config @@ -33,21 +32,29 @@ class BaseOnVoiceStateUpdateEventHelpChannel(OnVoiceStateUpdateABC): self._message_service = message_service self._t = t - self._logger.info(__name__, f'Module {type(self)} loaded') + self._logger.info(__name__, f"Module {type(self)} loaded") @EventChecks.check_is_ready() - async def on_voice_state_update(self, member: discord.Member, before: discord.VoiceState, after: discord.VoiceState): - self._logger.debug(__name__, f'Module {type(self)} started') + async def on_voice_state_update( + self, + member: discord.Member, + before: discord.VoiceState, + after: discord.VoiceState, + ): + self._logger.debug(__name__, f"Module {type(self)} started") server = self._servers.get_server_by_discord_id(member.guild.id) settings: BaseServerSettings = self._base_helper.get_config(server.discord_server_id) if after.channel is None or after.channel.id != settings.help_voice_channel_id: return - mods = [*self._permissions.get_admins(member.guild.id), *self._permissions.get_moderators(member.guild.id)] + mods = [ + *self._permissions.get_admins(member.guild.id), + *self._permissions.get_moderators(member.guild.id), + ] for a in mods: await self._message_service.send_dm_message( - self._t.transform('modules.base.member_joined_help_voice_channel').format(member.mention), + self._t.transform("modules.base.member_joined_help_voice_channel").format(member.mention), a, ) - self._logger.debug(__name__, f'Module {type(self)} stopped') + self._logger.debug(__name__, f"Module {type(self)} stopped") diff --git a/kdb-bot/src/modules/base/helper/__init__.py b/kdb-bot/src/modules/base/helper/__init__.py index 620faeb3..28f77684 100644 --- a/kdb-bot/src/modules/base/helper/__init__.py +++ b/kdb-bot/src/modules/base/helper/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'modules.base.helper' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "modules.base.helper" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/modules/base/helper/base_reaction_handler.py b/kdb-bot/src/modules/base/helper/base_reaction_handler.py index eb75a54a..407c1ece 100644 --- a/kdb-bot/src/modules/base/helper/base_reaction_handler.py +++ b/kdb-bot/src/modules/base/helper/base_reaction_handler.py @@ -1,8 +1,12 @@ +from datetime import datetime + from cpl_core.database.context import DatabaseContextABC from cpl_core.logging import LoggerABC from cpl_discord.service import DiscordBotServiceABC from discord import RawReactionActionEvent +from bot_core.abc.client_utils_abc import ClientUtilsABC +from bot_core.helper.log_message_helper import LogMessageHelper from bot_data.abc.server_repository_abc import ServerRepositoryABC from bot_data.abc.user_repository_abc import UserRepositoryABC from modules.base.abc.base_helper_abc import BaseHelperABC @@ -10,32 +14,50 @@ from modules.base.configuration.base_server_settings import BaseServerSettings class BaseReactionHandler: - def __init__( - self, - logger: LoggerABC, - bot: DiscordBotServiceABC, - servers: ServerRepositoryABC, - users: UserRepositoryABC, - base_helper: BaseHelperABC, - db: DatabaseContextABC, + self, + logger: LoggerABC, + bot: DiscordBotServiceABC, + servers: ServerRepositoryABC, + users: UserRepositoryABC, + base_helper: BaseHelperABC, + client_utils: ClientUtilsABC, + db: DatabaseContextABC, ): self._logger = logger self._bot = bot self._servers = servers self._users = users self._base_helper = base_helper + self._client_utils = client_utils self._db = db async def handle(self, payload: RawReactionActionEvent, r_type=None) -> None: - self._logger.trace(__name__, f'Handle reaction {payload} {r_type}') + self._logger.trace(__name__, f"Handle reaction {payload} {r_type}") guild = self._bot.get_guild(payload.guild_id) member = guild.get_member(payload.user_id) if member is None: - self._logger.warn(__name__, f'User {payload.user_id} in {guild.name} not found - skipping') + self._logger.warn(__name__, f"User {payload.user_id} in {guild.name} not found - skipping") return + try: + log_msg = f"{member.name} reacted" + if payload.emoji.name is not None: + log_msg += f" with {payload.emoji.name}" + try: + channel = guild.get_channel(payload.channel_id) + message = await channel.fetch_message(payload.message_id) + self._logger.info( + __name__, + f"{log_msg} to message {LogMessageHelper.get_log_string(message)}", + ) + except Exception as e: + self._logger.error(__name__, f"Getting message for reaction logging failed", e) + self._logger.info(__name__, f"{log_msg} to message {payload.message_id}") + except Exception as e: + self._logger.error(__name__, f"Reaction logging failed", e) + if member.bot: return @@ -43,13 +65,18 @@ class BaseReactionHandler: user = self._users.get_user_by_discord_id_and_server_id(member.id, server.server_id) settings: BaseServerSettings = self._base_helper.get_config(guild.id) - if r_type == 'add': + if r_type == "add": + if self._client_utils.is_message_xp_count_by_hour_higher_that_max_message_count_per_hour( + datetime.now(), user, settings, is_reaction=True + ): + return + user.xp += settings.xp_per_reaction self._users.update_user(user) self._db.save_changes() - elif r_type == 'remove': + elif r_type == "remove": user.xp -= settings.xp_per_reaction self._users.update_user(user) self._db.save_changes() else: - self._logger.warn(__name__, f'Invalid reaction type {r_type}') + self._logger.warn(__name__, f"Invalid reaction type {r_type}") diff --git a/kdb-bot/src/modules/base/service/__init__.py b/kdb-bot/src/modules/base/service/__init__.py index 92e0c816..719b7314 100644 --- a/kdb-bot/src/modules/base/service/__init__.py +++ b/kdb-bot/src/modules/base/service/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'modules.base.service' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "modules.base.service" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/modules/base/service/base_helper_service.py b/kdb-bot/src/modules/base/service/base_helper_service.py index e039ecfa..89c9d9c3 100644 --- a/kdb-bot/src/modules/base/service/base_helper_service.py +++ b/kdb-bot/src/modules/base/service/base_helper_service.py @@ -5,10 +5,9 @@ from modules.base.configuration.base_server_settings import BaseServerSettings class BaseHelperService(BaseHelperABC): - def __init__(self, config: ConfigurationABC): BaseHelperABC.__init__(self) self._config = config def get_config(self, g_id: int) -> BaseServerSettings: - return self._config.get_configuration(f'BaseServerSettings_{g_id}') + return self._config.get_configuration(f"BaseServerSettings_{g_id}") diff --git a/kdb-bot/src/modules/base/thread/__init__.py b/kdb-bot/src/modules/base/thread/__init__.py index 49bf9ba7..20cd2f0c 100644 --- a/kdb-bot/src/modules/base/thread/__init__.py +++ b/kdb-bot/src/modules/base/thread/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'modules.base.thread' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "modules.base.thread" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/modules/boot_log/__init__.py b/kdb-bot/src/modules/boot_log/__init__.py index e5cc21aa..b24415e8 100644 --- a/kdb-bot/src/modules/boot_log/__init__.py +++ b/kdb-bot/src/modules/boot_log/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'modules.boot_log' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "modules.boot_log" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple -# imports: +# imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/modules/boot_log/boot-log.json b/kdb-bot/src/modules/boot_log/boot-log.json index 589256d7..00610d31 100644 --- a/kdb-bot/src/modules/boot_log/boot-log.json +++ b/kdb-bot/src/modules/boot_log/boot-log.json @@ -4,7 +4,7 @@ "Version": { "Major": "0", "Minor": "3", - "Micro": "0" + "Micro": "1" }, "Author": "", "AuthorEmail": "", diff --git a/kdb-bot/src/modules/boot_log/boot_log_extension.py b/kdb-bot/src/modules/boot_log/boot_log_extension.py index bec9f1f7..62b7c6c7 100644 --- a/kdb-bot/src/modules/boot_log/boot_log_extension.py +++ b/kdb-bot/src/modules/boot_log/boot_log_extension.py @@ -10,7 +10,6 @@ from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings class BootLogExtension(ApplicationExtensionABC): - def __init__(self): pass @@ -19,5 +18,5 @@ class BootLogExtension(ApplicationExtensionABC): if not feature_flags.get_flag(FeatureFlagsEnum.boot_log_module): return logger: LoggerABC = services.get_service(LoggerABC) - logger.debug(__name__, 'BootLog extension started') - config.add_configuration('Bot_StartTime', str(datetime.now())) + logger.debug(__name__, "BootLog extension started") + config.add_configuration("Bot_StartTime", str(datetime.now())) diff --git a/kdb-bot/src/modules/boot_log/boot_log_module.py b/kdb-bot/src/modules/boot_log/boot_log_module.py index ac7ae4bb..94a1cc14 100644 --- a/kdb-bot/src/modules/boot_log/boot_log_module.py +++ b/kdb-bot/src/modules/boot_log/boot_log_module.py @@ -10,7 +10,6 @@ from modules.boot_log.boot_log_on_ready_event import BootLogOnReadyEvent class BootLogModule(ModuleABC): - def __init__(self, dc: DiscordCollectionABC): ModuleABC.__init__(self, dc, FeatureFlagsEnum.boot_log_module) diff --git a/kdb-bot/src/modules/boot_log/boot_log_on_ready_event.py b/kdb-bot/src/modules/boot_log/boot_log_on_ready_event.py index 5b90a89c..bfa0367d 100644 --- a/kdb-bot/src/modules/boot_log/boot_log_on_ready_event.py +++ b/kdb-bot/src/modules/boot_log/boot_log_on_ready_event.py @@ -9,18 +9,19 @@ from discord import guild from bot_core.abc.message_service_abc import MessageServiceABC from bot_core.configuration.server_settings import ServerSettings -from modules.boot_log.configuration.boot_log_server_settings import BootLogServerSettings +from modules.boot_log.configuration.boot_log_server_settings import ( + BootLogServerSettings, +) class BootLogOnReadyEvent(OnReadyABC): - def __init__( - self, - config: ConfigurationABC, - logger: LoggerABC, - bot: DiscordBotServiceABC, - message_service: MessageServiceABC, - translate: TranslatePipe + self, + config: ConfigurationABC, + logger: LoggerABC, + bot: DiscordBotServiceABC, + message_service: MessageServiceABC, + translate: TranslatePipe, ): OnReadyABC.__init__(self) self._config = config @@ -30,49 +31,48 @@ class BootLogOnReadyEvent(OnReadyABC): self._message_service = message_service self._t = translate - self._logger.info(__name__, f'Module {type(self)} loaded') + self._logger.info(__name__, f"Module {type(self)} loaded") async def on_ready(self): - self._logger.debug(__name__, f'Module {type(self)} started') + self._logger.debug(__name__, f"Module {type(self)} started") try: - start_time = self._config.get_configuration('Bot_StartTime') - init_time = round((datetime.now() - datetime.strptime(start_time, '%Y-%m-%d %H:%M:%S.%f')).total_seconds(), 2) - self._config.add_configuration('InitTime', str(init_time)) - self._logger.debug(__name__, f'Bot Init time: {init_time}s') + start_time = self._config.get_configuration("Bot_StartTime") + init_time = round( + (datetime.now() - datetime.strptime(start_time, "%Y-%m-%d %H:%M:%S.%f")).total_seconds(), + 2, + ) + self._config.add_configuration("InitTime", str(init_time)) + self._logger.debug(__name__, f"Bot Init time: {init_time}s") # print warning if initialisation took too long if init_time >= 30: - self._logger.warn( - __name__, 'It takes too long to start the bot!') + self._logger.warn(__name__, "It takes too long to start the bot!") # print error if initialisation took way too long elif init_time >= 90: - self._logger.error( - __name__, 'It takes far too long to start the bot!!!') + self._logger.error(__name__, "It takes far too long to start the bot!!!") except Exception as e: - self._logger.error(__name__, 'Init time calculation failed', e) + self._logger.error(__name__, "Init time calculation failed", e) return for g in self._bot.guilds: g: guild = g - self._logger.debug(__name__, f'Server detected: {g.id}') + self._logger.debug(__name__, f"Server detected: {g.id}") - server_settings: ServerSettings = self._config.get_configuration(f'ServerSettings_{g.id}') + server_settings: ServerSettings = self._config.get_configuration(f"ServerSettings_{g.id}") if server_settings is None: - self._logger.error(__name__, f'BootLog settings for server {g.id} not found!') + self._logger.error(__name__, f"BootLog settings for server {g.id} not found!") return - module_settings: BootLogServerSettings = self._config.get_configuration(f'BootLogServerSettings_{g.id}') + module_settings: BootLogServerSettings = self._config.get_configuration(f"BootLogServerSettings_{g.id}") if module_settings is None: - self._logger.error(__name__, f'Config {type(self).__name__}_{g.id} not found!') + self._logger.error(__name__, f"Config {type(self).__name__}_{g.id} not found!") return await self._message_service.send_channel_message( - self._bot.get_channel( - module_settings.login_message_channel_id - ), - self._t.transform('modules.boot_log.login_message').format(init_time) + self._bot.get_channel(module_settings.login_message_channel_id), + self._t.transform("modules.boot_log.login_message").format(init_time), ) - self._config.add_configuration('IS_READY', 'true') - self._logger.info(__name__, 'Bot is ready') - self._logger.trace(__name__, f'Module {type(self)} stopped') + self._config.add_configuration("IS_READY", "true") + self._logger.info(__name__, "Bot is ready") + self._logger.trace(__name__, f"Module {type(self)} stopped") diff --git a/kdb-bot/src/modules/boot_log/configuration/__init__.py b/kdb-bot/src/modules/boot_log/configuration/__init__.py index 0d76108e..c373fc0e 100644 --- a/kdb-bot/src/modules/boot_log/configuration/__init__.py +++ b/kdb-bot/src/modules/boot_log/configuration/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'modules.boot_log.configuration' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "modules.boot_log.configuration" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/modules/boot_log/configuration/boot_log_server_settings.py b/kdb-bot/src/modules/boot_log/configuration/boot_log_server_settings.py index a2d3c190..148609af 100644 --- a/kdb-bot/src/modules/boot_log/configuration/boot_log_server_settings.py +++ b/kdb-bot/src/modules/boot_log/configuration/boot_log_server_settings.py @@ -5,7 +5,6 @@ from cpl_core.console import Console class BootLogServerSettings(ConfigurationModelABC): - def __init__(self): ConfigurationModelABC.__init__(self) @@ -15,15 +14,15 @@ class BootLogServerSettings(ConfigurationModelABC): @property def id(self) -> int: return self._id - + @property def login_message_channel_id(self) -> int: return self._login_message_channel_id def from_dict(self, settings: dict): try: - self._id = int(settings['Id']) - self._login_message_channel_id = int(settings['LoginMessageChannelId']) + self._id = int(settings["Id"]) + self._login_message_channel_id = int(settings["LoginMessageChannelId"]) except Exception as e: - Console.error(f'[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings') - Console.error(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}') + Console.error(f"[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings") + Console.error(f"[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}") diff --git a/kdb-bot/src/modules/boot_log/configuration/boot_log_settings.py b/kdb-bot/src/modules/boot_log/configuration/boot_log_settings.py index 3903c5e2..d06ed5fb 100644 --- a/kdb-bot/src/modules/boot_log/configuration/boot_log_settings.py +++ b/kdb-bot/src/modules/boot_log/configuration/boot_log_settings.py @@ -4,11 +4,12 @@ from cpl_core.configuration.configuration_model_abc import ConfigurationModelABC from cpl_core.console import Console from cpl_query.extension import List -from modules.boot_log.configuration.boot_log_server_settings import BootLogServerSettings +from modules.boot_log.configuration.boot_log_server_settings import ( + BootLogServerSettings, +) class BootLogSettings(ConfigurationModelABC): - def __init__(self): ConfigurationModelABC.__init__(self) @@ -23,10 +24,10 @@ class BootLogSettings(ConfigurationModelABC): servers = List(BootLogServerSettings) for s in settings: st = BootLogServerSettings() - settings[s]['Id'] = s + settings[s]["Id"] = s st.from_dict(settings[s]) servers.append(st) self._servers = servers except Exception as e: - Console.error(f'[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings') - Console.error(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}') + Console.error(f"[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings") + Console.error(f"[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}") diff --git a/kdb-bot/src/modules/database/__init__.py b/kdb-bot/src/modules/database/__init__.py index 0615d2a1..218c25f4 100644 --- a/kdb-bot/src/modules/database/__init__.py +++ b/kdb-bot/src/modules/database/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'modules.database' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "modules.database" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple -# imports: +# imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/modules/database/database.json b/kdb-bot/src/modules/database/database.json index ccd2c9c2..bcbe621d 100644 --- a/kdb-bot/src/modules/database/database.json +++ b/kdb-bot/src/modules/database/database.json @@ -4,7 +4,7 @@ "Version": { "Major": "0", "Minor": "3", - "Micro": "0" + "Micro": "1" }, "Author": "Sven Heidemann", "AuthorEmail": "sven.heidemann@sh-edraft.de", diff --git a/kdb-bot/src/modules/database/database_extension.py b/kdb-bot/src/modules/database/database_extension.py index 1cc7a77f..88682ca0 100644 --- a/kdb-bot/src/modules/database/database_extension.py +++ b/kdb-bot/src/modules/database/database_extension.py @@ -13,7 +13,6 @@ from bot_data.service.seeder_service import SeederService class DatabaseExtension(ApplicationExtensionABC): - def __init__(self): pass @@ -22,7 +21,7 @@ class DatabaseExtension(ApplicationExtensionABC): if not feature_flags.get_flag(FeatureFlagsEnum.data_module): return logger: LoggerABC = services.get_service(DatabaseLogger) - logger.debug(__name__, 'Database extension started') - config.add_configuration('Database_StartTime', str(datetime.now())) + logger.debug(__name__, "Database extension started") + config.add_configuration("Database_StartTime", str(datetime.now())) migrations: MigrationService = services.get_service(MigrationService) migrations.migrate() diff --git a/kdb-bot/src/modules/database/database_module.py b/kdb-bot/src/modules/database/database_module.py index 52fdac9c..cf478645 100644 --- a/kdb-bot/src/modules/database/database_module.py +++ b/kdb-bot/src/modules/database/database_module.py @@ -10,7 +10,6 @@ from modules.database.database_on_ready_event import DatabaseOnReadyEvent class DatabaseModule(ModuleABC): - def __init__(self, dc: DiscordCollectionABC): ModuleABC.__init__(self, dc, FeatureFlagsEnum.database_module) diff --git a/kdb-bot/src/modules/database/database_on_ready_event.py b/kdb-bot/src/modules/database/database_on_ready_event.py index 96f013ee..08aa8177 100644 --- a/kdb-bot/src/modules/database/database_on_ready_event.py +++ b/kdb-bot/src/modules/database/database_on_ready_event.py @@ -12,7 +12,9 @@ from bot_core.pipes.date_time_offset_pipe import DateTimeOffsetPipe from bot_data.abc.client_repository_abc import ClientRepositoryABC from bot_data.abc.known_user_repository_abc import KnownUserRepositoryABC 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_joined_voice_channel_repository_abc import ( + UserJoinedVoiceChannelRepositoryABC, +) from bot_data.abc.user_repository_abc import UserRepositoryABC from bot_data.model.client import Client from bot_data.model.known_user import KnownUser @@ -26,7 +28,6 @@ from modules.base.configuration.base_server_settings import BaseServerSettings class DatabaseOnReadyEvent(OnReadyABC): - def __init__( self, config: ConfigurationABC, @@ -40,7 +41,7 @@ class DatabaseOnReadyEvent(OnReadyABC): known_users: KnownUserRepositoryABC, user_joins: UserJoinedServerRepositoryABC, user_joins_vc: UserJoinedVoiceChannelRepositoryABC, - dtp: DateTimeOffsetPipe + dtp: DateTimeOffsetPipe, ): self._config = config @@ -57,55 +58,56 @@ class DatabaseOnReadyEvent(OnReadyABC): self._dtp = dtp OnReadyABC.__init__(self) - self._logger.info(__name__, f'Module {type(self)} loaded') + self._logger.info(__name__, f"Module {type(self)} loaded") def _validate_init_time(self): try: - start_time = self._config.get_configuration('Database_StartTime') - init_time = round((datetime.now() - datetime.strptime(start_time, '%Y-%m-%d %H:%M:%S.%f')).total_seconds(), 2) - self._config.add_configuration('Database_InitTime', str(init_time)) - self._logger.debug(__name__, f'Database Init time: {init_time}s') + start_time = self._config.get_configuration("Database_StartTime") + init_time = round( + (datetime.now() - datetime.strptime(start_time, "%Y-%m-%d %H:%M:%S.%f")).total_seconds(), + 2, + ) + self._config.add_configuration("Database_InitTime", str(init_time)) + self._logger.debug(__name__, f"Database Init time: {init_time}s") # print warning if initialisation took too long if init_time >= 30: - self._logger.warn( - __name__, 'It takes too long to prepare the database!') + self._logger.warn(__name__, "It takes too long to prepare the database!") # print error if initialisation took way too long elif init_time >= 90: - self._logger.error( - __name__, 'It takes far too long to prepare the database!!!') + self._logger.error(__name__, "It takes far too long to prepare the database!!!") except Exception as e: # - self._logger.error(__name__, 'Database init time calculation failed', e) + self._logger.error(__name__, "Database init time calculation failed", e) return def _check_known_users(self): - self._logger.debug(__name__, f'Start checking KnownUsers table, {len(self._bot.users)}') + self._logger.debug(__name__, f"Start checking KnownUsers table, {len(self._bot.users)}") for u in self._bot.users: u: discord.User = u try: if u.bot: - self._logger.trace(__name__, f'User {u.id} is ignored, because its a bot') + self._logger.trace(__name__, f"User {u.id} is ignored, because its a bot") continue user = self._known_users.find_user_by_discord_id(u.id) if user is not None: continue - self._logger.warn(__name__, f'Unknown user: {u.id}') - self._logger.debug(__name__, f'Add user: {u.id}') + self._logger.warn(__name__, f"Unknown user: {u.id}") + self._logger.debug(__name__, f"Add user: {u.id}") self._known_users.add_user(KnownUser(u.id)) self._db_context.save_changes() user = self._known_users.find_user_by_discord_id(u.id) if user is None: - self._logger.fatal(__name__, f'Cannot add user: {u.id}') + self._logger.fatal(__name__, f"Cannot add user: {u.id}") - self._logger.debug(__name__, f'Added user: {u.id}') + self._logger.debug(__name__, f"Added user: {u.id}") except Exception as e: - self._logger.error(__name__, f'Cannot get user', e) + self._logger.error(__name__, f"Cannot get user", e) def _check_servers(self): - self._logger.debug(__name__, f'Start checking Servers table') + self._logger.debug(__name__, f"Start checking Servers table") for g in self._bot.guilds: g: discord.Guild = g try: @@ -113,123 +115,137 @@ class DatabaseOnReadyEvent(OnReadyABC): if server is not None: continue - self._logger.warn(__name__, f'Server not found in database: {g.id}') - self._logger.debug(__name__, f'Add server: {g.id}') + self._logger.warn(__name__, f"Server not found in database: {g.id}") + self._logger.debug(__name__, f"Add server: {g.id}") self._servers.add_server(Server(g.id)) self._db_context.save_changes() server = self._servers.find_server_by_discord_id(g.id) if server is None: - self._logger.fatal(__name__, f'Cannot add server: {g.id}') + self._logger.fatal(__name__, f"Cannot add server: {g.id}") - self._logger.debug(__name__, f'Added server: {g.id}') + self._logger.debug(__name__, f"Added server: {g.id}") except Exception as e: - self._logger.error(__name__, f'Cannot get server', e) + self._logger.error(__name__, f"Cannot get server", e) results = self._servers.get_servers() if results is None or len(results) == 0: - self._logger.error(__name__, f'Table Servers is empty!') + self._logger.error(__name__, f"Table Servers is empty!") def _check_clients(self): - self._logger.debug(__name__, f'Start checking Clients table') + self._logger.debug(__name__, f"Start checking Clients table") for g in self._bot.guilds: g: discord.Guild = g try: server: Server = self._servers.find_server_by_discord_id(g.id) if server is None: - self._logger.fatal(__name__, f'Server not found in database: {g.id}') + self._logger.fatal(__name__, f"Server not found in database: {g.id}") client = self._clients.find_client_by_server_id(server.server_id) if client is not None: continue - self._logger.warn(__name__, f'Client for server {g.id} not found in database: {self._bot.user.id}') - self._logger.debug(__name__, f'Add client: {self._bot.user.id}') + self._logger.warn( + __name__, + f"Client for server {g.id} not found in database: {self._bot.user.id}", + ) + self._logger.debug(__name__, f"Add client: {self._bot.user.id}") self._clients.add_client(Client(self._bot.user.id, 0, 0, 0, 0, 0, server)) self._db_context.save_changes() client = self._clients.find_client_by_server_id(server.server_id) if client is None: - self._logger.fatal(__name__, f'Cannot add client {self._bot.user.id} for server {g.id}') + self._logger.fatal( + __name__, + f"Cannot add client {self._bot.user.id} for server {g.id}", + ) - self._logger.debug(__name__, f'Added client: {g.id}') + self._logger.debug(__name__, f"Added client: {g.id}") except Exception as e: - self._logger.error(__name__, f'Cannot get client', e) + self._logger.error(__name__, f"Cannot get client", e) results = self._servers.get_servers() if results is None or len(results) == 0: - self._logger.error(__name__, f'Table Servers is empty!') + self._logger.error(__name__, f"Table Servers is empty!") def _check_users(self): - self._logger.debug(__name__, f'Start checking Users table') + self._logger.debug(__name__, f"Start checking Users table") for g in self._bot.guilds: g: discord.Guild = g try: server = self._servers.find_server_by_discord_id(g.id) if server is None: - self._logger.fatal(__name__, f'Server not found in database: {g.id}') + self._logger.fatal(__name__, f"Server not found in database: {g.id}") for u in g.members: u: Union[discord.Member, discord.User] = u if u.bot: - self._logger.trace(__name__, f'User {u.id} is ignored, because its a bot') + self._logger.trace(__name__, f"User {u.id} is ignored, because its a bot") continue user = self._users.find_user_by_discord_id_and_server_id(u.id, server.server_id) if user is not None: continue - self._logger.warn(__name__, f'User not found in database: {u.id}') - self._logger.debug(__name__, f'Add user: {u.id}') + self._logger.warn(__name__, f"User not found in database: {u.id}") + self._logger.debug(__name__, f"Add user: {u.id}") self._users.add_user(User(u.id, 0, server)) self._db_context.save_changes() - self._logger.debug(__name__, f'Added User: {u.id}') + self._logger.debug(__name__, f"Added User: {u.id}") except Exception as e: - self._logger.error(__name__, f'Cannot get User', e) + self._logger.error(__name__, f"Cannot get User", e) results = self._users.get_users() if results is None or len(results) == 0: - self._logger.error(__name__, f'Table Users is empty!') + self._logger.error(__name__, f"Table Users is empty!") def _check_user_joins(self): - self._logger.debug(__name__, f'Start checking UserJoinedServers table') + self._logger.debug(__name__, f"Start checking UserJoinedServers table") for guild in self._bot.guilds: guild: discord.Guild = guild server = self._servers.find_server_by_discord_id(guild.id) if server is None: - self._logger.fatal(__name__, f'Server not found in database: {guild.id}') + self._logger.fatal(__name__, f"Server not found in database: {guild.id}") try: for u in guild.members: u: discord.User = u if u.bot: - self._logger.trace(__name__, f'User {u.id} is ignored, because its a bot') + self._logger.trace(__name__, f"User {u.id} is ignored, because its a bot") continue user = self._users.find_user_by_discord_id_and_server_id(u.id, server.server_id) if user is None: - self._logger.fatal(__name__, f'User not found in database: {u.id}') + self._logger.fatal(__name__, f"User not found in database: {u.id}") join = self._user_joins.find_active_user_joined_server_by_user_id(user.user_id) if join is not None: continue m: discord.Member = u - self._logger.warn(__name__, f'Active UserJoinedServer not found in database: {guild.id}:{u.id}@{m.joined_at}') - self._logger.debug(__name__, f'Add UserJoinedServer: {guild.id}:{u.id}@{m.joined_at}') - self._user_joins.add_user_joined_server(UserJoinedServer(user, self._dtp.transform(m.joined_at), None)) + self._logger.warn( + __name__, + f"Active UserJoinedServer not found in database: {guild.id}:{u.id}@{m.joined_at}", + ) + self._logger.debug( + __name__, + f"Add UserJoinedServer: {guild.id}:{u.id}@{m.joined_at}", + ) + self._user_joins.add_user_joined_server( + UserJoinedServer(user, self._dtp.transform(m.joined_at), None) + ) self._db_context.save_changes() - self._logger.debug(__name__, f'Added UserJoinedServer: {u.id}') + self._logger.debug(__name__, f"Added UserJoinedServer: {u.id}") except Exception as e: - self._logger.error(__name__, f'Cannot get UserJoinedServer', e) + self._logger.error(__name__, f"Cannot get UserJoinedServer", e) results = self._users.get_users() if results is None or len(results) == 0: - self._logger.error(__name__, f'Table Users is empty!') + self._logger.error(__name__, f"Table Users is empty!") joins = self._user_joins.get_user_joined_servers() for join in joins: @@ -242,41 +258,49 @@ class DatabaseOnReadyEvent(OnReadyABC): dc_user = guild.get_member(join.user.discord_id) if dc_user is None: - self._logger.warn(__name__, f'User {join.user.discord_id} already left the server.') + self._logger.warn( + __name__, + f"User {join.user.discord_id} already left the server.", + ) join.leaved_on = datetime.now() self._user_joins.update_user_joined_server(join) self._db_context.save_changes() def _check_user_joins_vc(self): - self._logger.debug(__name__, f'Start checking UserJoinedVoiceChannel table') + self._logger.debug(__name__, f"Start checking UserJoinedVoiceChannel table") for guild in self._bot.guilds: guild: discord.Guild = guild server = self._servers.find_server_by_discord_id(guild.id) if server is None: - self._logger.fatal(__name__, f'Server not found in database: {guild.id}') + self._logger.fatal(__name__, f"Server not found in database: {guild.id}") try: for member in guild.members: if member.bot: - self._logger.trace(__name__, f'User {member.id} is ignored, because its a bot') + self._logger.trace(__name__, f"User {member.id} is ignored, because its a bot") continue user = self._users.find_user_by_discord_id_and_server_id(member.id, server.server_id) if user is None: - self._logger.fatal(__name__, f'User not found in database: {member.id}') + self._logger.fatal(__name__, f"User not found in database: {member.id}") joins = self._user_joins_vc.find_active_user_joined_voice_channels_by_user_id(user.user_id) if joins is None or len(joins) == 0: continue for join in joins: - self._logger.warn(__name__, f'Active UserJoinedVoiceChannel found in database: {guild.id}:{member.id}@{join.joined_on}') + self._logger.warn( + __name__, + f"Active UserJoinedVoiceChannel found in database: {guild.id}:{member.id}@{join.joined_on}", + ) join.leaved_on = datetime.now() - settings: BaseServerSettings = self._config.get_configuration(f'BaseServerSettings_{guild.id}') + settings: BaseServerSettings = self._config.get_configuration(f"BaseServerSettings_{guild.id}") - if ((join.leaved_on - join.joined_on).total_seconds() / 60 / 60) > settings.max_voice_state_hours: + if ( + (join.leaved_on - join.joined_on).total_seconds() / 60 / 60 + ) > settings.max_voice_state_hours: join.leaved_on = join.joined_on + timedelta(hours=settings.max_voice_state_hours) self._user_joins_vc.update_user_joined_voice_channel(join) @@ -285,7 +309,7 @@ class DatabaseOnReadyEvent(OnReadyABC): for member in guild.members: if member.bot: - self._logger.trace(__name__, f'User {member.id} is ignored, because its a bot') + self._logger.trace(__name__, f"User {member.id} is ignored, because its a bot") continue if member.voice is None: @@ -293,18 +317,18 @@ class DatabaseOnReadyEvent(OnReadyABC): user = self._users.find_user_by_discord_id_and_server_id(member.id, server.server_id) if user is None: - self._logger.fatal(__name__, f'User not found in database: {member.id}') + self._logger.fatal(__name__, f"User not found in database: {member.id}") join = UserJoinedVoiceChannel(user, member.voice.channel.id, datetime.now()) self._user_joins_vc.add_user_joined_voice_channel(join) self._db_context.save_changes() - self._logger.warn(__name__, f'VS {member.voice}') + self._logger.warn(__name__, f"VS {member.voice}") except Exception as e: - self._logger.error(__name__, f'Cannot get UserJoinedVoiceChannel', e) + self._logger.error(__name__, f"Cannot get UserJoinedVoiceChannel", e) async def on_ready(self): - self._logger.debug(__name__, f'Module {type(self)} started') + self._logger.debug(__name__, f"Module {type(self)} started") await self._seeder.seed() @@ -316,4 +340,4 @@ class DatabaseOnReadyEvent(OnReadyABC): self._check_user_joins_vc() self._validate_init_time() - self._logger.trace(__name__, f'Module {type(self)} stopped') + self._logger.trace(__name__, f"Module {type(self)} stopped") diff --git a/kdb-bot/src/modules/level/__init__.py b/kdb-bot/src/modules/level/__init__.py index c684c12d..3fef254a 100644 --- a/kdb-bot/src/modules/level/__init__.py +++ b/kdb-bot/src/modules/level/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'modules.level' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "modules.level" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple -# imports: +# imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/modules/level/command/__init__.py b/kdb-bot/src/modules/level/command/__init__.py index 35daaf7e..02a2c096 100644 --- a/kdb-bot/src/modules/level/command/__init__.py +++ b/kdb-bot/src/modules/level/command/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'modules.level.command' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "modules.level.command" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/modules/level/command/level_group.py b/kdb-bot/src/modules/level/command/level_group.py index 2e899c33..b508ead3 100644 --- a/kdb-bot/src/modules/level/command/level_group.py +++ b/kdb-bot/src/modules/level/command/level_group.py @@ -10,7 +10,7 @@ from discord import app_commands from discord.ext import commands from discord.ext.commands import Context -from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC +from bot_core.abc.client_utils_abc import ClientUtilsABC from bot_core.abc.message_service_abc import MessageServiceABC from bot_core.helper.command_checks import CommandChecks from bot_core.logging.command_logger import CommandLogger @@ -24,21 +24,20 @@ from modules.permission.abc.permission_service_abc import PermissionServiceABC class LevelGroup(DiscordCommandABC): - def __init__( - self, - logger: CommandLogger, - message_service: MessageServiceABC, - bot: DiscordBotServiceABC, - client_utils: ClientUtilsServiceABC, - permission_service: PermissionServiceABC, - translate: TranslatePipe, - db: DatabaseContextABC, - levels: LevelRepositoryABC, - servers: ServerRepositoryABC, - users: UserRepositoryABC, - level_service: LevelService, - level_seeder: LevelSeeder, + self, + logger: CommandLogger, + message_service: MessageServiceABC, + bot: DiscordBotServiceABC, + client_utils: ClientUtilsABC, + permission_service: PermissionServiceABC, + translate: TranslatePipe, + db: DatabaseContextABC, + levels: LevelRepositoryABC, + servers: ServerRepositoryABC, + users: UserRepositoryABC, + level_service: LevelService, + level_seeder: LevelSeeder, ): DiscordCommandABC.__init__(self) @@ -57,58 +56,75 @@ class LevelGroup(DiscordCommandABC): self._level_seeder = level_seeder self._colors = [ - ('blue', discord.Colour.blue().to_rgb()), - ('dark_blue', discord.Colour.dark_blue().to_rgb()), - ('dark_gold', discord.Colour.dark_gold().to_rgb()), - ('dark_gray', discord.Colour.dark_gray().to_rgb()), - ('dark_green', discord.Colour.dark_green().to_rgb()), - ('dark_grey', discord.Colour.dark_grey().to_rgb()), - ('dark_magenta', discord.Colour.dark_magenta().to_rgb()), - ('dark_orange', discord.Colour.dark_orange().to_rgb()), - ('dark_purple', discord.Colour.dark_purple().to_rgb()), - ('dark_red', discord.Colour.dark_red().to_rgb()), - ('dark_teal', discord.Colour.dark_teal().to_rgb()), - ('default', discord.Colour.default().to_rgb()), - ('gold', discord.Colour.gold().to_rgb()), - ('green', discord.Colour.green().to_rgb()), - ('greyple', discord.Colour.greyple().to_rgb()), - ('light_grey', discord.Colour.light_grey().to_rgb()), - ('magenta', discord.Colour.magenta().to_rgb()), - ('orange', discord.Colour.orange().to_rgb()), - ('purple', discord.Colour.purple().to_rgb()), - ('red', discord.Colour.red().to_rgb()), - ('teal', discord.Colour.teal().to_rgb()), - ('yellow', discord.Colour.yellow().to_rgb()) + ("blue", discord.Colour.blue().to_rgb()), + ("dark_blue", discord.Colour.dark_blue().to_rgb()), + ("dark_gold", discord.Colour.dark_gold().to_rgb()), + ("dark_gray", discord.Colour.dark_gray().to_rgb()), + ("dark_green", discord.Colour.dark_green().to_rgb()), + ("dark_grey", discord.Colour.dark_grey().to_rgb()), + ("dark_magenta", discord.Colour.dark_magenta().to_rgb()), + ("dark_orange", discord.Colour.dark_orange().to_rgb()), + ("dark_purple", discord.Colour.dark_purple().to_rgb()), + ("dark_red", discord.Colour.dark_red().to_rgb()), + ("dark_teal", discord.Colour.dark_teal().to_rgb()), + ("default", discord.Colour.default().to_rgb()), + ("gold", discord.Colour.gold().to_rgb()), + ("green", discord.Colour.green().to_rgb()), + ("greyple", discord.Colour.greyple().to_rgb()), + ("light_grey", discord.Colour.light_grey().to_rgb()), + ("magenta", discord.Colour.magenta().to_rgb()), + ("orange", discord.Colour.orange().to_rgb()), + ("purple", discord.Colour.purple().to_rgb()), + ("red", discord.Colour.red().to_rgb()), + ("teal", discord.Colour.teal().to_rgb()), + ("yellow", discord.Colour.yellow().to_rgb()), ] - self._logger.trace(__name__, f'Loaded command service: {type(self).__name__}') + self._logger.trace(__name__, f"Loaded command service: {type(self).__name__}") - async def _seed_levels(self, channel: discord.TextChannel): + async def _seed_levels(self, ctx: Context): # send message to ctx.channel because send_ctx_msg resolves ctx try: - await self._message_service.send_channel_message(channel, self._t.transform('modules.level.seeding_started')) + start = await self._message_service.send_ctx_msg( + ctx, + self._t.transform("modules.level.seeding_started"), + is_persistent=True, + ) await self._level_seeder.seed() - await self._message_service.send_channel_message(channel, self._t.transform('modules.level.seeding_finished')) - except Exception as e: - self._logger.error(__name__, f'Level seeding failed', e) - await self._message_service.send_channel_message(channel, self._t.transform('modules.level.seeding_failed')) - async def _level_auto_complete(self, interaction: discord.Interaction, current: str) -> TList[app_commands.Choice[str]]: + end = await self._message_service.send_ctx_msg( + ctx, + self._t.transform("modules.level.seeding_finished"), + is_persistent=True, + ) + await self._message_service.delete_message(start) + await self._message_service.delete_message(end) + + except Exception as e: + self._logger.error(__name__, f"Level seeding failed", e) + await self._message_service.send_ctx_msg(ctx, self._t.transform("modules.level.seeding_failed")) + + async def _level_auto_complete( + self, interaction: discord.Interaction, current: str + ) -> TList[app_commands.Choice[str]]: server = self._servers.get_server_by_discord_id(interaction.guild.id) levels = self._levels.get_levels_by_server_id(server.server_id).select(lambda l: l.name) - return [app_commands.Choice(name=level, value=level) for level in self._client_utils.get_auto_complete_list(levels, current)] + return [ + app_commands.Choice(name=level, value=level) + for level in self._client_utils.get_auto_complete_list(levels, current) + ] @commands.hybrid_group() @commands.guild_only() async def level(self, ctx: Context): pass - @level.command(alias='levels') + @level.command(alias="levels") @commands.guild_only() @CommandChecks.check_is_ready() @CommandChecks.check_is_member_moderator() async def list(self, ctx: Context, wait: int = None): - self._logger.debug(__name__, f'Received command level list {ctx}') + self._logger.debug(__name__, f"Received command level list {ctx}") if ctx.guild is None: return @@ -116,46 +132,54 @@ class LevelGroup(DiscordCommandABC): server = self._servers.get_server_by_discord_id(ctx.guild.id) levels = self._levels.get_levels_by_server_id(server.server_id) if levels.count() < 1: - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.level.error.nothing_found')) - self._logger.trace(__name__, f'Finished command level list') + await self._message_service.send_ctx_msg(ctx, self._t.transform("modules.level.error.nothing_found")) + self._logger.trace(__name__, f"Finished command level list") return - level_name = '' - xp = '' - permissions = '' + level_name = "" + xp = "" + permissions = "" for level in levels: - level_name += f'\n{level.name}' - xp += f'\n{level.min_xp}' - permissions += f'\n{level.permissions}' + level_name += f"\n{level.name}" + xp += f"\n{level.min_xp}" + permissions += f"\n{level.permissions}" embed = discord.Embed( - title=self._t.transform('modules.level.list.title'), - description=self._t.transform('modules.level.list.description'), - color=int('ef9d0d', 16) + title=self._t.transform("modules.level.list.title"), + description=self._t.transform("modules.level.list.description"), + color=int("ef9d0d", 16), + ) + embed.add_field( + name=self._t.transform("modules.level.list.name"), + value=level_name, + inline=True, + ) + embed.add_field(name=self._t.transform("modules.level.list.min_xp"), value=xp, inline=True) + embed.add_field( + name=self._t.transform("modules.level.list.permission_int"), + value=permissions, + inline=True, ) - embed.add_field(name=self._t.transform('modules.level.list.name'), value=level_name, inline=True) - embed.add_field(name=self._t.transform('modules.level.list.min_xp'), value=xp, inline=True) - embed.add_field(name=self._t.transform('modules.level.list.permission_int'), value=permissions, inline=True) await self._message_service.send_ctx_msg(ctx, embed, wait_before_delete=wait) - self._logger.trace(__name__, f'Finished command level list') + self._logger.trace(__name__, f"Finished command level list") @level.command() @commands.guild_only() @CommandChecks.check_is_ready() @CommandChecks.check_is_member_admin() async def create(self, ctx: Context, name: str, color: str, min_xp: int, permissions: int): - self._logger.debug(__name__, f'Received command level create {ctx}') + self._logger.debug(__name__, f"Received command level create {ctx}") try: color = hex(discord.Colour.from_str(color).value) except Exception as e: - self._logger.error(__name__, f'Error parsing color {color}', e) + self._logger.error(__name__, f"Error parsing color {color}", e) return try: permissions = discord.Permissions(permissions).value except Exception as e: - self._logger.error(__name__, f'Error parsing permissions {permissions}', e) + self._logger.error(__name__, f"Error parsing permissions {permissions}", e) return if ctx.guild is None: @@ -166,42 +190,83 @@ class LevelGroup(DiscordCommandABC): levels = self._levels.get_levels_by_server_id(server.server_id) if levels.where(lambda l: l.name == level.name).first_or_default() is not None: - self._logger.debug(__name__, f'Level with name {level.name} already exists') - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.level.error.level_with_name_already_exists').format(level.name)) + self._logger.debug(__name__, f"Level with name {level.name} already exists") + await self._message_service.send_ctx_msg( + ctx, + self._t.transform("modules.level.error.level_with_name_already_exists").format(level.name), + ) elif levels.where(lambda l: l.min_xp == level.min_xp).first_or_default() is not None: - self._logger.debug(__name__, f'Level with min_xp {level.min_xp} already exists {level.name}') + self._logger.debug( + __name__, + f"Level with min_xp {level.min_xp} already exists {level.name}", + ) found_level = levels.where(lambda l: l.min_xp == level.min_xp).first_or_default() - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.level.error.level_with_xp_already_exists').format(found_level.name, found_level.min_xp)) + await self._message_service.send_ctx_msg( + ctx, + self._t.transform("modules.level.error.level_with_xp_already_exists").format( + found_level.name, found_level.min_xp + ), + ) else: try: self._levels.add_level(level) self._db.save_changes() - self._logger.info(__name__, f'Saved level {name} with color {color}, min_xp {min_xp} and permissions {permissions}') + self._logger.info( + __name__, + f"Saved level {name} with color {color}, min_xp {min_xp} and permissions {permissions}", + ) except Exception as e: - self._logger.error(__name__, f'Could not save level {name} with color {color}, min_xp {min_xp} and permissions {permissions}', e) + self._logger.error( + __name__, + f"Could not save level {name} with color {color}, min_xp {min_xp} and permissions {permissions}", + e, + ) else: - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.level.create.created').format(name, permissions)) - await self._seed_levels(ctx.channel) + await self._message_service.send_ctx_msg( + ctx, + self._t.transform("modules.level.create.created").format(name, permissions), + ) + await self._seed_levels(ctx) - self._logger.trace(__name__, f'Finished command level create') + self._logger.trace(__name__, f"Finished command level create") - @create.autocomplete('color') - async def create_color_autocomplete(self, interaction: discord.Interaction, current: str) -> TList[app_commands.Choice[str]]: + @create.autocomplete("color") + async def create_color_autocomplete( + self, interaction: discord.Interaction, current: str + ) -> TList[app_commands.Choice[str]]: # value in rg format see: # https://discordpy.readthedocs.io/en/latest/api.html#discord.Colour.to_rgb - return [app_commands.Choice(name=self._t.transform(f'common.colors.{color}'), value=f'rgb({code[0]}, {code[1]}, {code[2]})') for color, code in self._colors] + return [ + app_commands.Choice( + name=self._t.transform(f"common.colors.{color}"), + value=f"rgb({code[0]}, {code[1]}, {code[2]})", + ) + for color, code in self._colors + ] @level.command() @commands.guild_only() @CommandChecks.check_is_ready() @CommandChecks.check_is_member_admin() - async def edit(self, ctx: Context, level: str, name: str = None, color: str = None, min_xp: int = None, permissions: int = None): - self._logger.debug(__name__, f'Received command level edit {ctx}') + async def edit( + self, + ctx: Context, + level: str, + name: str = None, + color: str = None, + min_xp: int = None, + permissions: int = None, + ): + self._logger.debug(__name__, f"Received command level edit {ctx}") server = self._servers.get_server_by_discord_id(ctx.guild.id) - level_from_db = self._levels.get_levels_by_server_id(server.server_id).where(lambda l: l.name == level).single_or_default() + level_from_db = ( + self._levels.get_levels_by_server_id(server.server_id).where(lambda l: l.name == level).single_or_default() + ) if level_from_db is None: - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.level.edit.not_found').format(level)) + await self._message_service.send_ctx_msg( + ctx, self._t.transform("modules.level.edit.not_found").format(level) + ) return guild: Guild = self._bot.guilds.where(lambda g: g == ctx.guild).single() @@ -214,8 +279,11 @@ class LevelGroup(DiscordCommandABC): try: level_from_db.color = hex(discord.Colour.from_str(color).value) except Exception as e: - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.level.edit.color_invalid').format(color)) - self._logger.error(__name__, f'Error parsing color {color}', e) + await self._message_service.send_ctx_msg( + ctx, + self._t.transform("modules.level.edit.color_invalid").format(color), + ) + self._logger.error(__name__, f"Error parsing color {color}", e) return if min_xp is not None: @@ -225,47 +293,75 @@ class LevelGroup(DiscordCommandABC): try: level_from_db.permissions = discord.Permissions(permissions).value except Exception as e: - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.level.edit.permission_invalid').format(permissions)) - self._logger.error(__name__, f'Error parsing permissions {permissions}', e) + await self._message_service.send_ctx_msg( + ctx, + self._t.transform("modules.level.edit.permission_invalid").format(permissions), + ) + self._logger.error(__name__, f"Error parsing permissions {permissions}", e) return try: self._levels.update_level(level_from_db) self._db.save_changes() - await role.edit(name=level_from_db.name, permissions=discord.Permissions(level_from_db.permissions), colour=discord.Colour(int(level_from_db.color, 16))) - self._logger.info(__name__, - f'Saved level {level_from_db.name} with color {level_from_db.color}, min_xp {level_from_db.min_xp} and permissions {level_from_db.permissions}') + await role.edit( + name=level_from_db.name, + permissions=discord.Permissions(level_from_db.permissions), + colour=discord.Colour(int(level_from_db.color, 16)), + ) + self._logger.info( + __name__, + f"Saved level {level_from_db.name} with color {level_from_db.color}, min_xp {level_from_db.min_xp} and permissions {level_from_db.permissions}", + ) except Exception as e: - self._logger.error(__name__, f'Could not save level {level} with color {color}, min_xp {min_xp} and permissions {permissions}', e) + self._logger.error( + __name__, + f"Could not save level {level} with color {color}, min_xp {min_xp} and permissions {permissions}", + e, + ) else: - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.level.edit.edited').format(level)) - await self._seed_levels(ctx.channel) + await self._message_service.send_ctx_msg(ctx, self._t.transform("modules.level.edit.edited").format(level)) + await self._seed_levels(ctx) - self._logger.trace(__name__, f'Finished command level edit') + self._logger.trace(__name__, f"Finished command level edit") - @edit.autocomplete('level') - async def edit_autocomplete(self, interaction: discord.Interaction, current: str) -> TList[app_commands.Choice[str]]: + @edit.autocomplete("level") + async def edit_autocomplete( + self, interaction: discord.Interaction, current: str + ) -> TList[app_commands.Choice[str]]: return await self._level_auto_complete(interaction, current) - @edit.autocomplete('color') - async def edit_color_autocomplete(self, interaction: discord.Interaction, current: str) -> TList[app_commands.Choice[str]]: + @edit.autocomplete("color") + async def edit_color_autocomplete( + self, interaction: discord.Interaction, current: str + ) -> TList[app_commands.Choice[str]]: # value in rg format see: # https://discordpy.readthedocs.io/en/latest/api.html#discord.Colour.to_rgb - return [app_commands.Choice(name=self._t.transform(f'common.colors.{color}'), value=f'rgb({code[0]}, {code[1]}, {code[2]})') for color, code in self._colors] + return [ + app_commands.Choice( + name=self._t.transform(f"common.colors.{color}"), + value=f"rgb({code[0]}, {code[1]}, {code[2]})", + ) + for color, code in self._colors + ] @level.command() @commands.guild_only() @CommandChecks.check_is_ready() @CommandChecks.check_is_member_admin() async def remove(self, ctx: Context, level: str): - self._logger.debug(__name__, f'Received command level remove {ctx}') + self._logger.debug(__name__, f"Received command level remove {ctx}") server = self._servers.get_server_by_discord_id(ctx.guild.id) - level_from_db = self._levels.get_levels_by_server_id(server.server_id).where(lambda l: l.name == level).first_or_default() + level_from_db = ( + self._levels.get_levels_by_server_id(server.server_id).where(lambda l: l.name == level).first_or_default() + ) if level_from_db is None: - self._logger.debug(__name__, f'level {level} not found') - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.level.remove.error.not_found').format(level)) - self._logger.trace(__name__, f'Finished command level remove') + self._logger.debug(__name__, f"level {level} not found") + await self._message_service.send_ctx_msg( + ctx, + self._t.transform("modules.level.remove.error.not_found").format(level), + ) + self._logger.trace(__name__, f"Finished command level remove") return try: @@ -275,17 +371,21 @@ class LevelGroup(DiscordCommandABC): role: Role = guild.roles.where(lambda r: r.name == level).single_or_default() if role is not None: await role.delete() - self._logger.info(__name__, f'Removed level {level}') + self._logger.info(__name__, f"Removed level {level}") except Exception as e: - self._logger.error(__name__, f'Could not remove level {level}', e) + self._logger.error(__name__, f"Could not remove level {level}", e) else: - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.level.remove.success').format(level)) - await self._seed_levels(ctx.channel) + await self._message_service.send_ctx_msg( + ctx, self._t.transform("modules.level.remove.success").format(level) + ) + await self._seed_levels(ctx) - self._logger.trace(__name__, f'Finished command level remove') + self._logger.trace(__name__, f"Finished command level remove") - @remove.autocomplete('level') - async def remove_autocomplete(self, interaction: discord.Interaction, current: str) -> TList[app_commands.Choice[str]]: + @remove.autocomplete("level") + async def remove_autocomplete( + self, interaction: discord.Interaction, current: str + ) -> TList[app_commands.Choice[str]]: return await self._level_auto_complete(interaction, current) @level.command() @@ -293,7 +393,7 @@ class LevelGroup(DiscordCommandABC): @CommandChecks.check_is_ready() @CommandChecks.check_is_member_moderator() async def down(self, ctx: Context, member: discord.Member): - self._logger.debug(__name__, f'Received command level down {ctx} {member}') + self._logger.debug(__name__, f"Received command level down {ctx} {member}") if member.bot: return @@ -304,8 +404,11 @@ class LevelGroup(DiscordCommandABC): levels = self._levels.get_levels_by_server_id(server.server_id).order_by(lambda l: l.min_xp) if level == levels.first(): - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.level.down.already_first').format(member.mention)) - self._logger.trace(__name__, f'Finished command level down') + await self._message_service.send_ctx_msg( + ctx, + self._t.transform("modules.level.down.already_first").format(member.mention), + ) + self._logger.trace(__name__, f"Finished command level down") return try: @@ -313,20 +416,26 @@ class LevelGroup(DiscordCommandABC): user.xp = new_level.min_xp self._users.update_user(user) self._db.save_changes() - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.level.down.success').format(member.mention, new_level.name)) + await self._message_service.send_ctx_msg( + ctx, + self._t.transform("modules.level.down.success").format(member.mention, new_level.name), + ) await self._level_service.set_level(user) except Exception as e: - self._logger.error(__name__, f'Cannot level down {member.name} with level {level.name}', e) - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.level.down.failed').format(member.mention)) + self._logger.error(__name__, f"Cannot level down {member.name} with level {level.name}", e) + await self._message_service.send_ctx_msg( + ctx, + self._t.transform("modules.level.down.failed").format(member.mention), + ) - self._logger.trace(__name__, f'Finished command level down') + self._logger.trace(__name__, f"Finished command level down") @level.command() @commands.guild_only() @CommandChecks.check_is_ready() @CommandChecks.check_is_member_moderator() async def up(self, ctx: Context, member: discord.Member): - self._logger.debug(__name__, f'Received command level up {ctx} {member}') + self._logger.debug(__name__, f"Received command level up {ctx} {member}") if member.bot: return @@ -337,8 +446,11 @@ class LevelGroup(DiscordCommandABC): levels = self._levels.get_levels_by_server_id(server.server_id).order_by(lambda l: l.min_xp) if level.name == levels.last().name: - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.level.up.already_last').format(member.mention)) - self._logger.trace(__name__, f'Finished command level up') + await self._message_service.send_ctx_msg( + ctx, + self._t.transform("modules.level.up.already_last").format(member.mention), + ) + self._logger.trace(__name__, f"Finished command level up") return try: @@ -346,20 +458,25 @@ class LevelGroup(DiscordCommandABC): user.xp = new_level.min_xp self._users.update_user(user) self._db.save_changes() - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.level.up.success').format(member.mention, new_level.name)) + await self._message_service.send_ctx_msg( + ctx, + self._t.transform("modules.level.up.success").format(member.mention, new_level.name), + ) await self._level_service.set_level(user) except Exception as e: - self._logger.error(__name__, f'Cannot level up {member.name} with level {level.name}', e) - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.level.up.failed').format(member.mention)) + self._logger.error(__name__, f"Cannot level up {member.name} with level {level.name}", e) + await self._message_service.send_ctx_msg( + ctx, self._t.transform("modules.level.up.failed").format(member.mention) + ) - self._logger.trace(__name__, f'Finished command level up') + self._logger.trace(__name__, f"Finished command level up") @level.command() @commands.guild_only() @CommandChecks.check_is_ready() @CommandChecks.check_is_member_moderator() async def set(self, ctx: Context, member: discord.Member, level: str): - self._logger.debug(__name__, f'Received command level up {ctx} {member}') + self._logger.debug(__name__, f"Received command level up {ctx} {member}") if member.bot: return @@ -367,30 +484,52 @@ class LevelGroup(DiscordCommandABC): server = self._servers.get_server_by_discord_id(ctx.guild.id) user = self._users.get_user_by_discord_id_and_server_id(member.id, server.server_id) current_level = self._level_service.get_level(user) - new_level = self._levels.get_levels_by_server_id(server.server_id).where(lambda l: l.name == level).single_or_default() + new_level = ( + self._levels.get_levels_by_server_id(server.server_id).where(lambda l: l.name == level).single_or_default() + ) if new_level is None: - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.level.set.not_found').format(level)) - self._logger.trace(__name__, f'Finished command level set') + await self._message_service.send_ctx_msg( + ctx, self._t.transform("modules.level.set.not_found").format(level) + ) + self._logger.trace(__name__, f"Finished command level set") return if current_level.name == level: - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.level.set.already_level').format(member.mention, level)) - self._logger.trace(__name__, f'Finished command level set') + await self._message_service.send_ctx_msg( + ctx, + self._t.transform("modules.level.set.already_level").format(member.mention, level), + ) + self._logger.trace(__name__, f"Finished command level set") return try: user.xp = new_level.min_xp self._users.update_user(user) self._db.save_changes() - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.level.set.success').format(member.mention, new_level.name)) + await self._message_service.send_ctx_msg( + ctx, + self._t.transform("modules.level.set.success").format(member.mention, new_level.name), + ) await self._level_service.set_level(user) except Exception as e: - self._logger.error(__name__, f'Cannot set level {level} for {member.name}', e) - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.level.set.failed').format(member.mention)) + self._logger.error(__name__, f"Cannot set level {level} for {member.name}", e) + await self._message_service.send_ctx_msg( + ctx, + self._t.transform("modules.level.set.failed").format(member.mention), + ) - self._logger.trace(__name__, f'Finished command level set') + self._logger.trace(__name__, f"Finished command level set") - @set.autocomplete('level') + @set.autocomplete("level") async def set_autocomplete(self, interaction: discord.Interaction, current: str) -> TList[app_commands.Choice[str]]: return await self._level_auto_complete(interaction, current) + + @level.command() + @commands.guild_only() + @CommandChecks.check_is_ready() + @CommandChecks.check_is_member_moderator() + async def reload(self, ctx: Context): + self._logger.debug(__name__, f"Received command level reload {ctx}") + await self._seed_levels(ctx) + self._logger.trace(__name__, f"Finished command level reload") diff --git a/kdb-bot/src/modules/level/configuration/__init__.py b/kdb-bot/src/modules/level/configuration/__init__.py index 40e63c11..0891b568 100644 --- a/kdb-bot/src/modules/level/configuration/__init__.py +++ b/kdb-bot/src/modules/level/configuration/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'modules.level.configuration' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "modules.level.configuration" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/modules/level/configuration/default_level_settings.py b/kdb-bot/src/modules/level/configuration/default_level_settings.py index 3687ab83..fcce9e47 100644 --- a/kdb-bot/src/modules/level/configuration/default_level_settings.py +++ b/kdb-bot/src/modules/level/configuration/default_level_settings.py @@ -8,12 +8,11 @@ from bot_data.model.level import Level class DefaultLevelSettings(ConfigurationModelABC): - def __init__(self): ConfigurationModelABC.__init__(self) self._levels = List(Level) - self._level_header = '' + self._level_header = "" @property def levels(self) -> List[Level]: @@ -25,15 +24,17 @@ class DefaultLevelSettings(ConfigurationModelABC): def from_dict(self, settings: dict): try: - self._level_header = settings['LevelHeader'] - for level in settings['Levels']: - self._levels.append(Level( - level['Name'], - level['Color'], - int(level['MinXp']), - int(level['Permissions']), - None - )) + self._level_header = settings["LevelHeader"] + for level in settings["Levels"]: + self._levels.append( + Level( + level["Name"], + level["Color"], + int(level["MinXp"]), + int(level["Permissions"]), + None, + ) + ) except Exception as e: - Console.error(f'[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings') - Console.error(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}') + Console.error(f"[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings") + Console.error(f"[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}") diff --git a/kdb-bot/src/modules/level/configuration/level_server_settings.py b/kdb-bot/src/modules/level/configuration/level_server_settings.py index 85985cff..f6dce290 100644 --- a/kdb-bot/src/modules/level/configuration/level_server_settings.py +++ b/kdb-bot/src/modules/level/configuration/level_server_settings.py @@ -5,7 +5,6 @@ from cpl_core.console import Console class LevelServerSettings(ConfigurationModelABC): - def __init__(self): ConfigurationModelABC.__init__(self) @@ -22,8 +21,8 @@ class LevelServerSettings(ConfigurationModelABC): def from_dict(self, settings: dict): try: - self._id = int(settings['Id']) - self._changed_level_notification_channel = int(settings['ChangedLevelNotificationChannelId']) + self._id = int(settings["Id"]) + self._changed_level_notification_channel = int(settings["ChangedLevelNotificationChannelId"]) except Exception as e: - Console.error(f'[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings') - Console.error(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}') + Console.error(f"[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings") + Console.error(f"[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}") diff --git a/kdb-bot/src/modules/level/configuration/level_settings.py b/kdb-bot/src/modules/level/configuration/level_settings.py index 7962941c..7dd7db42 100644 --- a/kdb-bot/src/modules/level/configuration/level_settings.py +++ b/kdb-bot/src/modules/level/configuration/level_settings.py @@ -8,7 +8,6 @@ from modules.level.configuration.level_server_settings import LevelServerSetting class LevelSettings(ConfigurationModelABC): - def __init__(self): ConfigurationModelABC.__init__(self) @@ -23,10 +22,10 @@ class LevelSettings(ConfigurationModelABC): servers = List(LevelServerSettings) for s in settings: st = LevelServerSettings() - settings[s]['Id'] = s + settings[s]["Id"] = s st.from_dict(settings[s]) servers.append(st) self._servers = servers except Exception as e: - Console.error(f'[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings') - Console.error(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}') + Console.error(f"[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings") + Console.error(f"[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}") diff --git a/kdb-bot/src/modules/level/events/__init__.py b/kdb-bot/src/modules/level/events/__init__.py index 7ff8646b..71554fc3 100644 --- a/kdb-bot/src/modules/level/events/__init__.py +++ b/kdb-bot/src/modules/level/events/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'modules.level.events' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "modules.level.events" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/modules/level/events/level_on_member_join_event.py b/kdb-bot/src/modules/level/events/level_on_member_join_event.py index c8ce80cc..26a9dccb 100644 --- a/kdb-bot/src/modules/level/events/level_on_member_join_event.py +++ b/kdb-bot/src/modules/level/events/level_on_member_join_event.py @@ -7,17 +7,12 @@ from modules.level.service.level_service import LevelService class LevelOnMemberJoinEvent(OnMemberJoinABC): - - def __init__( - self, - logger: MessageLogger, - level: LevelService - ): + def __init__(self, logger: MessageLogger, level: LevelService): OnMemberJoinABC.__init__(self) self._logger = logger self._level = level @EventChecks.check_is_ready() async def on_member_join(self, member: discord.Member): - self._logger.debug(__name__, f'Module {type(self)} started') + self._logger.debug(__name__, f"Module {type(self)} started") await self._level.check_level(member) diff --git a/kdb-bot/src/modules/level/events/level_on_message_event.py b/kdb-bot/src/modules/level/events/level_on_message_event.py index 293fb08f..104080ff 100644 --- a/kdb-bot/src/modules/level/events/level_on_message_event.py +++ b/kdb-bot/src/modules/level/events/level_on_message_event.py @@ -7,17 +7,12 @@ from modules.level.service.level_service import LevelService class LevelOnMessageEvent(OnMessageABC): - - def __init__( - self, - logger: MessageLogger, - level: LevelService - ): + def __init__(self, logger: MessageLogger, level: LevelService): OnMessageABC.__init__(self) self._logger = logger self._level = level @EventChecks.check_is_ready() async def on_message(self, message: discord.Message): - self._logger.debug(__name__, f'Module {type(self)} started') + self._logger.debug(__name__, f"Module {type(self)} started") await self._level.check_level(message.author) diff --git a/kdb-bot/src/modules/level/events/level_on_voice_state_update_event.py b/kdb-bot/src/modules/level/events/level_on_voice_state_update_event.py index 910e570a..d5c51f95 100644 --- a/kdb-bot/src/modules/level/events/level_on_voice_state_update_event.py +++ b/kdb-bot/src/modules/level/events/level_on_voice_state_update_event.py @@ -7,19 +7,19 @@ from modules.level.service.level_service import LevelService class LevelOnVoiceStateUpdateEvent(OnVoiceStateUpdateABC): - - def __init__( - self, - logger: LoggerABC, - level: LevelService - ): + def __init__(self, logger: LoggerABC, level: LevelService): OnVoiceStateUpdateABC.__init__(self) self._logger = logger self._level = level - self._logger.info(__name__, f'Module {type(self)} loaded') + self._logger.info(__name__, f"Module {type(self)} loaded") @EventChecks.check_is_ready() - async def on_voice_state_update(self, member: discord.Member, before: discord.VoiceState, after: discord.VoiceState): - self._logger.debug(__name__, f'Module {type(self)} started') + async def on_voice_state_update( + self, + member: discord.Member, + before: discord.VoiceState, + after: discord.VoiceState, + ): + self._logger.debug(__name__, f"Module {type(self)} started") await self._level.check_level(member) diff --git a/kdb-bot/src/modules/level/level.json b/kdb-bot/src/modules/level/level.json index 612f6acc..6a9137dc 100644 --- a/kdb-bot/src/modules/level/level.json +++ b/kdb-bot/src/modules/level/level.json @@ -4,7 +4,7 @@ "Version": { "Major": "0", "Minor": "3", - "Micro": "0" + "Micro": "1" }, "Author": "", "AuthorEmail": "", diff --git a/kdb-bot/src/modules/level/level_module.py b/kdb-bot/src/modules/level/level_module.py index 3502abad..1e2295a9 100644 --- a/kdb-bot/src/modules/level/level_module.py +++ b/kdb-bot/src/modules/level/level_module.py @@ -11,20 +11,21 @@ from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum from modules.level.command.level_group import LevelGroup from modules.level.events.level_on_member_join_event import LevelOnMemberJoinEvent from modules.level.events.level_on_message_event import LevelOnMessageEvent -from modules.level.events.level_on_voice_state_update_event import LevelOnVoiceStateUpdateEvent +from modules.level.events.level_on_voice_state_update_event import ( + LevelOnVoiceStateUpdateEvent, +) from modules.level.level_seeder import LevelSeeder from modules.level.service.level_service import LevelService class LevelModule(ModuleABC): - def __init__(self, dc: DiscordCollectionABC): ModuleABC.__init__(self, dc, FeatureFlagsEnum.level_module) def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC): cwd = env.working_directory env.set_working_directory(os.path.dirname(os.path.realpath(__file__))) - config.add_json_file(f'default-level.json', optional=False) + config.add_json_file(f"default-level.json", optional=False) env.set_working_directory(cwd) def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC): @@ -36,5 +37,8 @@ class LevelModule(ModuleABC): # events self._dc.add_event(DiscordEventTypesEnum.on_message.value, LevelOnMessageEvent) - self._dc.add_event(DiscordEventTypesEnum.on_voice_state_update.value, LevelOnVoiceStateUpdateEvent) + self._dc.add_event( + DiscordEventTypesEnum.on_voice_state_update.value, + LevelOnVoiceStateUpdateEvent, + ) self._dc.add_event(DiscordEventTypesEnum.on_member_join.value, LevelOnMemberJoinEvent) diff --git a/kdb-bot/src/modules/level/level_seeder.py b/kdb-bot/src/modules/level/level_seeder.py index 7dcd6118..7a51e2df 100644 --- a/kdb-bot/src/modules/level/level_seeder.py +++ b/kdb-bot/src/modules/level/level_seeder.py @@ -14,15 +14,14 @@ from modules.level.service.level_service import LevelService class LevelSeeder(DataSeederABC): - def __init__( - self, - logger: DatabaseLogger, - levels: DefaultLevelSettings, - level_repo: LevelRepositoryService, - servers: ServerRepositoryABC, - level: LevelService, - bot: DiscordBotServiceABC + self, + logger: DatabaseLogger, + levels: DefaultLevelSettings, + level_repo: LevelRepositoryService, + servers: ServerRepositoryABC, + level: LevelService, + bot: DiscordBotServiceABC, ): DataSeederABC.__init__(self) @@ -39,19 +38,25 @@ class LevelSeeder(DataSeederABC): level.server = server try: if guild.roles.where(lambda r: r.name == level.name).first_or_default() is None: - await guild.create_role(name=level.name, colour=Colour(int(level.color, 16)), hoist=False, mentionable=True, permissions=Permissions(level.permissions)) - self._logger.debug(__name__, f'Created role {level.name}') + await guild.create_role( + name=level.name, + colour=Colour(int(level.color, 16)), + hoist=False, + mentionable=True, + permissions=Permissions(level.permissions), + ) + self._logger.debug(__name__, f"Created role {level.name}") levels = self._levels.find_levels_by_server_id(server.server_id) if levels is None or levels.where(lambda l: l.name == level.name).first_or_default() is None: self._levels.add_level(level) - self._logger.debug(__name__, f'Saved level {level.name}') + self._logger.debug(__name__, f"Saved level {level.name}") except discord.errors.Forbidden as e: - self._logger.error(__name__, f'Creating level failed', e) + self._logger.error(__name__, f"Creating level failed", e) level.permissions = 0 self._levels.update_level(level) except Exception as e: - self._logger.error(__name__, f'Creating level failed', e) + self._logger.error(__name__, f"Creating level failed", e) async def seed(self): # create levels @@ -70,14 +75,14 @@ class LevelSeeder(DataSeederABC): for level in levels: await self._create_level(level, guild, server) - self._logger.debug(__name__, f'Seeded levels') + self._logger.debug(__name__, f"Seeded levels") else: # create default levels for level in self._default_levels: created_default = True await self._create_level(level, guild, server) - self._logger.debug(__name__, f'Seeded default levels') + self._logger.debug(__name__, f"Seeded default levels") if created_default: continue @@ -88,16 +93,21 @@ class LevelSeeder(DataSeederABC): if levels.where(lambda l: l.name == role.name).count() == 0: continue - new_position = position_above_levels - (levels.index_of(levels.where(lambda l: l.name == role.name).single()) + 1) + new_position = position_above_levels - ( + levels.index_of(levels.where(lambda l: l.name == role.name).single()) + 1 + ) if new_position <= 0: new_position = 1 try: - self._logger.debug(__name__, f'Moved {role.name} from {role.position} to {new_position}') + self._logger.debug( + __name__, + f"Moved {role.name} from {role.position} to {new_position}", + ) await role.edit(position=new_position) except Exception as e: - self._logger.error(__name__, f'Cannot change position of {role.name}', e) + self._logger.error(__name__, f"Cannot change position of {role.name}", e) for m in guild.members: await self._level.check_level(m) - self._logger.debug(__name__, f'Checked role order') + self._logger.debug(__name__, f"Checked role order") diff --git a/kdb-bot/src/modules/level/service/__init__.py b/kdb-bot/src/modules/level/service/__init__.py index fbe27314..b8b6ca28 100644 --- a/kdb-bot/src/modules/level/service/__init__.py +++ b/kdb-bot/src/modules/level/service/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'modules.level.service' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "modules.level.service" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/modules/level/service/level_service.py b/kdb-bot/src/modules/level/service/level_service.py index e49d6f31..192a7dde 100644 --- a/kdb-bot/src/modules/level/service/level_service.py +++ b/kdb-bot/src/modules/level/service/level_service.py @@ -18,18 +18,17 @@ from modules.level.configuration.level_server_settings import LevelServerSetting class LevelService: - def __init__( - self, - config: ConfigurationABC, - logger: LoggerABC, - db: DatabaseContextABC, - levels: LevelRepositoryService, - users: UserRepositoryService, - servers: ServerRepositoryService, - bot: DiscordBotServiceABC, - message_service: MessageService, - t: TranslatePipe + self, + config: ConfigurationABC, + logger: LoggerABC, + db: DatabaseContextABC, + levels: LevelRepositoryService, + users: UserRepositoryService, + servers: ServerRepositoryService, + bot: DiscordBotServiceABC, + message_service: MessageService, + t: TranslatePipe, ): self._config = config self._logger = logger @@ -42,8 +41,13 @@ class LevelService: self._t = t def get_level(self, user: User) -> Level: - levels = self._levels.get_levels_by_server_id(user.server.server_id).order_by(lambda l: l.min_xp) - return levels.where(lambda l: user.xp >= l.min_xp).last() + levels_by_server = self._levels.get_levels_by_server_id(user.server.server_id) + levels = levels_by_server.order_by(lambda l: l.min_xp).where(lambda l: user.xp >= l.min_xp) + + if levels.count() == 0: + return levels_by_server.order_by(lambda l: l.min_xp).last() + + return levels.last() async def set_level(self, user: User): level_names = self._levels.get_levels_by_server_id(user.server.server_id).select(lambda l: l.name) @@ -60,24 +64,24 @@ class LevelService: continue try: - self._logger.debug(__name__, f'Try to remove role {role.name} from {member.name}') + self._logger.debug(__name__, f"Try to remove role {role.name} from {member.name}") await member.remove_roles(role) - self._logger.info(__name__, f'Removed role {role.name} from {member.name}') + self._logger.info(__name__, f"Removed role {role.name} from {member.name}") except Exception as e: - self._logger.error(__name__, f'Removing role {role.name} from {member.name} failed!', e) + self._logger.error(__name__, f"Removing role {role.name} from {member.name} failed!", e) try: - self._logger.debug(__name__, f'Try to add role {level_role.name} to {member.name}') + self._logger.debug(__name__, f"Try to add role {level_role.name} to {member.name}") await member.add_roles(level_role) - self._logger.info(__name__, f'Add role {level_role.name} to {member.name}') + self._logger.info(__name__, f"Add role {level_role.name} to {member.name}") except Exception as e: - self._logger.error(__name__, f'Adding role {level_role.name} to {member.name} failed!', e) + self._logger.error(__name__, f"Adding role {level_role.name} to {member.name} failed!", e) - level_settings: LevelServerSettings = self._config.get_configuration(f'LevelServerSettings_{guild.id}') + level_settings: LevelServerSettings = self._config.get_configuration(f"LevelServerSettings_{guild.id}") await self._message_service.send_channel_message( self._bot.get_channel(level_settings.changed_level_notification_channel), - self._t.transform('modules.level.new_level_message').format(member.mention, level.name), - is_persistent=True + self._t.transform("modules.level.new_level_message").format(member.mention, level.name), + is_persistent=True, ) async def check_level(self, member: discord.Member): @@ -87,7 +91,7 @@ class LevelService: server = self._servers.get_server_by_discord_id(member.guild.id) user = self._users.find_user_by_discord_id_and_server_id(member.id, server.server_id) if user is None: - self._logger.warn(__name__, f'User not found {member.guild.name}@{member.name}') + self._logger.warn(__name__, f"User not found {member.guild.name}@{member.name}") return await self.set_level(user) diff --git a/kdb-bot/src/modules/permission/__init__.py b/kdb-bot/src/modules/permission/__init__.py index f14bcd24..dfc4fab3 100644 --- a/kdb-bot/src/modules/permission/__init__.py +++ b/kdb-bot/src/modules/permission/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'modules.permission' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "modules.permission" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple -# imports: +# imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/modules/permission/abc/__init__.py b/kdb-bot/src/modules/permission/abc/__init__.py index 220dde0d..2d83e842 100644 --- a/kdb-bot/src/modules/permission/abc/__init__.py +++ b/kdb-bot/src/modules/permission/abc/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'modules.permission.abc' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "modules.permission.abc" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/modules/permission/abc/permission_service_abc.py b/kdb-bot/src/modules/permission/abc/permission_service_abc.py index b2323742..2409088c 100644 --- a/kdb-bot/src/modules/permission/abc/permission_service_abc.py +++ b/kdb-bot/src/modules/permission/abc/permission_service_abc.py @@ -4,42 +4,54 @@ import discord class PermissionServiceABC(ABC): + @abstractmethod + def __init__(self): + pass @abstractmethod - def __init__(self): pass + def on_ready(self): + pass @abstractmethod - def on_ready(self): pass + def on_member_update(self, before: discord.Member, after: discord.Member): + pass @abstractmethod - def on_member_update(self, before: discord.Member, after: discord.Member): pass + def get_admin_role_ids(self, g_id: int) -> list[int]: + pass @abstractmethod - def get_admin_role_ids(self, g_id: int) -> list[int]: pass + def get_admin_roles(self, g_id: int) -> list[discord.Role]: + pass @abstractmethod - def get_admin_roles(self, g_id: int) -> list[discord.Role]: pass + def get_admins(self, g_id: int) -> list[discord.Member]: + pass @abstractmethod - def get_admins(self, g_id: int) -> list[discord.Member]: pass + def get_moderator_role_ids(self, g_id: int) -> list[int]: + pass @abstractmethod - def get_moderator_role_ids(self, g_id: int) -> list[int]: pass + def get_moderator_roles(self, g_id: int) -> list[discord.Role]: + pass @abstractmethod - def get_moderator_roles(self, g_id: int) -> list[discord.Role]: pass + def get_moderators(self, g_id: int) -> list[discord.Member]: + pass @abstractmethod - def get_moderators(self, g_id: int) -> list[discord.Member]: pass + def get_technicians(self) -> list[discord.Member]: + pass @abstractmethod - def get_technicians(self) -> list[discord.Member]: pass + def is_member_admin(self, member: discord.Member) -> bool: + pass @abstractmethod - def is_member_admin(self, member: discord.Member) -> bool: pass + def is_member_moderator(self, member: discord.Member) -> bool: + pass @abstractmethod - def is_member_moderator(self, member: discord.Member) -> bool: pass - - @abstractmethod - def is_member_technician(self, member: discord.Member) -> bool: pass + def is_member_technician(self, member: discord.Member) -> bool: + pass diff --git a/kdb-bot/src/modules/permission/configuration/__init__.py b/kdb-bot/src/modules/permission/configuration/__init__.py index 1de58813..d88644c7 100644 --- a/kdb-bot/src/modules/permission/configuration/__init__.py +++ b/kdb-bot/src/modules/permission/configuration/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'modules.permission.configuration' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "modules.permission.configuration" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/modules/permission/configuration/permission_server_settings.py b/kdb-bot/src/modules/permission/configuration/permission_server_settings.py index f45762c8..1ffdfdf7 100644 --- a/kdb-bot/src/modules/permission/configuration/permission_server_settings.py +++ b/kdb-bot/src/modules/permission/configuration/permission_server_settings.py @@ -5,7 +5,6 @@ from cpl_core.console import Console class PermissionServerSettings(ConfigurationModelABC): - def __init__(self): ConfigurationModelABC.__init__(self) @@ -27,12 +26,12 @@ class PermissionServerSettings(ConfigurationModelABC): def from_dict(self, settings: dict): try: - self._id = int(settings['Id']) - for index in settings['AdminRoleIds']: + self._id = int(settings["Id"]) + for index in settings["AdminRoleIds"]: self._admin_roles.append(int(index)) - - for index in settings['ModeratorRoleIds']: + + for index in settings["ModeratorRoleIds"]: self._moderator_roles.append(int(index)) except Exception as e: - Console.error(f'[ ERROR ] [ {__name__} ]: Reading error in {self.__name__} settings') - Console.error(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}') + Console.error(f"[ ERROR ] [ {__name__} ]: Reading error in {self.__name__} settings") + Console.error(f"[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}") diff --git a/kdb-bot/src/modules/permission/configuration/permission_settings.py b/kdb-bot/src/modules/permission/configuration/permission_settings.py index 408d5087..532c592a 100644 --- a/kdb-bot/src/modules/permission/configuration/permission_settings.py +++ b/kdb-bot/src/modules/permission/configuration/permission_settings.py @@ -4,11 +4,12 @@ from cpl_core.configuration.configuration_model_abc import ConfigurationModelABC from cpl_core.console import Console from cpl_query.extension import List -from modules.permission.configuration.permission_server_settings import PermissionServerSettings +from modules.permission.configuration.permission_server_settings import ( + PermissionServerSettings, +) class PermissionSettings(ConfigurationModelABC): - def __init__(self): ConfigurationModelABC.__init__(self) @@ -23,10 +24,10 @@ class PermissionSettings(ConfigurationModelABC): servers = List(PermissionServerSettings) for s in settings: st = PermissionServerSettings() - settings[s]['Id'] = s + settings[s]["Id"] = s st.from_dict(settings[s]) servers.append(st) self._servers = servers except Exception as e: - Console.error(f'[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings') - Console.error(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}') + Console.error(f"[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings") + Console.error(f"[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}") diff --git a/kdb-bot/src/modules/permission/events/__init__.py b/kdb-bot/src/modules/permission/events/__init__.py index 117b3b8b..988712ce 100644 --- a/kdb-bot/src/modules/permission/events/__init__.py +++ b/kdb-bot/src/modules/permission/events/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'modules.permission.events' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "modules.permission.events" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/modules/permission/events/permission_on_member_update_event.py b/kdb-bot/src/modules/permission/events/permission_on_member_update_event.py index 91e7c389..30d567ee 100644 --- a/kdb-bot/src/modules/permission/events/permission_on_member_update_event.py +++ b/kdb-bot/src/modules/permission/events/permission_on_member_update_event.py @@ -6,14 +6,13 @@ from modules.permission.abc.permission_service_abc import PermissionServiceABC class PermissionOnMemberUpdateEvent(OnMemberUpdateABC): - def __init__(self, logger: LoggerABC, permission_service: PermissionServiceABC): OnMemberUpdateABC.__init__(self) self._logger = logger self._permission_service = permission_service async def on_member_update(self, before: discord.Member, after: discord.Member): - self._logger.debug(__name__, f'Module {type(self)} started') + self._logger.debug(__name__, f"Module {type(self)} started") if before.roles != after.roles: self._permission_service.on_member_update(before, after) diff --git a/kdb-bot/src/modules/permission/events/permission_on_ready_event.py b/kdb-bot/src/modules/permission/events/permission_on_ready_event.py index 8a9febd5..4da13dc0 100644 --- a/kdb-bot/src/modules/permission/events/permission_on_ready_event.py +++ b/kdb-bot/src/modules/permission/events/permission_on_ready_event.py @@ -5,12 +5,11 @@ from modules.permission.abc.permission_service_abc import PermissionServiceABC class PermissionOnReadyEvent(OnReadyABC): - def __init__(self, logger: LoggerABC, permission_service: PermissionServiceABC): OnReadyABC.__init__(self) self._logger = logger self._permission_service = permission_service async def on_ready(self): - self._logger.debug(__name__, f'Module {type(self)} started') + self._logger.debug(__name__, f"Module {type(self)} started") self._permission_service.on_ready() diff --git a/kdb-bot/src/modules/permission/permission.json b/kdb-bot/src/modules/permission/permission.json index 02a65716..15ddb76d 100644 --- a/kdb-bot/src/modules/permission/permission.json +++ b/kdb-bot/src/modules/permission/permission.json @@ -4,7 +4,7 @@ "Version": { "Major": "0", "Minor": "3", - "Micro": "0" + "Micro": "1" }, "Author": "", "AuthorEmail": "", diff --git a/kdb-bot/src/modules/permission/permission_module.py b/kdb-bot/src/modules/permission/permission_module.py index 63615b55..1cd2be8a 100644 --- a/kdb-bot/src/modules/permission/permission_module.py +++ b/kdb-bot/src/modules/permission/permission_module.py @@ -7,13 +7,14 @@ from cpl_discord.service.discord_collection_abc import DiscordCollectionABC from bot_core.abc.module_abc import ModuleABC from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum 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_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): - def __init__(self, dc: DiscordCollectionABC): ModuleABC.__init__(self, dc, FeatureFlagsEnum.permission_module) diff --git a/kdb-bot/src/modules/permission/service/__init__.py b/kdb-bot/src/modules/permission/service/__init__.py index 8d6d28f1..b139e331 100644 --- a/kdb-bot/src/modules/permission/service/__init__.py +++ b/kdb-bot/src/modules/permission/service/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'modules.permission.service' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "modules.permission.service" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/modules/permission/service/permission_service.py b/kdb-bot/src/modules/permission/service/permission_service.py index 825a9ea0..e793ebe1 100644 --- a/kdb-bot/src/modules/permission/service/permission_service.py +++ b/kdb-bot/src/modules/permission/service/permission_service.py @@ -5,17 +5,18 @@ from cpl_discord.service import DiscordBotServiceABC from bot_core.configuration.bot_settings import BotSettings from modules.permission.abc.permission_service_abc import PermissionServiceABC -from modules.permission.configuration.permission_server_settings import PermissionServerSettings +from modules.permission.configuration.permission_server_settings import ( + PermissionServerSettings, +) class PermissionService(PermissionServiceABC): - def __init__( - self, - logger: LoggerABC, - bot: DiscordBotServiceABC, - config: ConfigurationABC, - bot_settings: BotSettings + self, + logger: LoggerABC, + bot: DiscordBotServiceABC, + config: ConfigurationABC, + bot_settings: BotSettings, ): PermissionServiceABC.__init__(self) self._logger = logger @@ -36,7 +37,7 @@ class PermissionService(PermissionServiceABC): def on_ready(self): for guild in self._bot.guilds: guild: discord.Guild = guild - self._logger.debug(__name__, f'Validate permission settings') + self._logger.debug(__name__, f"Validate permission settings") for technician_id in self._technician_ids: technician = guild.get_member(technician_id) @@ -44,9 +45,9 @@ class PermissionService(PermissionServiceABC): continue self._technicians.append(technician) - settings: PermissionServerSettings = self._config.get_configuration(f'PermissionServerSettings_{guild.id}') + settings: PermissionServerSettings = self._config.get_configuration(f"PermissionServerSettings_{guild.id}") if settings is None: - self._logger.error(__name__, 'Permission settings not found') + self._logger.error(__name__, "Permission settings not found") return self._admin_role_ids[guild.id] = settings.admin_roles @@ -63,19 +64,19 @@ class PermissionService(PermissionServiceABC): if role.id in self._admin_role_ids[guild.id]: admin_roles.append(role) - self._logger.trace(__name__, f'Added admin role {role}') + self._logger.trace(__name__, f"Added admin role {role}") for member in role.members: admins.append(member) - self._logger.trace(__name__, f'Added admin {member}') + self._logger.trace(__name__, f"Added admin {member}") if role.id in self._moderator_role_ids[guild.id]: mod_roles.append(role) - self._logger.trace(__name__, f'Added moderator role {role}') + self._logger.trace(__name__, f"Added moderator role {role}") for member in role.members: mods.append(member) - self._logger.trace(__name__, f'Added moderator {member}') + self._logger.trace(__name__, f"Added moderator {member}") self._admin_roles[guild.id] = admin_roles self._admins[guild.id] = admins @@ -88,20 +89,20 @@ class PermissionService(PermissionServiceABC): for admin_role in self._admin_roles[g_id]: if admin_role in before.roles and admin_role not in after.roles: self._admins[g_id].remove(after) - self._logger.trace(__name__, f'Removed {after.id} from admins') + self._logger.trace(__name__, f"Removed {after.id} from admins") elif admin_role in after.roles and admin_role not in before.roles: self._admins[g_id].append(after) - self._logger.trace(__name__, f'Added {after.id} to admins') + self._logger.trace(__name__, f"Added {after.id} to admins") for moderator_role in self._moderator_roles[g_id]: if moderator_role in before.roles and moderator_role not in after.roles: self._moderators[g_id].remove(after) - self._logger.trace(__name__, f'Removed {after.id} from moderators') + self._logger.trace(__name__, f"Removed {after.id} from moderators") elif moderator_role in after.roles and moderator_role not in before.roles: self._moderators[g_id].append(after) - self._logger.trace(__name__, f'Added {after.id} to moderators') + self._logger.trace(__name__, f"Added {after.id} to moderators") def get_admin_role_ids(self, g_id: int) -> list[int]: return self._admin_role_ids[g_id] @@ -128,7 +129,11 @@ class PermissionService(PermissionServiceABC): return member.guild.id in self._admins and member in self._admins[member.guild.id] def is_member_moderator(self, member: discord.Member) -> bool: - return member.guild.id in self._moderators and member in self._moderators[member.guild.id] or self.is_member_admin(member) + return ( + member.guild.id in self._moderators + and member in self._moderators[member.guild.id] + or self.is_member_admin(member) + ) def is_member_technician(self, member: discord.Member) -> bool: return member in self._technicians diff --git a/kdb-bot/src/modules/stats/__init__.py b/kdb-bot/src/modules/stats/__init__.py index f59e31b5..0c26311e 100644 --- a/kdb-bot/src/modules/stats/__init__.py +++ b/kdb-bot/src/modules/stats/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'modules.stats' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "modules.stats" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple -# imports: +# imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/modules/stats/command/__init__.py b/kdb-bot/src/modules/stats/command/__init__.py index c027c2dc..f5346950 100644 --- a/kdb-bot/src/modules/stats/command/__init__.py +++ b/kdb-bot/src/modules/stats/command/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'modules.stats.command' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "modules.stats.command" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/modules/stats/command/stats_group.py b/kdb-bot/src/modules/stats/command/stats_group.py index b035e54a..7db65858 100644 --- a/kdb-bot/src/modules/stats/command/stats_group.py +++ b/kdb-bot/src/modules/stats/command/stats_group.py @@ -8,7 +8,7 @@ from discord import app_commands from discord.ext import commands from discord.ext.commands import Context -from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC +from bot_core.abc.client_utils_abc import ClientUtilsABC from bot_core.abc.message_service_abc import MessageServiceABC from bot_core.helper.command_checks import CommandChecks from bot_core.logging.command_logger import CommandLogger @@ -20,18 +20,17 @@ from modules.stats.ui.add_statistic_form import AddStatisticForm class StatsGroup(DiscordCommandABC): - def __init__( - self, - logger: CommandLogger, - message_service: MessageServiceABC, - client_utils: ClientUtilsServiceABC, - translate: TranslatePipe, - permission_service: PermissionServiceABC, - statistic: StatisticService, - servers: ServerRepositoryABC, - stats: StatisticRepositoryABC, - db: DatabaseContextABC, + self, + logger: CommandLogger, + message_service: MessageServiceABC, + client_utils: ClientUtilsABC, + translate: TranslatePipe, + permission_service: PermissionServiceABC, + statistic: StatisticService, + servers: ServerRepositoryABC, + stats: StatisticRepositoryABC, + db: DatabaseContextABC, ): DiscordCommandABC.__init__(self) @@ -55,41 +54,49 @@ class StatsGroup(DiscordCommandABC): @CommandChecks.check_is_ready() @CommandChecks.check_is_member_moderator() async def list(self, ctx: Context, wait: int = None): - self._logger.debug(__name__, f'Received command stats list {ctx}') + self._logger.debug(__name__, f"Received command stats list {ctx}") if ctx.guild is None: return embed = discord.Embed( - title=self._t.transform('modules.auto_role.list.title'), - description=self._t.transform('modules.auto_role.list.description'), - color=int('ef9d0d', 16) + title=self._t.transform("modules.auto_role.list.title"), + description=self._t.transform("modules.auto_role.list.description"), + color=int("ef9d0d", 16), ) server = self._servers.get_server_by_discord_id(ctx.guild.id) stats = self._stats.get_statistics_by_server_id(server.server_id) if stats.count() == 0: - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.stats.list.nothing_found')) + await self._message_service.send_ctx_msg(ctx, self._t.transform("modules.stats.list.nothing_found")) return - statistics = '' - descriptions = '' + statistics = "" + descriptions = "" for statistic in stats: - statistics += f'\n{statistic.name}' - descriptions += f'\n{statistic.description}' + statistics += f"\n{statistic.name}" + descriptions += f"\n{statistic.description}" - embed.add_field(name=self._t.transform('modules.stats.list.statistic'), value=statistics, inline=True) - embed.add_field(name=self._t.transform('modules.stats.list.description'), value=descriptions, inline=True) + embed.add_field( + name=self._t.transform("modules.stats.list.statistic"), + value=statistics, + inline=True, + ) + embed.add_field( + name=self._t.transform("modules.stats.list.description"), + value=descriptions, + inline=True, + ) await self._message_service.send_ctx_msg(ctx, embed, wait_before_delete=wait) - self._logger.trace(__name__, f'Finished command stats list') + self._logger.trace(__name__, f"Finished command stats list") @stats.command() @commands.guild_only() @CommandChecks.check_is_ready() @CommandChecks.check_is_member_moderator() async def view(self, ctx: Context, name: str, wait: int = None): - self._logger.debug(__name__, f'Received command stats view {ctx}:{name}') + self._logger.debug(__name__, f"Received command stats view {ctx}:{name}") if ctx.guild is None: return @@ -103,43 +110,56 @@ class StatsGroup(DiscordCommandABC): embed = discord.Embed( title=statistic.name, description=statistic.description, - color=int('ef9d0d', 16) + color=int("ef9d0d", 16), ) for i in range(result.header.count()): header = result.header[i] - value = '' + value = "" for row in result.values: - value += f'\n{row[i]}' + value += f"\n{row[i]}" embed.add_field(name=header, value=value, inline=True) await self._message_service.send_ctx_msg(ctx, embed, wait_before_delete=wait) except Exception as e: - self._logger.error(__name__, f'Cannot view statistic {name}', e) - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.stats.view.failed')) + self._logger.error(__name__, f"Cannot view statistic {name}", e) + await self._message_service.send_ctx_msg(ctx, self._t.transform("modules.stats.view.failed")) - self._logger.trace(__name__, f'Finished stats view command') + self._logger.trace(__name__, f"Finished stats view command") - @view.autocomplete('name') - async def view_autocomplete(self, interaction: discord.Interaction, current: str) -> TList[app_commands.Choice[str]]: + @view.autocomplete("name") + async def view_autocomplete( + self, interaction: discord.Interaction, current: str + ) -> TList[app_commands.Choice[str]]: server = self._servers.get_server_by_discord_id(interaction.guild.id) stats = self._stats.get_statistics_by_server_id(server.server_id) - return [app_commands.Choice(name=f'{statistic.name}: {statistic.description}', value=statistic.name) for statistic in stats] + return [ + app_commands.Choice(name=f"{statistic.name}: {statistic.description}", value=statistic.name) + for statistic in stats + ] @stats.command() @commands.guild_only() @CommandChecks.check_is_ready() @CommandChecks.check_is_member_technician() async def add(self, ctx: Context, name: str): - self._logger.debug(__name__, f'Received command stats add {ctx}: {name}') + self._logger.debug(__name__, f"Received command stats add {ctx}: {name}") if ctx.guild is None: return server = self._servers.get_server_by_discord_id(ctx.guild.id) - form = AddStatisticForm(server, self._stats, self._db, name, self._message_service, self._logger, self._t) - self._logger.trace(__name__, f'Finished stats add command') - self._logger.trace(__name__, f'Started stats command form') + form = AddStatisticForm( + server, + self._stats, + self._db, + name, + self._message_service, + self._logger, + self._t, + ) + self._logger.trace(__name__, f"Finished stats add command") + self._logger.trace(__name__, f"Started stats command form") await ctx.interaction.response.send_modal(form) @stats.command() @@ -147,46 +167,66 @@ class StatsGroup(DiscordCommandABC): @CommandChecks.check_is_ready() @CommandChecks.check_is_member_technician() async def edit(self, ctx: Context, name: str): - self._logger.debug(__name__, f'Received command stats edit {ctx}: {name}') + self._logger.debug(__name__, f"Received command stats edit {ctx}: {name}") try: server = self._servers.get_server_by_discord_id(ctx.guild.id) stats = self._stats.get_statistics_by_server_id(server.server_id) statistic = stats.where(lambda s: s.name == name).single() - form = AddStatisticForm(server, self._stats, self._db, name, self._message_service, self._logger, self._t, code=statistic.code, description=statistic.description) - self._logger.trace(__name__, f'Finished stats edit command') - self._logger.trace(__name__, f'Started stats command form') + form = AddStatisticForm( + server, + self._stats, + self._db, + name, + self._message_service, + self._logger, + self._t, + code=statistic.code, + description=statistic.description, + ) + self._logger.trace(__name__, f"Finished stats edit command") + self._logger.trace(__name__, f"Started stats command form") await ctx.interaction.response.send_modal(form) except Exception as e: - self._logger.error(__name__, f'Cannot edit statistic {name}', e) - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.stats.edit.failed')) + self._logger.error(__name__, f"Cannot edit statistic {name}", e) + await self._message_service.send_ctx_msg(ctx, self._t.transform("modules.stats.edit.failed")) - @edit.autocomplete('name') - async def edit_autocomplete(self, interaction: discord.Interaction, current: str) -> TList[app_commands.Choice[str]]: + @edit.autocomplete("name") + async def edit_autocomplete( + self, interaction: discord.Interaction, current: str + ) -> TList[app_commands.Choice[str]]: server = self._servers.get_server_by_discord_id(interaction.guild.id) stats = self._stats.get_statistics_by_server_id(server.server_id) - return [app_commands.Choice(name=f'{statistic.name}: {statistic.description}', value=statistic.name) for statistic in stats] + return [ + app_commands.Choice(name=f"{statistic.name}: {statistic.description}", value=statistic.name) + for statistic in stats + ] @stats.command() @commands.guild_only() @CommandChecks.check_is_ready() @CommandChecks.check_is_member_technician() async def remove(self, ctx: Context, name: str): - self._logger.debug(__name__, f'Received command stats remove {ctx}: {name}') + self._logger.debug(__name__, f"Received command stats remove {ctx}: {name}") try: server = self._servers.get_server_by_discord_id(ctx.guild.id) statistic = self._stats.get_statistic_by_name(name, server.server_id) self._stats.delete_statistic(statistic) self._db.save_changes() - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.stats.remove.success')) - self._logger.trace(__name__, f'Finished stats remove command') + await self._message_service.send_ctx_msg(ctx, self._t.transform("modules.stats.remove.success")) + self._logger.trace(__name__, f"Finished stats remove command") except Exception as e: - self._logger.error(__name__, f'Cannot remove statistic {name}', e) - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.stats.remove.failed')) + self._logger.error(__name__, f"Cannot remove statistic {name}", e) + await self._message_service.send_ctx_msg(ctx, self._t.transform("modules.stats.remove.failed")) - @remove.autocomplete('name') - async def edit_autocomplete(self, interaction: discord.Interaction, current: str) -> TList[app_commands.Choice[str]]: + @remove.autocomplete("name") + async def edit_autocomplete( + self, interaction: discord.Interaction, current: str + ) -> TList[app_commands.Choice[str]]: server = self._servers.get_server_by_discord_id(interaction.guild.id) stats = self._stats.get_statistics_by_server_id(server.server_id) - return [app_commands.Choice(name=f'{statistic.name}: {statistic.description}', value=statistic.name) for statistic in stats] + return [ + app_commands.Choice(name=f"{statistic.name}: {statistic.description}", value=statistic.name) + for statistic in stats + ] diff --git a/kdb-bot/src/modules/stats/model/__init__.py b/kdb-bot/src/modules/stats/model/__init__.py index 3bbb47aa..ce2d9618 100644 --- a/kdb-bot/src/modules/stats/model/__init__.py +++ b/kdb-bot/src/modules/stats/model/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'modules.stats.model' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "modules.stats.model" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/modules/stats/model/statistic_result.py b/kdb-bot/src/modules/stats/model/statistic_result.py index c2c53742..d8e62bf6 100644 --- a/kdb-bot/src/modules/stats/model/statistic_result.py +++ b/kdb-bot/src/modules/stats/model/statistic_result.py @@ -2,7 +2,6 @@ from cpl_query.extension import List class StatisticResult: - def __init__(self): self._header = List(str) self._values = List(List) diff --git a/kdb-bot/src/modules/stats/service/__init__.py b/kdb-bot/src/modules/stats/service/__init__.py index 2c2fc357..74fb38e5 100644 --- a/kdb-bot/src/modules/stats/service/__init__.py +++ b/kdb-bot/src/modules/stats/service/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'modules.stats.service' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "modules.stats.service" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/modules/stats/service/statistic_service.py b/kdb-bot/src/modules/stats/service/statistic_service.py index cee56335..8286c533 100644 --- a/kdb-bot/src/modules/stats/service/statistic_service.py +++ b/kdb-bot/src/modules/stats/service/statistic_service.py @@ -10,7 +10,9 @@ from bot_data.abc.known_user_repository_abc import KnownUserRepositoryABC from bot_data.abc.level_repository_abc import LevelRepositoryABC 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_joined_voice_channel_repository_abc import ( + UserJoinedVoiceChannelRepositoryABC, +) from bot_data.abc.user_repository_abc import UserRepositoryABC from bot_data.model.auto_role import AutoRole from bot_data.model.client import Client @@ -24,18 +26,17 @@ from modules.stats.model.statistic_result import StatisticResult class StatisticService: - def __init__( - self, - auto_roles: AutoRoleRepositoryABC, - clients: ClientRepositoryABC, - known_users: KnownUserRepositoryABC, - levels: LevelRepositoryABC, - servers: ServerRepositoryABC, - user_joined_servers: UserJoinedServerRepositoryABC, - user_joined_voice_channel: UserJoinedVoiceChannelRepositoryABC, - users: UserRepositoryABC, - bot: DiscordBotServiceABC, + self, + auto_roles: AutoRoleRepositoryABC, + clients: ClientRepositoryABC, + known_users: KnownUserRepositoryABC, + levels: LevelRepositoryABC, + servers: ServerRepositoryABC, + user_joined_servers: UserJoinedServerRepositoryABC, + user_joined_voice_channel: UserJoinedVoiceChannelRepositoryABC, + users: UserRepositoryABC, + bot: DiscordBotServiceABC, ): self._auto_roles = auto_roles self._clients = clients @@ -52,43 +53,33 @@ class StatisticService: return await self.get_data( code, - self._auto_roles - .get_auto_roles() - .where(lambda x: x.server.server_id == server.server_id), - self._clients - .get_clients() - .where(lambda x: x.server.server_id == server.server_id), + self._auto_roles.get_auto_roles().where(lambda x: x.server.server_id == server.server_id), + self._clients.get_clients().where(lambda x: x.server.server_id == server.server_id), self._known_users.get_users(), - self._levels - .get_levels() - .where(lambda x: x.server.server_id == server.server_id), - self._servers - .get_servers() - .where(lambda x: x.server_id == server.server_id), - self._user_joined_servers - .get_user_joined_servers() - .where(lambda x: x.user.server.server_id == server.server_id), - self._user_joined_voice_channel - .get_user_joined_voice_channels() - .where(lambda x: x.user.server.server_id == server.server_id), - self._users - .get_users() - .where(lambda x: x.server.server_id == server.server_id), - guild + self._levels.get_levels().where(lambda x: x.server.server_id == server.server_id), + self._servers.get_servers().where(lambda x: x.server_id == server.server_id), + self._user_joined_servers.get_user_joined_servers().where( + lambda x: x.user.server.server_id == server.server_id + ), + self._user_joined_voice_channel.get_user_joined_voice_channels().where( + lambda x: x.user.server.server_id == server.server_id + ), + self._users.get_users().where(lambda x: x.server.server_id == server.server_id), + guild, ) @staticmethod async def get_data( - code: str, - auto_roles: List[AutoRole], - clients: List[Client], - known_users: List[KnownUser], - levels: List[Level], - servers: List[Server], - user_joined_servers: List[UserJoinedServer], - user_joined_voice_channel: List[UserJoinedVoiceChannel], - users: List[User], - guild: Guild + code: str, + auto_roles: List[AutoRole], + clients: List[Client], + known_users: List[KnownUser], + levels: List[Level], + servers: List[Server], + user_joined_servers: List[UserJoinedServer], + user_joined_voice_channel: List[UserJoinedVoiceChannel], + users: List[User], + guild: Guild, ) -> StatisticResult: result = StatisticResult() exec(code) diff --git a/kdb-bot/src/modules/stats/stats.json b/kdb-bot/src/modules/stats/stats.json index 7fca6677..d063c651 100644 --- a/kdb-bot/src/modules/stats/stats.json +++ b/kdb-bot/src/modules/stats/stats.json @@ -4,7 +4,7 @@ "Version": { "Major": "0", "Minor": "3", - "Micro": "0" + "Micro": "1" }, "Author": "", "AuthorEmail": "", diff --git a/kdb-bot/src/modules/stats/stats_module.py b/kdb-bot/src/modules/stats/stats_module.py index 4c60b02a..9cb459af 100644 --- a/kdb-bot/src/modules/stats/stats_module.py +++ b/kdb-bot/src/modules/stats/stats_module.py @@ -10,7 +10,6 @@ from modules.stats.service.statistic_service import StatisticService class StatsModule(ModuleABC): - def __init__(self, dc: DiscordCollectionABC): ModuleABC.__init__(self, dc, FeatureFlagsEnum.stats_module) diff --git a/kdb-bot/src/modules/stats/ui/__init__.py b/kdb-bot/src/modules/stats/ui/__init__.py index 8c713f45..8e71e850 100644 --- a/kdb-bot/src/modules/stats/ui/__init__.py +++ b/kdb-bot/src/modules/stats/ui/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'modules.stats.ui' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "modules.stats.ui" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/modules/stats/ui/add_statistic_form.py b/kdb-bot/src/modules/stats/ui/add_statistic_form.py index 625bac82..0688aef6 100644 --- a/kdb-bot/src/modules/stats/ui/add_statistic_form.py +++ b/kdb-bot/src/modules/stats/ui/add_statistic_form.py @@ -13,20 +13,20 @@ from bot_data.model.statistic import Statistic class AddStatisticForm(ui.Modal): - description = ui.TextInput(label='Beschreibung', required=True) - code = ui.TextInput(label='Code', required=True, style=TextStyle.long) + description = ui.TextInput(label="Beschreibung", required=True) + code = ui.TextInput(label="Code", required=True, style=TextStyle.long) def __init__( - self, - server: Server, - stats: StatisticRepositoryABC, - db: DatabaseContextABC, - name: str, - message_service: MessageServiceABC, - logger: CommandLogger, - t: TranslatePipe, - code: str = None, - description: str = None, + self, + server: Server, + stats: StatisticRepositoryABC, + db: DatabaseContextABC, + name: str, + message_service: MessageServiceABC, + logger: CommandLogger, + t: TranslatePipe, + code: str = None, + description: str = None, ): ui.Modal.__init__(self, title=name) @@ -45,32 +45,55 @@ class AddStatisticForm(ui.Modal): self.description.default = description async def on_submit(self, interaction: discord.Interaction): - statistic = self._stats.get_statistics_by_server_id(self._server.server_id).where(lambda s: s.name == self._name).single_or_default() + statistic = ( + self._stats.get_statistics_by_server_id(self._server.server_id) + .where(lambda s: s.name == self._name) + .single_or_default() + ) if interaction.guild is None: if statistic is None: - await self._message_service.send_interaction_msg(interaction, self._t.transform('modules.stats.add.failed')) + await self._message_service.send_interaction_msg( + interaction, self._t.transform("modules.stats.add.failed") + ) else: - await self._message_service.send_interaction_msg(interaction, self._t.transform('modules.stats.edit.failed')) + await self._message_service.send_interaction_msg( + interaction, self._t.transform("modules.stats.edit.failed") + ) return try: if statistic is None: - self._stats.add_statistic(Statistic(self._name, self.description.value, self.code.value, self._server)) + self._stats.add_statistic( + Statistic( + self._name, + self.description.value, + self.code.value, + self._server, + ) + ) self._db.save_changes() - await self._message_service.send_interaction_msg(interaction, self._t.transform('modules.stats.add.success')) + await self._message_service.send_interaction_msg( + interaction, self._t.transform("modules.stats.add.success") + ) return statistic.description = self.description.value statistic.code = self.code.value self._stats.update_statistic(statistic) self._db.save_changes() - await self._message_service.send_interaction_msg(interaction, self._t.transform('modules.stats.edit.success')) + await self._message_service.send_interaction_msg( + interaction, self._t.transform("modules.stats.edit.success") + ) except Exception as e: - self._logger.error(__name__, f'Save statistic {self._name} failed', e) + self._logger.error(__name__, f"Save statistic {self._name} failed", e) if statistic is None: - await self._message_service.send_interaction_msg(interaction, self._t.transform('modules.stats.add.failed')) + await self._message_service.send_interaction_msg( + interaction, self._t.transform("modules.stats.add.failed") + ) else: - await self._message_service.send_interaction_msg(interaction, self._t.transform('modules.stats.edit.failed')) + await self._message_service.send_interaction_msg( + interaction, self._t.transform("modules.stats.edit.failed") + ) - self._logger.trace(__name__, f'Finished stats command form') + self._logger.trace(__name__, f"Finished stats command form") diff --git a/kdb-bot/src/modules/technician/__init__.py b/kdb-bot/src/modules/technician/__init__.py index 7227c7f2..70439bd1 100644 --- a/kdb-bot/src/modules/technician/__init__.py +++ b/kdb-bot/src/modules/technician/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'modules.technician' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "modules.technician" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple -# imports: +# imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/modules/technician/command/__init__.py b/kdb-bot/src/modules/technician/command/__init__.py index f630985e..6326d824 100644 --- a/kdb-bot/src/modules/technician/command/__init__.py +++ b/kdb-bot/src/modules/technician/command/__init__.py @@ -6,21 +6,21 @@ bot Keksdose bot Discord bot for the Keksdose discord Server -:copyright: (c) 2022 sh-edraft.de +:copyright: (c) 2022 - 2023 sh-edraft.de :license: MIT, see LICENSE for more details. """ -__title__ = 'modules.technician.command' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '0.3.0' +__title__ = "modules.technician.command" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" +__version__ = "0.3.1" from collections import namedtuple # imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='0', minor='3', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="0", minor="3", micro="1") diff --git a/kdb-bot/src/modules/technician/command/log_command.py b/kdb-bot/src/modules/technician/command/log_command.py index 3988ce63..2f799d61 100644 --- a/kdb-bot/src/modules/technician/command/log_command.py +++ b/kdb-bot/src/modules/technician/command/log_command.py @@ -13,7 +13,7 @@ from cpl_translation import TranslatePipe from discord.ext import commands from discord.ext.commands import Context -from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC +from bot_core.abc.client_utils_abc import ClientUtilsABC from bot_core.abc.custom_file_logger_abc import CustomFileLoggerABC from bot_core.abc.message_service_abc import MessageServiceABC from bot_core.helper.command_checks import CommandChecks @@ -22,18 +22,17 @@ from modules.permission.abc.permission_service_abc import PermissionServiceABC class LogCommand(DiscordCommandABC): - def __init__( - self, - logger: CommandLogger, - logging_settings: LoggingSettings, - services: ServiceProviderABC, - message_service: MessageServiceABC, - client_utils: ClientUtilsServiceABC, - translate: TranslatePipe, - permissions: PermissionServiceABC, - time_format: TimeFormatSettings, - env: ApplicationEnvironmentABC + self, + logger: CommandLogger, + logging_settings: LoggingSettings, + services: ServiceProviderABC, + message_service: MessageServiceABC, + client_utils: ClientUtilsABC, + translate: TranslatePipe, + permissions: PermissionServiceABC, + time_format: TimeFormatSettings, + env: ApplicationEnvironmentABC, ): DiscordCommandABC.__init__(self) @@ -49,10 +48,10 @@ class LogCommand(DiscordCommandABC): self._log_settings: LoggingSettings = logging_settings self._time_format_settings: TimeFormatSettings = time_format - self._logger.trace(__name__, f'Loaded command service: {type(self).__name__}') + self._logger.trace(__name__, f"Loaded command service: {type(self).__name__}") def _reduce_path(self, p: str) -> str: - if len(p.split('/')) == 1 or p == '': + if len(p.split("/")) == 1 or p == "": return p return self._reduce_path(os.path.dirname(p)) @@ -62,15 +61,15 @@ class LogCommand(DiscordCommandABC): @CommandChecks.check_is_ready() @CommandChecks.check_is_member_technician() async def log(self, ctx: Context): - self._logger.debug(__name__, f'Received command log {ctx}') + self._logger.debug(__name__, f"Received command log {ctx}") possible_log_paths = List(str) possible_log_paths.append(self._reduce_path(self._logging_settings.path)) file_extensions = List(str) - if '.' in self._logging_settings.filename: + if "." in self._logging_settings.filename: split_filename = self._logging_settings.filename.split(".") - file_extensions.append(f'.{split_filename[len(split_filename) - 1]}') + file_extensions.append(f".{split_filename[len(split_filename) - 1]}") for subclass in CustomFileLoggerABC.__subclasses__(): logger: CustomFileLoggerABC = self._services.get_service(subclass) @@ -78,9 +77,9 @@ class LogCommand(DiscordCommandABC): continue path = self._reduce_path(logger.settings.path) - if '.' in logger.settings.filename: + if "." in logger.settings.filename: split_filename = logger.settings.filename.split(".") - file_extension = f'.{split_filename[len(split_filename) - 1]}' + file_extension = f".{split_filename[len(split_filename) - 1]}" if file_extension not in file_extensions: file_extensions.append(file_extension) @@ -89,28 +88,32 @@ class LogCommand(DiscordCommandABC): possible_log_paths.append(path) files_str = "\n\t".join(possible_log_paths.to_list()) - self._logger.debug(__name__, f'Possible log files: \n\t{files_str}') + self._logger.debug(__name__, f"Possible log files: \n\t{files_str}") files = List(str) for possible_path in possible_log_paths: for r, d, f in os.walk(possible_path): for file in f: - if '.' not in file: + if "." not in file: continue split_filename = file.split(".") - if f'.{split_filename[len(split_filename) - 1]}' not in file_extensions: + if f".{split_filename[len(split_filename) - 1]}" not in file_extensions: continue files.append(os.path.join(r, file)) files_str = "\n\t".join(files.to_list()) - self._logger.debug(__name__, f'Log files: \n\t{files_str}') + self._logger.debug(__name__, f"Log files: \n\t{files_str}") - zip_file = ZipFile('logs.zip', 'w') + zip_file = ZipFile("logs.zip", "w") files.for_each(lambda x: zip_file.write(x)) zip_file.close() - await self._message_service.send_interaction_msg(ctx.interaction, self._t.transform('modules.technician.log_message'), file=discord.File(zip_file.filename, 'logs.zip')) + await self._message_service.send_interaction_msg( + ctx.interaction, + self._t.transform("modules.technician.log_message"), + file=discord.File(zip_file.filename, "logs.zip"), + ) os.remove(zip_file.filename) - self._logger.trace(__name__, f'Finished log command') + self._logger.trace(__name__, f"Finished log command") diff --git a/kdb-bot/src/modules/technician/command/restart_command.py b/kdb-bot/src/modules/technician/command/restart_command.py index 0a14e41b..302ba7e9 100644 --- a/kdb-bot/src/modules/technician/command/restart_command.py +++ b/kdb-bot/src/modules/technician/command/restart_command.py @@ -7,7 +7,7 @@ from cpl_translation import TranslatePipe from discord.ext import commands from discord.ext.commands import Context -from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC +from bot_core.abc.client_utils_abc import ClientUtilsABC from bot_core.abc.message_service_abc import MessageServiceABC from bot_core.configuration.bot_settings import BotSettings from bot_core.helper.command_checks import CommandChecks @@ -16,17 +16,16 @@ from modules.permission.abc.permission_service_abc import PermissionServiceABC class RestartCommand(DiscordCommandABC): - def __init__( - self, - logger: CommandLogger, - config: ConfigurationABC, - message_service: MessageServiceABC, - bot: DiscordBotServiceABC, - client_utils: ClientUtilsServiceABC, - translate: TranslatePipe, - permissions: PermissionServiceABC, - settings: BotSettings + self, + logger: CommandLogger, + config: ConfigurationABC, + message_service: MessageServiceABC, + bot: DiscordBotServiceABC, + client_utils: ClientUtilsABC, + translate: TranslatePipe, + permissions: PermissionServiceABC, + settings: BotSettings, ): DiscordCommandABC.__init__(self) @@ -39,19 +38,19 @@ class RestartCommand(DiscordCommandABC): self._permissions = permissions self._settings = settings - self._logger.trace(__name__, f'Loaded command service: {type(self).__name__}') + self._logger.trace(__name__, f"Loaded command service: {type(self).__name__}") @commands.hybrid_command() @commands.guild_only() @CommandChecks.check_is_ready() @CommandChecks.check_is_member_technician() async def restart(self, ctx: Context): - self._logger.debug(__name__, f'Received command restart {ctx}') + self._logger.debug(__name__, f"Received command restart {ctx}") - self._config.add_configuration('IS_RESTART', 'true') - await self._client_utils.presence_game('common.presence.restart') - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.technician.restart_message')) + self._config.add_configuration("IS_RESTART", "true") + await self._client_utils.presence_game("common.presence.restart") + await self._message_service.send_ctx_msg(ctx, self._t.transform("modules.technician.restart_message")) await asyncio.sleep(self._settings.wait_for_restart) await self._bot.stop_async() - self._logger.trace(__name__, f'Finished restart command') + self._logger.trace(__name__, f"Finished restart command") diff --git a/kdb-bot/src/modules/technician/command/shutdown_command.py b/kdb-bot/src/modules/technician/command/shutdown_command.py index f81d127a..6ba52651 100644 --- a/kdb-bot/src/modules/technician/command/shutdown_command.py +++ b/kdb-bot/src/modules/technician/command/shutdown_command.py @@ -8,7 +8,7 @@ from cpl_translation import TranslatePipe from discord.ext import commands from discord.ext.commands import Context -from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC +from bot_core.abc.client_utils_abc import ClientUtilsABC from bot_core.abc.message_service_abc import MessageServiceABC from bot_core.configuration.bot_settings import BotSettings from bot_core.helper.command_checks import CommandChecks @@ -17,17 +17,16 @@ from modules.permission.abc.permission_service_abc import PermissionServiceABC class ShutdownCommand(DiscordCommandABC): - def __init__( - self, - logger: CommandLogger, - config: ConfigurationABC, - message_service: MessageServiceABC, - bot: DiscordBotServiceABC, - client_utils: ClientUtilsServiceABC, - translate: TranslatePipe, - permissions: PermissionServiceABC, - settings: BotSettings + self, + logger: CommandLogger, + config: ConfigurationABC, + message_service: MessageServiceABC, + bot: DiscordBotServiceABC, + client_utils: ClientUtilsABC, + translate: TranslatePipe, + permissions: PermissionServiceABC, + settings: BotSettings, ): DiscordCommandABC.__init__(self) @@ -40,18 +39,18 @@ class ShutdownCommand(DiscordCommandABC): self._permissions = permissions self._settings = settings - self._logger.trace(__name__, f'Loaded command service: {type(self).__name__}') + self._logger.trace(__name__, f"Loaded command service: {type(self).__name__}") @commands.hybrid_command() @commands.guild_only() @CommandChecks.check_is_ready() @CommandChecks.check_is_member_technician() async def shutdown(self, ctx: Context): - self._logger.debug(__name__, f'Received command shutdown {ctx}') + self._logger.debug(__name__, f"Received command shutdown {ctx}") - await self._client_utils.presence_game('common.presence.shutdown') - await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.technician.shutdown_message')) + await self._client_utils.presence_game("common.presence.shutdown") + await self._message_service.send_ctx_msg(ctx, self._t.transform("modules.technician.shutdown_message")) await asyncio.sleep(self._settings.wait_for_shutdown) await self._bot.stop_async() - self._logger.trace(__name__, f'Finished shutdown command') + self._logger.trace(__name__, f"Finished shutdown command") diff --git a/kdb-bot/src/modules/technician/technician.json b/kdb-bot/src/modules/technician/technician.json index 98455a19..4f69b972 100644 --- a/kdb-bot/src/modules/technician/technician.json +++ b/kdb-bot/src/modules/technician/technician.json @@ -4,7 +4,7 @@ "Version": { "Major": "0", "Minor": "3", - "Micro": "0" + "Micro": "1" }, "Author": "", "AuthorEmail": "", diff --git a/kdb-bot/src/modules/technician/technician_module.py b/kdb-bot/src/modules/technician/technician_module.py index 5c074ca8..9a9ca7ba 100644 --- a/kdb-bot/src/modules/technician/technician_module.py +++ b/kdb-bot/src/modules/technician/technician_module.py @@ -13,7 +13,6 @@ from modules.base.service.base_helper_service import BaseHelperService class TechnicianModule(ModuleABC): - def __init__(self, dc: DiscordCollectionABC): ModuleABC.__init__(self, dc, FeatureFlagsEnum.base_module) diff --git a/kdb-bot/tools/get_version/__init__.py b/kdb-bot/tools/get_version/__init__.py index 12ffaf20..7db6ac36 100644 --- a/kdb-bot/tools/get_version/__init__.py +++ b/kdb-bot/tools/get_version/__init__.py @@ -11,16 +11,16 @@ CPL internal tool to set version from branch name """ -__title__ = 'get_version' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '1.0.0' +__title__ = "get_version" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 sh-edraft.de" +__version__ = "1.0.0" from collections import namedtuple -# imports: +# imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='1', minor='0', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="1", minor="0", micro="0") diff --git a/kdb-bot/tools/get_version/application.py b/kdb-bot/tools/get_version/application.py index bc4d8935..60447605 100644 --- a/kdb-bot/tools/get_version/application.py +++ b/kdb-bot/tools/get_version/application.py @@ -6,7 +6,6 @@ from cpl_core.dependency_injection.service_provider_abc import ServiceProviderAB class Application(ApplicationABC): - def __init__(self, config: ConfigurationABC, services: ServiceProviderABC): ApplicationABC.__init__(self, config, services) diff --git a/kdb-bot/tools/get_version/get-version.json b/kdb-bot/tools/get_version/get-version.json index 05c178d9..5a988b8b 100644 --- a/kdb-bot/tools/get_version/get-version.json +++ b/kdb-bot/tools/get_version/get-version.json @@ -4,7 +4,7 @@ "Version": { "Major": "0", "Minor": "3", - "Micro": "0" + "Micro": "1" }, "Author": "Sven Heidemann", "AuthorEmail": "sven.heidemann@sh-edraft.de", diff --git a/kdb-bot/tools/get_version/main.py b/kdb-bot/tools/get_version/main.py index 81ac71ba..87e57cd2 100644 --- a/kdb-bot/tools/get_version/main.py +++ b/kdb-bot/tools/get_version/main.py @@ -10,5 +10,5 @@ def main(): app_builder.build().run() -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/kdb-bot/tools/get_version/startup.py b/kdb-bot/tools/get_version/startup.py index 946f8541..8cb6680f 100644 --- a/kdb-bot/tools/get_version/startup.py +++ b/kdb-bot/tools/get_version/startup.py @@ -8,17 +8,20 @@ from cpl_core.environment import ApplicationEnvironment class Startup(StartupABC): - def __init__(self): StartupABC.__init__(self) - def configure_configuration(self, configuration: ConfigurationABC, environment: ApplicationEnvironment) -> ConfigurationABC: - environment.set_working_directory(os.path.abspath(os.path.join(environment.working_directory, '../../'))) - configuration.add_json_file(f'cpl-workspace.json', optional=False, output=False) + def configure_configuration( + self, configuration: ConfigurationABC, environment: ApplicationEnvironment + ) -> ConfigurationABC: + environment.set_working_directory(os.path.abspath(os.path.join(environment.working_directory, "../../"))) + configuration.add_json_file(f"cpl-workspace.json", optional=False, output=False) ws: WorkspaceSettings = configuration.get_configuration(WorkspaceSettings) configuration.add_json_file(ws.projects[ws.default_project], optional=False, output=False) return configuration - def configure_services(self, services: ServiceCollectionABC, environment: ApplicationEnvironment) -> ServiceProviderABC: + def configure_services( + self, services: ServiceCollectionABC, environment: ApplicationEnvironment + ) -> ServiceProviderABC: return services.build_service_provider() diff --git a/kdb-bot/tools/post_build/__init__.py b/kdb-bot/tools/post_build/__init__.py index 372a0aa7..29fe07f8 100644 --- a/kdb-bot/tools/post_build/__init__.py +++ b/kdb-bot/tools/post_build/__init__.py @@ -11,16 +11,16 @@ Tool project to clean build project files """ -__title__ = 'post_build' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '1.0.0' +__title__ = "post_build" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 sh-edraft.de" +__version__ = "1.0.0" from collections import namedtuple -# imports: +# imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='1', minor='0', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="1", minor="0", micro="0") diff --git a/kdb-bot/tools/post_build/application.py b/kdb-bot/tools/post_build/application.py index 29f67e58..e3db8dad 100644 --- a/kdb-bot/tools/post_build/application.py +++ b/kdb-bot/tools/post_build/application.py @@ -8,7 +8,6 @@ from post_build.service.remove_config import RemoveConfig class Application(ApplicationABC): - def __init__(self, config: ConfigurationABC, services: ServiceProviderABC): ApplicationABC.__init__(self, config, services) @@ -19,8 +18,6 @@ class Application(ApplicationABC): pass def main(self): - Console.write_line('KDB Post-Build:') - Console.spinner(f'Removing unnecessary configs', self._remove_config.remove) - Console.spinner(f'Creating requirements file for pip', self._deps.create) - - + Console.write_line("KDB Post-Build:") + Console.spinner(f"Removing unnecessary configs", self._remove_config.remove) + Console.spinner(f"Creating requirements file for pip", self._deps.create) diff --git a/kdb-bot/tools/post_build/main.py b/kdb-bot/tools/post_build/main.py index 042ae520..fb2f140b 100644 --- a/kdb-bot/tools/post_build/main.py +++ b/kdb-bot/tools/post_build/main.py @@ -10,5 +10,5 @@ def main(): app_builder.build().run() -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/kdb-bot/tools/post_build/post-build.json b/kdb-bot/tools/post_build/post-build.json index e00c4c75..9f9f2af7 100644 --- a/kdb-bot/tools/post_build/post-build.json +++ b/kdb-bot/tools/post_build/post-build.json @@ -4,7 +4,7 @@ "Version": { "Major": "0", "Minor": "3", - "Micro": "0" + "Micro": "1" }, "Author": "Sven Heidemann", "AuthorEmail": "sven.heidemann@sh-edraft.de", diff --git a/kdb-bot/tools/post_build/post_build_settings.py b/kdb-bot/tools/post_build/post_build_settings.py index e52ec53f..3c8a789e 100644 --- a/kdb-bot/tools/post_build/post_build_settings.py +++ b/kdb-bot/tools/post_build/post_build_settings.py @@ -5,7 +5,6 @@ from cpl_core.console import Console class PostBuildSettings(ConfigurationModelABC): - def __init__(self): ConfigurationModelABC.__init__(self) @@ -15,15 +14,15 @@ class PostBuildSettings(ConfigurationModelABC): @property def keep_config(self) -> list[str]: return self._keep_config - + @property def config_paths(self) -> list[str]: return self._config_paths def from_dict(self, settings: dict): try: - self._keep_config = settings['KeepConfigs'] - self._config_paths = settings['ConfigPaths'] + self._keep_config = settings["KeepConfigs"] + self._config_paths = settings["ConfigPaths"] except Exception as e: - Console.error(f'[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings') - Console.error(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}') + Console.error(f"[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings") + Console.error(f"[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}") diff --git a/kdb-bot/tools/post_build/service/__init__.py b/kdb-bot/tools/post_build/service/__init__.py index eec51612..27999ddd 100644 --- a/kdb-bot/tools/post_build/service/__init__.py +++ b/kdb-bot/tools/post_build/service/__init__.py @@ -11,16 +11,16 @@ Tool project to clean build project files """ -__title__ = 'post_build.service' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '1.0.0' +__title__ = "post_build.service" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 sh-edraft.de" +__version__ = "1.0.0" from collections import namedtuple # imports -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='1', minor='0', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="1", minor="0", micro="0") diff --git a/kdb-bot/tools/post_build/service/dependencies.py b/kdb-bot/tools/post_build/service/dependencies.py index 1359b738..060adae4 100644 --- a/kdb-bot/tools/post_build/service/dependencies.py +++ b/kdb-bot/tools/post_build/service/dependencies.py @@ -9,15 +9,14 @@ from post_build.post_build_settings import PostBuildSettings class Dependencies: - def __init__( - self, - config: ConfigurationABC, - env: ApplicationEnvironmentABC, - ws: WorkspaceSettings, - project: ProjectSettings, - build: BuildSettings, - post_build: PostBuildSettings + self, + config: ConfigurationABC, + env: ApplicationEnvironmentABC, + ws: WorkspaceSettings, + project: ProjectSettings, + build: BuildSettings, + post_build: PostBuildSettings, ): self._config = config self._env = env @@ -31,12 +30,12 @@ class Dependencies: def _add_dependencies(self, deps: list[str]): for d in deps: d_name = d - if '>=' in d: - d_name = d.split('>=')[0] - if '<=' in d: - d_name = d.split('<=')[0] - if '==' in d: - d_name = d.split('==')[0] + if ">=" in d: + d_name = d.split(">=")[0] + if "<=" in d: + d_name = d.split("<=")[0] + if "==" in d: + d_name = d.split("==")[0] if d_name in self._dependencies: continue @@ -44,13 +43,15 @@ class Dependencies: self._dependencies[d_name] = d def create(self): - dist_path = os.path.abspath(os.path.join( - self._env.working_directory, - os.path.dirname(self._workspace.projects[self._project.name]), - self._build.output_path, - self._project.name, - 'build' - )) + dist_path = os.path.abspath( + os.path.join( + self._env.working_directory, + os.path.dirname(self._workspace.projects[self._project.name]), + self._build.output_path, + self._project.name, + "build", + ) + ) for project in self._workspace.projects: project_file = os.path.join(self._env.working_directory, self._workspace.projects[project]) @@ -58,7 +59,7 @@ class Dependencies: project: ProjectSettings = self._config.get_configuration(ProjectSettings) self._add_dependencies(project.dependencies) - with open(f'{dist_path}/requirements.txt', 'w+', encoding='utf-8') as f: + with open(f"{dist_path}/requirements.txt", "w+", encoding="utf-8") as f: for dependency in self._dependencies: - f.write(f'{self._dependencies[dependency]}\n') + f.write(f"{self._dependencies[dependency]}\n") f.close() diff --git a/kdb-bot/tools/post_build/service/remove_config.py b/kdb-bot/tools/post_build/service/remove_config.py index 99210a30..ab8b9d47 100644 --- a/kdb-bot/tools/post_build/service/remove_config.py +++ b/kdb-bot/tools/post_build/service/remove_config.py @@ -8,8 +8,14 @@ from post_build.post_build_settings import PostBuildSettings class RemoveConfig: - - def __init__(self, env: ApplicationEnvironmentABC, ws: WorkspaceSettings, project: ProjectSettings, build: BuildSettings, post_build: PostBuildSettings): + def __init__( + self, + env: ApplicationEnvironmentABC, + ws: WorkspaceSettings, + project: ProjectSettings, + build: BuildSettings, + post_build: PostBuildSettings, + ): self._env = env self._workspace = ws @@ -18,19 +24,18 @@ class RemoveConfig: self._post_build = post_build def remove(self): - dist_path = os.path.abspath(os.path.join( - self._env.working_directory, - os.path.dirname(self._workspace.projects[self._project.name]), - self._build.output_path, - self._project.name, - 'build' - )) + dist_path = os.path.abspath( + os.path.join( + self._env.working_directory, + os.path.dirname(self._workspace.projects[self._project.name]), + self._build.output_path, + self._project.name, + "build", + ) + ) for cfg_path in self._post_build.config_paths: - config_path = os.path.join( - dist_path, - cfg_path - ) + config_path = os.path.join(dist_path, cfg_path) for r, d, f in os.walk(config_path): for file in f: if file in self._post_build.keep_config: diff --git a/kdb-bot/tools/post_build/startup.py b/kdb-bot/tools/post_build/startup.py index a3afba39..537f3f2a 100644 --- a/kdb-bot/tools/post_build/startup.py +++ b/kdb-bot/tools/post_build/startup.py @@ -11,20 +11,23 @@ from post_build.service.remove_config import RemoveConfig class Startup(StartupABC): - def __init__(self): StartupABC.__init__(self) - def configure_configuration(self, configuration: ConfigurationABC, environment: ApplicationEnvironment) -> ConfigurationABC: - configuration.add_json_file(f'appsettings.json', optional=False, output=False) - environment.set_working_directory(os.path.abspath(os.path.join(environment.working_directory, '../../'))) - configuration.add_json_file(f'cpl-workspace.json', optional=False, output=False) + def configure_configuration( + self, configuration: ConfigurationABC, environment: ApplicationEnvironment + ) -> ConfigurationABC: + configuration.add_json_file(f"appsettings.json", optional=False, output=False) + environment.set_working_directory(os.path.abspath(os.path.join(environment.working_directory, "../../"))) + configuration.add_json_file(f"cpl-workspace.json", optional=False, output=False) ws: WorkspaceSettings = configuration.get_configuration(WorkspaceSettings) configuration.add_json_file(ws.projects[ws.default_project], optional=False, output=False) return configuration - def configure_services(self, services: ServiceCollectionABC, environment: ApplicationEnvironment) -> ServiceProviderABC: + def configure_services( + self, services: ServiceCollectionABC, environment: ApplicationEnvironment + ) -> ServiceProviderABC: services.add_transient(RemoveConfig) services.add_transient(Dependencies) diff --git a/kdb-bot/tools/set_version/__init__.py b/kdb-bot/tools/set_version/__init__.py index ef7b39f6..dd65d98a 100644 --- a/kdb-bot/tools/set_version/__init__.py +++ b/kdb-bot/tools/set_version/__init__.py @@ -11,16 +11,16 @@ CPL internal tool to set version from branch name """ -__title__ = 'set_version' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2022 sh-edraft.de' -__version__ = '2022.7.0' +__title__ = "set_version" +__author__ = "Sven Heidemann" +__license__ = "MIT" +__copyright__ = "Copyright (c) 2022 sh-edraft.de" +__version__ = "2022.7.0" from collections import namedtuple -# imports: +# imports: -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='7', micro='0') +VersionInfo = namedtuple("VersionInfo", "major minor micro") +version_info = VersionInfo(major="2022", minor="7", micro="0") diff --git a/kdb-bot/tools/set_version/application.py b/kdb-bot/tools/set_version/application.py index f9b1e711..f656c453 100644 --- a/kdb-bot/tools/set_version/application.py +++ b/kdb-bot/tools/set_version/application.py @@ -16,7 +16,6 @@ from set_version.version_setter_service import VersionSetterService class Application(ApplicationABC): - def __init__(self, config: ConfigurationABC, services: ServiceProviderABC): ApplicationABC.__init__(self, config, services) @@ -30,15 +29,15 @@ class Application(ApplicationABC): self._configuration.parse_console_arguments(self._services) def main(self): - Console.write_line('Set versions:') + Console.write_line("Set versions:") args = self._configuration.additional_arguments version = {} branch = "" suffix = "" force = False - if '--force' in args: - args.remove('--force') + if "--force" in args: + args.remove("--force") force = True if len(args) > 1: @@ -50,44 +49,46 @@ class Application(ApplicationABC): try: branch = self._git_service.get_active_branch_name() - Console.write_line(f'Found branch: {branch}') + Console.write_line(f"Found branch: {branch}") except Exception as e: - Console.error('Branch not found', traceback.format_exc()) + Console.error("Branch not found", traceback.format_exc()) return try: - if branch.startswith('#'): - self._configuration.add_json_file(self._workspace.projects[self._workspace.default_project], optional=False, output=False) + if branch.startswith("#"): + self._configuration.add_json_file( + self._workspace.projects[self._workspace.default_project], optional=False, output=False + ) ps: ProjectSettings = self._configuration.get_configuration(ProjectSettings) version[VersionSettingsNameEnum.major.value] = ps.version.major version[VersionSettingsNameEnum.minor.value] = ps.version.minor version[VersionSettingsNameEnum.micro.value] = f'dev{branch.split("#")[1]}' else: - version[VersionSettingsNameEnum.major.value] = branch.split('.')[0] - version[VersionSettingsNameEnum.minor.value] = branch.split('.')[1] - if len(branch.split('.')) == 2: - if suffix == '': - suffix = '0' - version[VersionSettingsNameEnum.micro.value] = f'{suffix}' + version[VersionSettingsNameEnum.major.value] = branch.split(".")[0] + version[VersionSettingsNameEnum.minor.value] = branch.split(".")[1] + if len(branch.split(".")) == 2: + if suffix == "": + suffix = "0" + version[VersionSettingsNameEnum.micro.value] = f"{suffix}" else: - if not suffix.startswith('.') and suffix != '': - suffix = f'.{suffix}' + if not suffix.startswith(".") and suffix != "": + suffix = f".{suffix}" version[VersionSettingsNameEnum.micro.value] = f'{branch.split(".")[2]}{suffix}' except Exception as e: - Console.error(f'Branch {branch} does not contain valid version') + Console.error(f"Branch {branch} does not contain valid version") return diff_paths = [] for file in self._git_service.get_diff_files(): - if 'kdb-bot/src' in file: - file = file.replace('kdb-bot/src', '') + if "kdb-bot/src" in file: + file = file.replace("kdb-bot/src", "") - if file.startswith('tools') or 'kdb-web/src' in file: + if file.startswith("tools") or "kdb-web/src" in file: continue - if '/' in file: - file = file.split('/')[1] + if "/" in file: + file = file.split("/")[1] else: file = os.path.basename(os.path.dirname(file)) @@ -104,12 +105,16 @@ class Application(ApplicationABC): skipped.append(project) continue - Console.write_line(f'Set dependencies {self._version_pipe.transform(version)} for {project}') - self._version_setter.set_dependencies(self._workspace.projects[project], version, 'Dependencies', skipped=skipped) - self._version_setter.set_dependencies(self._workspace.projects[project], version, 'DevDependencies', skipped=skipped) + Console.write_line(f"Set dependencies {self._version_pipe.transform(version)} for {project}") + self._version_setter.set_dependencies( + self._workspace.projects[project], version, "Dependencies", skipped=skipped + ) + self._version_setter.set_dependencies( + self._workspace.projects[project], version, "DevDependencies", skipped=skipped + ) - Console.write_line(f'Set version {self._version_pipe.transform(version)} for {project}') + Console.write_line(f"Set version {self._version_pipe.transform(version)} for {project}") self._version_setter.set_version(self._workspace.projects[project], version) except Exception as e: - Console.error('Version could not be set', traceback.format_exc()) + Console.error("Version could not be set", traceback.format_exc()) return diff --git a/kdb-bot/tools/set_version/git_service.py b/kdb-bot/tools/set_version/git_service.py index c46b52d0..57b3d233 100644 --- a/kdb-bot/tools/set_version/git_service.py +++ b/kdb-bot/tools/set_version/git_service.py @@ -5,10 +5,9 @@ from git import Repo class GitService: - def __init__(self, env: ApplicationEnvironmentABC): self._env = env - self._repo = Repo(os.path.abspath(os.path.join(env.working_directory, '../'))) + self._repo = Repo(os.path.abspath(os.path.join(env.working_directory, "../"))) def get_active_branch_name(self) -> str: branch = self._repo.active_branch diff --git a/kdb-bot/tools/set_version/main.py b/kdb-bot/tools/set_version/main.py index 71943f43..dfbecfda 100644 --- a/kdb-bot/tools/set_version/main.py +++ b/kdb-bot/tools/set_version/main.py @@ -10,5 +10,5 @@ def main(): app_builder.build().run() -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/kdb-bot/tools/set_version/set-version.json b/kdb-bot/tools/set_version/set-version.json index f19b5a18..e70fbdbf 100644 --- a/kdb-bot/tools/set_version/set-version.json +++ b/kdb-bot/tools/set_version/set-version.json @@ -4,7 +4,7 @@ "Version": { "Major": "0", "Minor": "3", - "Micro": "0" + "Micro": "1" }, "Author": "Sven Heidemann", "AuthorEmail": "sven.heidemann@sh-edraft.de", diff --git a/kdb-bot/tools/set_version/startup.py b/kdb-bot/tools/set_version/startup.py index 609ef337..ce7fb47f 100644 --- a/kdb-bot/tools/set_version/startup.py +++ b/kdb-bot/tools/set_version/startup.py @@ -11,19 +11,22 @@ from set_version.version_setter_service import VersionSetterService class Startup(StartupABC): - def __init__(self): StartupABC.__init__(self) - def configure_configuration(self, configuration: ConfigurationABC, environment: ApplicationEnvironment) -> ConfigurationABC: - configuration.add_json_file('cpl-workspace.json', optional=True, output=False) + def configure_configuration( + self, configuration: ConfigurationABC, environment: ApplicationEnvironment + ) -> ConfigurationABC: + configuration.add_json_file("cpl-workspace.json", optional=True, output=False) if configuration.get_configuration(WorkspaceSettings) is None: - environment.set_working_directory(os.path.join(environment.working_directory, '../../')) - configuration.add_json_file('cpl-workspace.json', optional=False, output=False) + environment.set_working_directory(os.path.join(environment.working_directory, "../../")) + configuration.add_json_file("cpl-workspace.json", optional=False, output=False) return configuration - def configure_services(self, services: ServiceCollectionABC, environment: ApplicationEnvironment) -> ServiceProviderABC: + def configure_services( + self, services: ServiceCollectionABC, environment: ApplicationEnvironment + ) -> ServiceProviderABC: services.add_pipes() services.add_singleton(GitService) services.add_transient(VersionSetterService) diff --git a/kdb-bot/tools/set_version/version_setter_service.py b/kdb-bot/tools/set_version/version_setter_service.py index d00a0c08..e1dfcf8a 100644 --- a/kdb-bot/tools/set_version/version_setter_service.py +++ b/kdb-bot/tools/set_version/version_setter_service.py @@ -7,13 +7,12 @@ from cpl_core.utils import String class VersionSetterService: - def __init__(self, env: ApplicationEnvironmentABC): self._env = env def _read_file(self, file: str) -> dict: project_json = {} - with open(os.path.join(self._env.working_directory, file), 'r', encoding='utf-8') as f: + with open(os.path.join(self._env.working_directory, file), "r", encoding="utf-8") as f: # load json project_json = json.load(f) f.close() @@ -21,37 +20,43 @@ class VersionSetterService: return project_json def _write_file(self, file: str, project_json: dict): - with open(os.path.join(self._env.working_directory, file), 'w', encoding='utf-8') as f: + with open(os.path.join(self._env.working_directory, file), "w", encoding="utf-8") as f: f.write(json.dumps(project_json, indent=2)) f.close() def set_version(self, file: str, version: dict): project_json = self._read_file(file) - project_json['ProjectSettings']['Version'] = version + project_json["ProjectSettings"]["Version"] = version self._write_file(file, project_json) def set_dependencies(self, file: str, version: dict, key: str, skipped=None): project_json = self._read_file(file) - if key not in project_json['ProjectSettings']: - project_json['ProjectSettings'][key] = [] + if key not in project_json["ProjectSettings"]: + project_json["ProjectSettings"][key] = [] - dependencies = project_json['ProjectSettings'][key] + dependencies = project_json["ProjectSettings"][key] new_deps = [] for dependency in dependencies: - if not dependency.startswith('cpl-'): + if not dependency.startswith("cpl-"): new_deps.append(dependency) continue - dep_version = dependency.split('=')[1] - dep_name = dependency.split('=')[0] - if dep_name[len(dep_name)-1] not in ascii_letters: - dep_name = dep_name[:len(dep_name)-1] + dep_version = dependency.split("=")[1] + dep_name = dependency.split("=")[0] + if dep_name[len(dep_name) - 1] not in ascii_letters: + dep_name = dep_name[: len(dep_name) - 1] - if skipped is not None and (dep_name in skipped or String.convert_to_snake_case(dep_name) in skipped) or dep_version == '': + if ( + skipped is not None + and (dep_name in skipped or String.convert_to_snake_case(dep_name) in skipped) + or dep_version == "" + ): new_deps.append(dependency) continue - new_deps.append(dependency.replace(dep_version, f'{version["Major"]}.{version["Minor"]}.{version["Micro"]}')) + new_deps.append( + dependency.replace(dep_version, f'{version["Major"]}.{version["Minor"]}.{version["Micro"]}') + ) - project_json['ProjectSettings'][key] = new_deps + project_json["ProjectSettings"][key] = new_deps self._write_file(file, project_json)