Compare commits
	
		
			181 Commits
		
	
	
		
			1.0.7
			...
			e52f5e4186
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| e52f5e4186 | |||
| 85ba012b6f | |||
| d4b40eb52e | |||
| ed524c2f64 | |||
| 8e3c8459f8 | |||
| e661ee1489 | |||
| 9eaeb2df42 | |||
| 481c0f881a | |||
| a065c703eb | |||
| f72ea68f66 | |||
| 9226a1188e | |||
| c06cb02cd6 | |||
| 20747001b0 | |||
| b4be6b4ac2 | |||
| bd3dd39dbc | |||
| 9e0905d49e | |||
| 3c0719f50e | |||
| 77d3668a06 | |||
| e914c7d02b | |||
| b40f521212 | |||
| d40ca88cd5 | |||
| 1e63baed97 | |||
| cdfd151851 | |||
| 12fbc972d9 | |||
| dca939f025 | |||
| ed9b893c12 | |||
| 731f80bd5f | |||
| 85852bf2f0 | |||
| 2c3ef97a14 | |||
| 9ec65689ba | |||
| 44f5de32a5 | |||
| c016d5fc84 | |||
| 306ce2664c | |||
| 3ce5471ef4 | |||
| 4cdd6c05bf | |||
| d364ea1b4c | |||
| 6fa08ea828 | |||
| 296c6e8044 | |||
| 0541f3dfde | |||
| 052e0f976a | |||
| f41dfc9be2 | |||
| 74437fdc20 | |||
| df2b660b75 | |||
| 12f231aa41 | |||
| 2f3ae229c9 | |||
| 5bbed854a4 | |||
| 2321c12bc9 | |||
| 1cdfd1291f | |||
| 223946ad76 | |||
| 4ea1b5b94c | |||
| 919970d199 | |||
| 19ed164845 | |||
| 92001a45be | |||
| 78b761a672 | |||
| 7bfa39f459 | |||
| d586cca672 | |||
| efce172c01 | |||
| 0974325148 | |||
| 206754919f | |||
| b49512e28d | |||
| fa71759a20 | |||
| 9338e35504 | |||
| 2956dcb9c2 | |||
| 762bebf416 | |||
| f3b5cef253 | |||
| 6869c5a671 | |||
| 352b44be0f | |||
| 5912708d3a | |||
| 45a3127696 | |||
| 10c20621a8 | |||
| 49e0e44461 | |||
| ec6b080ba6 | |||
| 28944755ac | |||
| 7318239b2d | |||
| cf66d246a9 | |||
| 41fe6faa52 | |||
| 685c96bb38 | |||
| 2c3e5268e4 | |||
| 2d5ce58612 | |||
| fe3d67eff5 | |||
| 4cea31fce5 | |||
| aa2c80ec12 | |||
| e283a18def | |||
| f5b2bec356 | |||
| c2b32996fd | |||
| 195566a2b6 | |||
| 073c318671 | |||
| caeec47b7c | |||
| 44f6b36347 | |||
| 4e32414f48 | |||
| 573c9c999e | |||
| 825fcff82d | |||
| a95bf7bc6c | |||
| 0bc3bff58e | |||
| c3b86fab6b | |||
| 906602134e | |||
| 30791f7529 | |||
| 456d939b47 | |||
| 1f47636e8d | |||
| f4acc2669d | |||
| 46b5757fd1 | |||
| 1cd75cd78f | |||
| f7f3fea7a7 | |||
| 5dd2000f10 | |||
| 1b2bb85b37 | |||
| 113b188a40 | |||
| e549341196 | |||
| 8a0d939147 | |||
| 4b57d7f102 | |||
| 02e0c72a80 | |||
| bfc9979961 | |||
| 8d76f79732 | |||
| 4add293186 | |||
| 1fc5ef76a6 | |||
| e6c9959381 | |||
| 9db00516c3 | |||
| 44e225c273 | |||
| 99e75ba325 | |||
| 3a078271ff | |||
| 1f9991eeda | |||
| bfe72668dc | |||
| 51d95c81c1 | |||
| 6c39cd1ae1 | |||
| 5d36f1188a | |||
| 4c42949516 | |||
| 8922524f44 | |||
| eac367c611 | |||
| f02acd7f94 | |||
| 05ddfb3de3 | |||
| 5c2c89ca45 | |||
| ec1ce4adef | |||
| 71f1f972c9 | |||
| 23757bc841 | |||
| 9671090385 | |||
| a03ddf3fc2 | |||
| da3538a836 | |||
| c782c11b6d | |||
| 05a2ea9b18 | |||
| a482c72a56 | |||
| 22bdf13835 | |||
| 0a3affc5d0 | |||
| d642322985 | |||
| 9f63a9c6dd | |||
| 11a4874bfb | |||
| d4dd55944a | |||
| 23d6216029 | |||
| f7297ddf78 | |||
| eb3715d00b | |||
| aae6472e11 | |||
| a71e3e4720 | |||
| 189128f0d3 | |||
| 3fb951a748 | |||
| 2293849d94 | |||
| cd5b3b6523 | |||
| c8a2ed290b | |||
| 184d241695 | |||
| cab65477b0 | |||
| 3507623c92 | |||
| b99dd1bded | |||
| a0d38bec49 | |||
| f312a2d776 | |||
| bfb816dd17 | |||
| d6854d44b7 | |||
| fdbba1b89c | |||
| 7f197a0ea7 | |||
| 2c9569b75f | |||
| 607b7d8aee | |||
| 00db6ac10f | |||
| f034413e35 | |||
| ff16eae477 | |||
| dbd82930d4 | |||
| 2e9cf0bd97 | |||
| 8a2edc7228 | |||
| 6d14ba9d79 | |||
| ba5f83f3d0 | |||
| 9f614e8a31 | |||
| 6e0d4a5144 | |||
| bd8bd40863 | |||
| c7a1069c0c | |||
| dc0c6ca6a0 | |||
| 9201cbf357 | 
							
								
								
									
										100
									
								
								kdb-bot/.cpl/schematic_db_table.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								kdb-bot/.cpl/schematic_db_table.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,100 @@ | ||||
| from cpl_cli.abc.generate_schematic_abc import GenerateSchematicABC | ||||
|  | ||||
|  | ||||
| class DBTable(GenerateSchematicABC): | ||||
|     def __init__(self, *args: str): | ||||
|         GenerateSchematicABC.__init__(self, *args) | ||||
|         self._name = self._name.replace("_db_table", "") | ||||
|         self._class_name = self._class_name.split("Db_table")[0] | ||||
|  | ||||
|     def get_code(self) -> str: | ||||
|         import textwrap | ||||
|  | ||||
|         code = textwrap.dedent( | ||||
|             """\ | ||||
|                 from datetime import datetime | ||||
|  | ||||
|                 from cpl_core.database import TableABC | ||||
|                  | ||||
|                  | ||||
|                 class $ClassName(TableABC): | ||||
|                     def __init__( | ||||
|                         self, | ||||
|                         value: str, | ||||
|                         created_at: datetime = None, | ||||
|                         modified_at: datetime = None, | ||||
|                         id=0, | ||||
|                     ): | ||||
|                         self._id = id | ||||
|                         self._value = value | ||||
|                  | ||||
|                         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 value(self) -> str: | ||||
|                         return self._value | ||||
|                  | ||||
|                     @value.setter | ||||
|                     def value(self, value: str): | ||||
|                         self._value = value | ||||
|                  | ||||
|                     @staticmethod | ||||
|                     def get_select_all_string() -> str: | ||||
|                         return str( | ||||
|                             f\""" | ||||
|                                 SELECT * FROM `$TableName`; | ||||
|                             \""" | ||||
|                         ) | ||||
|                  | ||||
|                     @staticmethod | ||||
|                     def get_select_by_id_string(id: int) -> str: | ||||
|                         return str( | ||||
|                             f\""" | ||||
|                                 SELECT * FROM `$TableName` | ||||
|                                 WHERE `Id` = {id}; | ||||
|                             \""" | ||||
|                         ) | ||||
|                  | ||||
|                     @property | ||||
|                     def insert_string(self) -> str: | ||||
|                         return str( | ||||
|                             f\""" | ||||
|                                 INSERT INTO `$TableName` ( | ||||
|                                     `Value` | ||||
|                                 ) VALUES ( | ||||
|                                     {self._value} | ||||
|                                 ); | ||||
|                             \""" | ||||
|                         ) | ||||
|                  | ||||
|                     @property | ||||
|                     def udpate_string(self) -> str: | ||||
|                         return str( | ||||
|                             f\""" | ||||
|                                 UPDATE `$TableName` | ||||
|                                 SET `Value` = {self._value} | ||||
|                                 WHERE `Id` = {self._id}; | ||||
|                             \""" | ||||
|                         ) | ||||
|                  | ||||
|                     @property | ||||
|                     def delete_string(self) -> str: | ||||
|                         return str( | ||||
|                             f\""" | ||||
|                                 DELETE FROM `$TableName` | ||||
|                                 WHERE `Id` = {self._id}; | ||||
|                             \""" | ||||
|                         ) | ||||
|             """ | ||||
|         ) | ||||
|         return self.build_code_str( | ||||
|             code, | ||||
|             ClassName=self._class_name, | ||||
|             TableName=self._class_name, | ||||
|         ) | ||||
|  | ||||
|     @classmethod | ||||
|     def register(cls): | ||||
|         GenerateSchematicABC.register(cls, "db-table", []) | ||||
							
								
								
									
										55
									
								
								kdb-bot/.cpl/schematic_migration.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								kdb-bot/.cpl/schematic_migration.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| from cpl_cli.abc.generate_schematic_abc import GenerateSchematicABC | ||||
|  | ||||
|  | ||||
| class Migration(GenerateSchematicABC): | ||||
|     def __init__(self, *args: str): | ||||
|         GenerateSchematicABC.__init__(self, *args) | ||||
|  | ||||
|     def get_code(self) -> str: | ||||
|         import textwrap | ||||
|  | ||||
|         code = textwrap.dedent( | ||||
|             """\ | ||||
|                 from bot_core.logging.database_logger import DatabaseLogger | ||||
|                 from bot_data.abc.migration_abc import MigrationABC | ||||
|                 from bot_data.db_context import DBContext | ||||
|                  | ||||
|                  | ||||
|                 class $ClassName(MigrationABC): | ||||
|                     name = "1.0_$ClassName" | ||||
|                  | ||||
|                     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 `$TableName` ( | ||||
|                                         `Id` BIGINT NOT NULL AUTO_INCREMENT, | ||||
|                                         `CreatedAt` DATETIME(6), | ||||
|                                         `LastModifiedAt` DATETIME(6), | ||||
|                                         PRIMARY KEY(`Id`) | ||||
|                                     ); | ||||
|                                 \""" | ||||
|                             ) | ||||
|                         ) | ||||
|                  | ||||
|                     def downgrade(self): | ||||
|                         self._cursor.execute("DROP TABLE `$TableName`;") | ||||
|             """ | ||||
|         ) | ||||
|         return self.build_code_str( | ||||
|             code, | ||||
|             ClassName=self._class_name, | ||||
|             TableName=self._class_name.split("Migration")[0], | ||||
|         ) | ||||
|  | ||||
|     @classmethod | ||||
|     def register(cls): | ||||
|         GenerateSchematicABC.register(cls, "migration", []) | ||||
| @@ -1,7 +1,7 @@ | ||||
| from cpl_cli.abc.generate_schematic_abc import GenerateSchematicABC | ||||
|  | ||||
|  | ||||
| class query(GenerateSchematicABC): | ||||
| class Query(GenerateSchematicABC): | ||||
|     def __init__(self, *args: str): | ||||
|         GenerateSchematicABC.__init__(self, *args) | ||||
|  | ||||
|   | ||||
| @@ -7,9 +7,11 @@ | ||||
|       "bot-core": "src/bot_core/bot-core.json", | ||||
|       "bot-data": "src/bot_data/bot-data.json", | ||||
|       "bot-graphql": "src/bot_graphql/bot-graphql.json", | ||||
|       "achievements": "src/modules/achievements/achievements.json", | ||||
|       "auto-role": "src/modules/auto_role/auto-role.json", | ||||
|       "base": "src/modules/base/base.json", | ||||
|       "boot-log": "src/modules/boot_log/boot-log.json", | ||||
|       "config": "src/modules/config/config.json", | ||||
|       "database": "src/modules/database/database.json", | ||||
|       "level": "src/modules/level/level.json", | ||||
|       "permission": "src/modules/permission/permission.json", | ||||
| @@ -21,25 +23,18 @@ | ||||
|     }, | ||||
|     "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; 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;", | ||||
|  | ||||
|       "pre-stage": "cpl build", | ||||
|       "stage": "export KDB_ENVIRONMENT=staging; export KDB_NAME=KDB-Stage; cpl start;", | ||||
|  | ||||
|       "pre-dev": "cpl build", | ||||
|       "dev": "export KDB_ENVIRONMENT=development; export KDB_NAME=KDB-Dev; cpl start;", | ||||
|  | ||||
|       "docker-build": "cpl build $ARGS; docker build -t kdb-bot/kdb-bot:$(cpl gv) .;", | ||||
|       "dc-up": "docker-compose up -d", | ||||
|       "dc-down": "docker-compose down", | ||||
|   | ||||
 Submodule kdb-bot/docker updated: 62475d6546...7ae4783874
									
								
							| @@ -15,7 +15,7 @@ __title__ = "bot" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.0.7" | ||||
| __version__ = "1.1.5" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="0", micro="7") | ||||
| version_info = VersionInfo(major="1", minor="1", micro="5") | ||||
|   | ||||
| @@ -10,6 +10,7 @@ from cpl_translation import TranslatePipe, TranslationServiceABC, TranslationSet | ||||
| from bot_api.api_thread import ApiThread | ||||
| from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum | ||||
| from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings | ||||
| from bot_core.service.data_integrity_service import DataIntegrityService | ||||
|  | ||||
|  | ||||
| class Application(DiscordBotApplicationABC): | ||||
| @@ -21,6 +22,7 @@ class Application(DiscordBotApplicationABC): | ||||
|  | ||||
|         # cpl-core | ||||
|         self._logger: LoggerABC = services.get_service(LoggerABC) | ||||
|         self._data_integrity: DataIntegrityService = services.get_service(DataIntegrityService) | ||||
|         # cpl-discord | ||||
|         self._bot: DiscordBotServiceABC = services.get_service(DiscordBotServiceABC) | ||||
|         self._bot_settings: DiscordBotSettings = config.get_configuration(DiscordBotSettings) | ||||
| @@ -69,6 +71,7 @@ class Application(DiscordBotApplicationABC): | ||||
|                 self._api.stop() | ||||
|  | ||||
|             await self._bot.close() | ||||
|             await self._data_integrity.check_data_integrity(is_for_shutdown=True) | ||||
|             self._logger.info(__name__, f"Stopped {DiscordBotService.__name__}") | ||||
|         except Exception as e: | ||||
|             self._logger.error(__name__, "stop failed", e) | ||||
| @@ -76,4 +79,4 @@ class Application(DiscordBotApplicationABC): | ||||
|         Console.write_line() | ||||
|  | ||||
|     def is_restart(self): | ||||
|         return True if self._configuration.get_configuration("IS_RESTART") == "true" else False  # | ||||
|         return True if self._configuration.get_configuration("IS_RESTART") == "true" else False | ||||
|   | ||||
| @@ -3,8 +3,8 @@ | ||||
|     "Name": "bot", | ||||
|     "Version": { | ||||
|       "Major": "1", | ||||
|       "Minor": "0", | ||||
|       "Micro": "7" | ||||
|       "Minor": "1", | ||||
|       "Micro": "5" | ||||
|     }, | ||||
|     "Author": "Sven Heidemann", | ||||
|     "AuthorEmail": "sven.heidemann@sh-edraft.de", | ||||
| @@ -16,24 +16,26 @@ | ||||
|     "LicenseName": "MIT", | ||||
|     "LicenseDescription": "MIT, see LICENSE for more details.", | ||||
|     "Dependencies": [ | ||||
|       "cpl-core==2022.12.1.post3", | ||||
|       "cpl-translation==2022.12.1", | ||||
|       "cpl-query==2022.12.2.post2", | ||||
|       "cpl-discord==2022.12.2.post1", | ||||
|       "Flask==2.2.2", | ||||
|       "cpl-core==2023.4.0.post5", | ||||
|       "cpl-translation==2023.4.0.post1", | ||||
|       "cpl-query==2023.4.0.post1", | ||||
|       "cpl-discord==2023.4.0.post3", | ||||
|       "Flask==2.3.2", | ||||
|       "Flask-Classful==0.14.2", | ||||
|       "Flask-Cors==3.0.10", | ||||
|       "PyJWT==2.6.0", | ||||
|       "Flask-Cors==4.0.0", | ||||
|       "PyJWT==2.8.0", | ||||
|       "waitress==2.1.2", | ||||
|       "Flask-SocketIO==5.3.2", | ||||
|       "Flask-SocketIO==5.3.4", | ||||
|       "eventlet==0.33.3", | ||||
|       "requests-oauthlib==1.3.1", | ||||
|       "icmplib==3.0.3", | ||||
|       "ariadne==0.17.1" | ||||
|       "ariadne==0.20.1", | ||||
|       "cryptography==41.0.2", | ||||
|       "discord>=2.3.2" | ||||
|     ], | ||||
|     "DevDependencies": [ | ||||
|       "cpl-cli==2022.12.1.post3", | ||||
|       "pygount==1.5.1" | ||||
|       "cpl-cli==2023.4.0.post3", | ||||
|       "pygount==1.6.1" | ||||
|     ], | ||||
|     "PythonVersion": ">=3.10.4", | ||||
|     "PythonPath": {}, | ||||
| @@ -58,9 +60,11 @@ | ||||
|       "../bot_core/bot-core.json", | ||||
|       "../bot_data/bot-data.json", | ||||
|       "../bot_graphql/bot-graphql.json", | ||||
|       "../modules/achievements/achievements.json", | ||||
|       "../modules/auto_role/auto-role.json", | ||||
|       "../modules/base/base.json", | ||||
|       "../modules/boot_log/boot-log.json", | ||||
|       "../modules/config/config.json", | ||||
|       "../modules/database/database.json", | ||||
|       "../modules/level/level.json", | ||||
|       "../modules/permission/permission.json", | ||||
|   | ||||
 Submodule kdb-bot/src/bot/config updated: 0c94637537...23eafb2e21
									
								
							| @@ -15,7 +15,7 @@ __title__ = "bot.extension" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.0.7" | ||||
| __version__ = "1.1.5" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="0", micro="7") | ||||
| version_info = VersionInfo(major="1", minor="1", micro="5") | ||||
|   | ||||
| @@ -3,7 +3,7 @@ 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 | ||||
| from bot_data.model.technician_config import TechnicianConfig | ||||
|  | ||||
|  | ||||
| class InitBotExtension(ApplicationExtensionABC): | ||||
| @@ -11,6 +11,6 @@ class InitBotExtension(ApplicationExtensionABC): | ||||
|         ApplicationExtensionABC.__init__(self) | ||||
|  | ||||
|     async def run(self, config: ConfigurationABC, services: ServiceProviderABC): | ||||
|         settings = config.get_configuration(BotSettings) | ||||
|         settings = config.get_configuration(TechnicianConfig) | ||||
|  | ||||
|         bot: DiscordBotServiceABC = services.get_service(DiscordBotServiceABC, max_messages=settings.cache_max_messages) | ||||
|   | ||||
| @@ -15,6 +15,7 @@ from bot.startup_settings_extension import StartupSettingsExtension | ||||
| from bot_api.app_api_extension import AppApiExtension | ||||
| from bot_core.core_extension.core_extension import CoreExtension | ||||
| from modules.boot_log.boot_log_extension import BootLogExtension | ||||
| from modules.config.config_extension import ConfigExtension | ||||
| from modules.database.database_extension import DatabaseExtension | ||||
|  | ||||
|  | ||||
| @@ -30,9 +31,10 @@ class Program: | ||||
|             .use_extension(StartupDiscordExtension) | ||||
|             .use_extension(StartupModuleExtension) | ||||
|             .use_extension(StartupMigrationExtension) | ||||
|             .use_extension(DatabaseExtension) | ||||
|             .use_extension(ConfigExtension) | ||||
|             .use_extension(InitBotExtension) | ||||
|             .use_extension(BootLogExtension) | ||||
|             .use_extension(DatabaseExtension) | ||||
|             .use_extension(AppApiExtension) | ||||
|             .use_extension(CoreExtension) | ||||
|             .use_startup(Startup) | ||||
|   | ||||
| @@ -5,9 +5,11 @@ from bot_core.core_extension.core_extension_module import CoreExtensionModule | ||||
| from bot_core.core_module import CoreModule | ||||
| from bot_data.data_module import DataModule | ||||
| from bot_graphql.graphql_module import GraphQLModule | ||||
| from modules.achievements.achievements_module import AchievementsModule | ||||
| from modules.auto_role.auto_role_module import AutoRoleModule | ||||
| from modules.base.base_module import BaseModule | ||||
| from modules.boot_log.boot_log_module import BootLogModule | ||||
| from modules.config.config_module import ConfigModule | ||||
| from modules.database.database_module import DatabaseModule | ||||
| from modules.level.level_module import LevelModule | ||||
| from modules.permission.permission_module import PermissionModule | ||||
| @@ -23,14 +25,16 @@ class ModuleList: | ||||
|             [ | ||||
|                 CoreModule,  # has to be first! | ||||
|                 DataModule, | ||||
|                 ConfigModule,  # has to be before db check | ||||
|                 DatabaseModule, | ||||
|                 GraphQLModule, | ||||
|                 PermissionModule, | ||||
|                 DatabaseModule, | ||||
|                 AutoRoleModule, | ||||
|                 BaseModule, | ||||
|                 LevelModule, | ||||
|                 ApiModule, | ||||
|                 TechnicianModule, | ||||
|                 AchievementsModule, | ||||
|                 # has to be last! | ||||
|                 BootLogModule, | ||||
|                 CoreExtensionModule, | ||||
|   | ||||
| @@ -4,11 +4,15 @@ from cpl_core.dependency_injection import ServiceCollectionABC | ||||
| from cpl_core.environment import ApplicationEnvironmentABC | ||||
|  | ||||
| from bot_data.abc.migration_abc import MigrationABC | ||||
| from bot_data.migration.achievements_migration import AchievementsMigration | ||||
| from bot_data.migration.api_key_migration import ApiKeyMigration | ||||
| from bot_data.migration.api_migration import ApiMigration | ||||
| from bot_data.migration.auto_role_fix1_migration import AutoRoleFix1Migration | ||||
| from bot_data.migration.auto_role_migration import AutoRoleMigration | ||||
| from bot_data.migration.config_feature_flags_migration import ConfigFeatureFlagsMigration | ||||
| from bot_data.migration.config_migration import ConfigMigration | ||||
| from bot_data.migration.db_history_migration import DBHistoryMigration | ||||
| from bot_data.migration.default_role_migration import DefaultRoleMigration | ||||
| from bot_data.migration.initial_migration import InitialMigration | ||||
| from bot_data.migration.level_migration import LevelMigration | ||||
| from bot_data.migration.remove_stats_migration import RemoveStatsMigration | ||||
| @@ -42,3 +46,7 @@ class StartupMigrationExtension(StartupExtensionABC): | ||||
|         services.add_transient(MigrationABC, RemoveStatsMigration)  # 19.02.2023 #190 - 1.0.0 | ||||
|         services.add_transient(MigrationABC, UserWarningMigration)  # 21.02.2023 #35 - 1.0.0 | ||||
|         services.add_transient(MigrationABC, DBHistoryMigration)  # 06.03.2023 #246 - 1.0.0 | ||||
|         services.add_transient(MigrationABC, AchievementsMigration)  # 14.06.2023 #268 - 1.1.0 | ||||
|         services.add_transient(MigrationABC, ConfigMigration)  # 19.07.2023 #127 - 1.1.0 | ||||
|         services.add_transient(MigrationABC, ConfigFeatureFlagsMigration)  # 15.08.2023 #334 - 1.1.0 | ||||
|         services.add_transient(MigrationABC, DefaultRoleMigration)  # 24.09.2023 #360 - 1.1.3 | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| import os | ||||
| from datetime import datetime | ||||
| from typing import Callable, Type, Optional | ||||
| from typing import Optional, Type, Callable | ||||
|  | ||||
| from cpl_core.application import StartupExtensionABC | ||||
| from cpl_core.configuration import ConfigurationABC | ||||
| @@ -8,11 +8,6 @@ from cpl_core.dependency_injection import ServiceCollectionABC | ||||
| from cpl_core.environment import ApplicationEnvironmentABC | ||||
|  | ||||
| from bot_core.configuration.bot_logging_settings import BotLoggingSettings | ||||
| from bot_core.configuration.bot_settings import BotSettings | ||||
| from modules.base.configuration.base_settings import BaseSettings | ||||
| from modules.boot_log.configuration.boot_log_settings import BootLogSettings | ||||
| from modules.level.configuration.level_settings import LevelSettings | ||||
| from modules.permission.configuration.permission_settings import PermissionSettings | ||||
|  | ||||
|  | ||||
| class StartupSettingsExtension(StartupExtensionABC): | ||||
| @@ -34,13 +29,6 @@ class StartupSettingsExtension(StartupExtensionABC): | ||||
|         configuration.add_json_file(f"config/feature-flags.{environment.host_name}.json", optional=True) | ||||
|  | ||||
|         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 | ||||
|         ) | ||||
| @@ -50,9 +38,9 @@ class StartupSettingsExtension(StartupExtensionABC): | ||||
|  | ||||
|     @staticmethod | ||||
|     def _configure_settings_with_sub_settings( | ||||
|         config: ConfigurationABC, settings: Type, list_atr: Callable, atr: Callable | ||||
|         config: ConfigurationABC, settings_type: Type, list_atr: Callable, atr: Callable | ||||
|     ): | ||||
|         settings: Optional[settings] = config.get_configuration(settings) | ||||
|         settings: Optional[settings_type] = config.get_configuration(settings_type) | ||||
|         if settings is None: | ||||
|             return | ||||
|  | ||||
|   | ||||
| @@ -93,6 +93,12 @@ | ||||
|     } | ||||
|   }, | ||||
|   "modules": { | ||||
|     "achievements": { | ||||
|       "got_new_achievement": "{} hat die Errungenschaft {} freigeschaltet :D", | ||||
|       "commands": { | ||||
|         "check": "Alles klar, ich schaue eben nach... nom nom" | ||||
|       } | ||||
|     }, | ||||
|     "auto_role": { | ||||
|       "add": { | ||||
|         "error": { | ||||
| @@ -145,6 +151,19 @@ | ||||
|       } | ||||
|     }, | ||||
|     "base": { | ||||
|       "member_left_message": "{} hat uns leider verlassen :(", | ||||
|       "complaints": { | ||||
|         "title": "Beschwerde einreichen", | ||||
|         "label": "Beschwerde", | ||||
|         "message": "{} hat eine Beschwerde eingereicht:\n{}", | ||||
|         "response": "Danke für deine Beschwerde" | ||||
|       }, | ||||
|       "bug": { | ||||
|         "title": "Bug melden", | ||||
|         "label": "Bug", | ||||
|         "message": "{} meldet einen Bug:\n{}", | ||||
|         "response": "Danke für dein Feedback :D" | ||||
|       }, | ||||
|       "afk_command_channel_missing_message": "Zu unfähig einem Sprachkanal beizutreten?", | ||||
|       "afk_command_move_message": "Ich verschiebe dich ja schon... (◔_◔)", | ||||
|       "game_server": { | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.0.7" | ||||
| __version__ = "1.1.5" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="0", micro="7") | ||||
| version_info = VersionInfo(major="1", minor="1", micro="5") | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api.abc" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.0.7" | ||||
| __version__ = "1.1.5" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="0", micro="7") | ||||
| version_info = VersionInfo(major="1", minor="1", micro="5") | ||||
|   | ||||
| @@ -3,8 +3,8 @@ | ||||
|     "Name": "bot-api", | ||||
|     "Version": { | ||||
|       "Major": "1", | ||||
|       "Minor": "0", | ||||
|       "Micro": "7" | ||||
|       "Minor": "1", | ||||
|       "Micro": "5" | ||||
|     }, | ||||
|     "Author": "", | ||||
|     "AuthorEmail": "", | ||||
|   | ||||
 Submodule kdb-bot/src/bot_api/config updated: c712f856eb...b6ffed4da1
									
								
							| @@ -15,7 +15,7 @@ __title__ = "bot_api.configuration" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.0.7" | ||||
| __version__ = "1.1.5" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="0", micro="7") | ||||
| version_info = VersionInfo(major="1", minor="1", micro="5") | ||||
|   | ||||
| @@ -1,16 +1,13 @@ | ||||
| import traceback | ||||
|  | ||||
| from cpl_core.configuration.configuration_model_abc import ConfigurationModelABC | ||||
| from cpl_core.console import Console | ||||
|  | ||||
|  | ||||
| class ApiSettings(ConfigurationModelABC): | ||||
|     def __init__(self): | ||||
|     def __init__(self, port: int = None, host: str = None, redirect_uri: bool = None): | ||||
|         ConfigurationModelABC.__init__(self) | ||||
|  | ||||
|         self._port = 80 | ||||
|         self._host = "" | ||||
|         self._redirect_to_https = False | ||||
|         self._port = 80 if port is None else port | ||||
|         self._host = "" if host is None else host | ||||
|         self._redirect_to_https = False if redirect_uri is None else redirect_uri | ||||
|  | ||||
|     @property | ||||
|     def port(self) -> int: | ||||
| @@ -23,12 +20,3 @@ class ApiSettings(ConfigurationModelABC): | ||||
|     @property | ||||
|     def redirect_to_https(self) -> bool: | ||||
|         return self._redirect_to_https | ||||
|  | ||||
|     def from_dict(self, settings: dict): | ||||
|         try: | ||||
|             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()}") | ||||
|   | ||||
| @@ -1,19 +1,22 @@ | ||||
| import traceback | ||||
| from datetime import datetime | ||||
|  | ||||
| from cpl_core.configuration.configuration_model_abc import ConfigurationModelABC | ||||
| from cpl_core.console import Console | ||||
|  | ||||
|  | ||||
| class AuthenticationSettings(ConfigurationModelABC): | ||||
|     def __init__(self): | ||||
|     def __init__( | ||||
|         self, | ||||
|         secret_key: str = None, | ||||
|         issuer: str = None, | ||||
|         audience: str = None, | ||||
|         token_expire_time: int = None, | ||||
|         refresh_token_expire_time: int = None, | ||||
|     ): | ||||
|         ConfigurationModelABC.__init__(self) | ||||
|  | ||||
|         self._secret_key = "" | ||||
|         self._issuer = "" | ||||
|         self._audience = "" | ||||
|         self._token_expire_time = 0 | ||||
|         self._refresh_token_expire_time = 0 | ||||
|         self._secret_key = "" if secret_key is None else secret_key | ||||
|         self._issuer = "" if issuer is None else issuer | ||||
|         self._audience = "" if audience is None else audience | ||||
|         self._token_expire_time = 0 if token_expire_time is None else token_expire_time | ||||
|         self._refresh_token_expire_time = 0 if refresh_token_expire_time is None else refresh_token_expire_time | ||||
|  | ||||
|     @property | ||||
|     def secret_key(self) -> str: | ||||
| @@ -34,14 +37,3 @@ class AuthenticationSettings(ConfigurationModelABC): | ||||
|     @property | ||||
|     def refresh_token_expire_time(self) -> int: | ||||
|         return self._refresh_token_expire_time | ||||
|  | ||||
|     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"]) | ||||
|         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()}") | ||||
|   | ||||
| @@ -1,19 +1,23 @@ | ||||
| import traceback | ||||
|  | ||||
| from cpl_core.configuration.configuration_model_abc import ConfigurationModelABC | ||||
| from cpl_core.console import Console | ||||
| from cpl_query.extension import List | ||||
|  | ||||
|  | ||||
| class DiscordAuthenticationSettings(ConfigurationModelABC): | ||||
|     def __init__(self): | ||||
|     def __init__( | ||||
|         self, | ||||
|         client_secret: str = None, | ||||
|         redirect_uri: str = None, | ||||
|         scope: list = None, | ||||
|         token_url: str = None, | ||||
|         auth_url: str = None, | ||||
|     ): | ||||
|         ConfigurationModelABC.__init__(self) | ||||
|  | ||||
|         self._client_secret = "" | ||||
|         self._redirect_url = "" | ||||
|         self._scope = List() | ||||
|         self._token_url = "" | ||||
|         self._auth_url = "" | ||||
|         self._client_secret = "" if client_secret is None else client_secret | ||||
|         self._redirect_url = "" if redirect_uri is None else redirect_uri | ||||
|         self._scope = List() if scope is None else List(str, scope) | ||||
|         self._token_url = "" if token_url is None else token_url | ||||
|         self._auth_url = "" if auth_url is None else auth_url | ||||
|  | ||||
|     @property | ||||
|     def client_secret(self) -> str: | ||||
| @@ -34,14 +38,3 @@ class DiscordAuthenticationSettings(ConfigurationModelABC): | ||||
|     @property | ||||
|     def auth_url(self) -> str: | ||||
|         return self._auth_url | ||||
|  | ||||
|     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"] | ||||
|         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()}") | ||||
|   | ||||
| @@ -1,22 +1,12 @@ | ||||
| import traceback | ||||
|  | ||||
| from cpl_core.configuration.configuration_model_abc import ConfigurationModelABC | ||||
| from cpl_core.console import Console | ||||
|  | ||||
|  | ||||
| class FrontendSettings(ConfigurationModelABC): | ||||
|     def __init__(self): | ||||
|     def __init__(self, url: str = None): | ||||
|         ConfigurationModelABC.__init__(self) | ||||
|  | ||||
|         self._url = "" | ||||
|         self._url = "" if url is None else url | ||||
|  | ||||
|     @property | ||||
|     def url(self) -> str: | ||||
|         return self._url | ||||
|  | ||||
|     def from_dict(self, settings: dict): | ||||
|         try: | ||||
|             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()}") | ||||
|   | ||||
| @@ -1,49 +0,0 @@ | ||||
| from typing import Optional | ||||
|  | ||||
| from cpl_core.configuration.configuration_model_abc import ConfigurationModelABC | ||||
| from cpl_cli.configuration.version_settings_name_enum import VersionSettingsNameEnum | ||||
|  | ||||
|  | ||||
| class VersionSettings(ConfigurationModelABC): | ||||
|     def __init__(self, major: str = None, minor: str = None, micro: str = None): | ||||
|         ConfigurationModelABC.__init__(self) | ||||
|  | ||||
|         self._major: Optional[str] = major | ||||
|         self._minor: Optional[str] = minor | ||||
|         self._micro: Optional[str] = micro | ||||
|  | ||||
|     @property | ||||
|     def major(self) -> str: | ||||
|         return self._major | ||||
|  | ||||
|     @property | ||||
|     def minor(self) -> str: | ||||
|         return self._minor | ||||
|  | ||||
|     @property | ||||
|     def micro(self) -> str: | ||||
|         return self._micro | ||||
|  | ||||
|     def to_str(self) -> str: | ||||
|         if self._micro is None: | ||||
|             return f"{self._major}.{self._minor}" | ||||
|         else: | ||||
|             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 != "": | ||||
|             self._micro = micro | ||||
|  | ||||
|     def to_dict(self) -> dict: | ||||
|         version = { | ||||
|             VersionSettingsNameEnum.major.value: self._major, | ||||
|             VersionSettingsNameEnum.minor.value: self._minor, | ||||
|         } | ||||
|  | ||||
|         if self._micro is not None: | ||||
|             version[VersionSettingsNameEnum.micro.value] = self._micro | ||||
|  | ||||
|         return version | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api.controller" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.0.7" | ||||
| __version__ = "1.1.5" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="0", micro="7") | ||||
| version_info = VersionInfo(major="1", minor="1", micro="5") | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| from ariadne import graphql_sync | ||||
| from ariadne.constants import PLAYGROUND_HTML | ||||
| from ariadne.explorer import ExplorerPlayground | ||||
| from cpl_core.configuration import ConfigurationABC | ||||
| from cpl_core.environment import ApplicationEnvironmentABC | ||||
| from flask import request, jsonify | ||||
| @@ -30,7 +30,7 @@ class GraphQLController: | ||||
|         if self._env.environment_name != "development": | ||||
|             return "", 403 | ||||
|  | ||||
|         return PLAYGROUND_HTML, 200 | ||||
|         return ExplorerPlayground().html(None), 200 | ||||
|  | ||||
|     @Route.post(f"{BasePath}") | ||||
|     @Route.authorize(by_api_key=True) | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api.event" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.0.7" | ||||
| __version__ = "1.1.5" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="0", micro="7") | ||||
| version_info = VersionInfo(major="1", minor="1", micro="5") | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api.exception" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.0.7" | ||||
| __version__ = "1.1.5" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="0", micro="7") | ||||
| version_info = VersionInfo(major="1", minor="1", micro="5") | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api.filter" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.0.7" | ||||
| __version__ = "1.1.5" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="0", micro="7") | ||||
| version_info = VersionInfo(major="1", minor="1", micro="5") | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api.filter.discord" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.0.7" | ||||
| __version__ = "1.1.5" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="0", micro="7") | ||||
| version_info = VersionInfo(major="1", minor="1", micro="5") | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api.logging" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.0.7" | ||||
| __version__ = "1.1.5" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="0", micro="7") | ||||
| version_info = VersionInfo(major="1", minor="1", micro="5") | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api.model" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.0.7" | ||||
| __version__ = "1.1.5" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="0", micro="7") | ||||
| version_info = VersionInfo(major="1", minor="1", micro="5") | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api.model.discord" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.0.7" | ||||
| __version__ = "1.1.5" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="0", micro="7") | ||||
| version_info = VersionInfo(major="1", minor="1", micro="5") | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api.route" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.0.7" | ||||
| __version__ = "1.1.5" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="0", micro="7") | ||||
| version_info = VersionInfo(major="1", minor="1", micro="5") | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api.service" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.0.7" | ||||
| __version__ = "1.1.5" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="0", micro="7") | ||||
| version_info = VersionInfo(major="1", minor="1", micro="5") | ||||
|   | ||||
| @@ -494,8 +494,13 @@ class AuthService(AuthServiceABC): | ||||
|             added_user = True | ||||
|  | ||||
|         db_user = self._auth_users.get_auth_user_by_email(user_dto.email) | ||||
|         if db_user.users.count() == 0: | ||||
|             members.for_each(lambda x: self._auth_users.add_auth_user_user_rel(AuthUserUsersRelation(db_user, x))) | ||||
|         user_ids = db_user.users.select(lambda x: x.id) | ||||
|  | ||||
|         for user in self._users.get_users_by_discord_id(dc_id): | ||||
|             if user.id in user_ids: | ||||
|                 continue | ||||
|  | ||||
|             self._auth_users.add_auth_user_user_rel(AuthUserUsersRelation(db_user, user)) | ||||
|  | ||||
|         if db_user.confirmation_id is not None and not added_user: | ||||
|             raise ServiceException(ServiceErrorCode.Forbidden, "E-Mail not verified") | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api.transformer" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.0.7" | ||||
| __version__ = "1.1.5" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="0", micro="7") | ||||
| version_info = VersionInfo(major="1", minor="1", micro="5") | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_core" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.0.7" | ||||
| __version__ = "1.1.5" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="0", micro="7") | ||||
| version_info = VersionInfo(major="1", minor="1", micro="5") | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_core.abc" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.0.7" | ||||
| __version__ = "1.1.5" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="0", micro="7") | ||||
| version_info = VersionInfo(major="1", minor="1", micro="5") | ||||
|   | ||||
| @@ -1,14 +1,14 @@ | ||||
| from abc import ABC, abstractmethod | ||||
| from datetime import datetime | ||||
| from typing import Callable | ||||
| from typing import Callable, Union | ||||
|  | ||||
| import discord | ||||
| from cpl_query.extension import List | ||||
| from discord.ext.commands import Context | ||||
|  | ||||
| from bot_data.model.auto_role_rule import AutoRoleRule | ||||
| from bot_data.model.server_config import ServerConfig | ||||
| from bot_data.model.user import User | ||||
| from modules.base.configuration.base_server_settings import BaseServerSettings | ||||
|  | ||||
|  | ||||
| class ClientUtilsABC(ABC): | ||||
| @@ -53,7 +53,7 @@ class ClientUtilsABC(ABC): | ||||
|         self, | ||||
|         created_at: datetime, | ||||
|         user: User, | ||||
|         settings: BaseServerSettings, | ||||
|         settings: ServerConfig, | ||||
|         is_reaction: bool = False, | ||||
|     ) -> bool: | ||||
|         pass | ||||
| @@ -67,3 +67,7 @@ class ClientUtilsABC(ABC): | ||||
|         self, discord_channel_id: int, discord_message_id: int, rule: AutoRoleRule, guild: discord.Guild | ||||
|     ): | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     async def check_default_role(self, member: Union[discord.User, discord.Member]): | ||||
|         pass | ||||
|   | ||||
| @@ -3,8 +3,8 @@ | ||||
|     "Name": "bot-core", | ||||
|     "Version": { | ||||
|       "Major": "1", | ||||
|       "Minor": "0", | ||||
|       "Micro": "7" | ||||
|       "Minor": "1", | ||||
|       "Micro": "5" | ||||
|     }, | ||||
|     "Author": "Sven Heidemann", | ||||
|     "AuthorEmail": "sven.heidemann@sh-edraft.de", | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_core.configuration" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.0.7" | ||||
| __version__ = "1.1.5" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="0", micro="7") | ||||
| version_info = VersionInfo(major="1", minor="1", micro="5") | ||||
|   | ||||
| @@ -1,32 +1,25 @@ | ||||
| import traceback | ||||
|  | ||||
| from cpl_core.configuration.configuration_model_abc import ConfigurationModelABC | ||||
| from cpl_core.console import Console, ForegroundColorEnum | ||||
| from cpl_core.utils.json_processor import JSONProcessor | ||||
| from cpl_query.extension import List | ||||
|  | ||||
| from bot_core.configuration.file_logging_settings import FileLoggingSettings | ||||
|  | ||||
|  | ||||
| class BotLoggingSettings(ConfigurationModelABC): | ||||
|     def __init__(self): | ||||
|     def __init__(self, **kwargs: dict): | ||||
|         ConfigurationModelABC.__init__(self) | ||||
|         self._files: List[FileLoggingSettings] = List(FileLoggingSettings) | ||||
|  | ||||
|         if kwargs is not None: | ||||
|             self._files_from_dict(kwargs) | ||||
|  | ||||
|     @property | ||||
|     def files(self) -> List[FileLoggingSettings]: | ||||
|         return self._files | ||||
|  | ||||
|     def from_dict(self, settings: dict): | ||||
|         try: | ||||
|             files = List(FileLoggingSettings) | ||||
|             for s in settings: | ||||
|                 st = FileLoggingSettings() | ||||
|                 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.set_foreground_color(ForegroundColorEnum.default) | ||||
|     def _files_from_dict(self, settings: dict): | ||||
|         files = List(FileLoggingSettings) | ||||
|         for s in settings: | ||||
|             settings[s]["Key"] = s | ||||
|             files.append(JSONProcessor.process(FileLoggingSettings, settings[s])) | ||||
|         self._files = files | ||||
|   | ||||
| @@ -1,62 +0,0 @@ | ||||
| import traceback | ||||
|  | ||||
| from cpl_core.configuration import ConfigurationModelABC | ||||
| from cpl_core.console import Console | ||||
| from cpl_query.extension import List | ||||
|  | ||||
| from bot_core.configuration.server_settings import ServerSettings | ||||
|  | ||||
|  | ||||
| class BotSettings(ConfigurationModelABC): | ||||
|     def __init__(self): | ||||
|         ConfigurationModelABC.__init__(self) | ||||
|  | ||||
|         self._servers: List[ServerSettings] = List(ServerSettings) | ||||
|         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 | ||||
|  | ||||
|     @property | ||||
|     def technicians(self) -> List[int]: | ||||
|         return self._technicians | ||||
|  | ||||
|     @property | ||||
|     def wait_for_restart(self) -> int: | ||||
|         return self._wait_for_restart | ||||
|  | ||||
|     @property | ||||
|     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"] | ||||
|             self._wait_for_restart = settings["WaitForRestart"] | ||||
|             self._wait_for_shutdown = settings["WaitForShutdown"] | ||||
|             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() | ||||
|                 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()}") | ||||
| @@ -3,13 +3,14 @@ from enum import Enum | ||||
|  | ||||
| class FeatureFlagsEnum(Enum): | ||||
|     # modules | ||||
|     achievements_module = "AchievementsModule" | ||||
|     api_module = "ApiModule" | ||||
|     admin_module = "AdminModule" | ||||
|     auto_role_module = "AutoRoleModule" | ||||
|     base_module = "BaseModule" | ||||
|     boot_log_module = "BootLogModule" | ||||
|     core_module = "CoreModule" | ||||
|     core_extension_module = "CoreExtensionModule" | ||||
|     config_module = "ConfigModule" | ||||
|     data_module = "DataModule" | ||||
|     database_module = "DatabaseModule" | ||||
|     level_module = "LevelModule" | ||||
|   | ||||
| @@ -1,33 +1,48 @@ | ||||
| import traceback | ||||
|  | ||||
| from cpl_core.configuration.configuration_model_abc import ConfigurationModelABC | ||||
| from cpl_core.console import Console | ||||
|  | ||||
| from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum | ||||
|  | ||||
|  | ||||
| class FeatureFlagsSettings(ConfigurationModelABC): | ||||
|     def __init__(self): | ||||
|     _flags = { | ||||
|         # modules | ||||
|         FeatureFlagsEnum.achievements_module.value: False,  # 14.06.2023 #268 | ||||
|         FeatureFlagsEnum.api_module.value: False,  # 13.10.2022 #70 | ||||
|         FeatureFlagsEnum.auto_role_module.value: False,  # 03.10.2022 #54 | ||||
|         FeatureFlagsEnum.base_module.value: True,  # 02.10.2022 #48 | ||||
|         FeatureFlagsEnum.boot_log_module.value: True,  # 02.10.2022 #48 | ||||
|         FeatureFlagsEnum.core_module.value: True,  # 03.10.2022 #56 | ||||
|         FeatureFlagsEnum.core_extension_module.value: True,  # 03.10.2022 #56 | ||||
|         FeatureFlagsEnum.data_module.value: True,  # 03.10.2022 #56 | ||||
|         FeatureFlagsEnum.database_module.value: True,  # 02.10.2022 #48 | ||||
|         FeatureFlagsEnum.moderator_module.value: False,  # 02.10.2022 #48 | ||||
|         FeatureFlagsEnum.permission_module.value: True,  # 02.10.2022 #48 | ||||
|         FeatureFlagsEnum.config_module.value: True,  # 19.07.2023 #127 | ||||
|         # features | ||||
|         FeatureFlagsEnum.api_only.value: False,  # 13.10.2022 #70 | ||||
|         FeatureFlagsEnum.presence.value: True,  # 03.10.2022 #56 | ||||
|         FeatureFlagsEnum.version_in_presence.value: False,  # 21.03.2023 #253 | ||||
|     } | ||||
|  | ||||
|     def __init__(self, **kwargs: dict): | ||||
|         ConfigurationModelABC.__init__(self) | ||||
|  | ||||
|         self._flags = { | ||||
|             # modules | ||||
|             FeatureFlagsEnum.api_module.value: False,  # 13.10.2022 #70 | ||||
|             FeatureFlagsEnum.admin_module.value: False,  # 02.10.2022 #48 | ||||
|             FeatureFlagsEnum.auto_role_module.value: True,  # 03.10.2022 #54 | ||||
|             FeatureFlagsEnum.base_module.value: True,  # 02.10.2022 #48 | ||||
|             FeatureFlagsEnum.boot_log_module.value: True,  # 02.10.2022 #48 | ||||
|             FeatureFlagsEnum.core_module.value: True,  # 03.10.2022 #56 | ||||
|             FeatureFlagsEnum.core_extension_module.value: True,  # 03.10.2022 #56 | ||||
|             FeatureFlagsEnum.data_module.value: True,  # 03.10.2022 #56 | ||||
|             FeatureFlagsEnum.database_module.value: True,  # 02.10.2022 #48 | ||||
|             FeatureFlagsEnum.moderator_module.value: False,  # 02.10.2022 #48 | ||||
|             FeatureFlagsEnum.permission_module.value: True,  # 02.10.2022 #48 | ||||
|             # features | ||||
|             FeatureFlagsEnum.api_only.value: False,  # 13.10.2022 #70 | ||||
|             FeatureFlagsEnum.presence.value: True,  # 03.10.2022 #56 | ||||
|             FeatureFlagsEnum.version_in_presence.value: False,  # 21.03.2023 #253 | ||||
|         } | ||||
|         if len(kwargs.keys()) == 0: | ||||
|             return | ||||
|  | ||||
|         for flag in [f.value for f in FeatureFlagsEnum]: | ||||
|             self._load_flag(kwargs, FeatureFlagsEnum(flag)) | ||||
|  | ||||
|     @classmethod | ||||
|     def get_flag_from_dict(cls, flags: dict, key: FeatureFlagsEnum) -> bool: | ||||
|         def get_flag(): | ||||
|             if key.value not in cls._flags: | ||||
|                 return False | ||||
|             return cls._flags[key.value] | ||||
|  | ||||
|         if key.value not in flags: | ||||
|             return get_flag() | ||||
|         return flags[key.value] | ||||
|  | ||||
|     def get_flag(self, key: FeatureFlagsEnum) -> bool: | ||||
|         if key.value not in self._flags: | ||||
| @@ -39,11 +54,3 @@ class FeatureFlagsSettings(ConfigurationModelABC): | ||||
|             return | ||||
|  | ||||
|         self._flags[key.value] = bool(settings[key.value]) | ||||
|  | ||||
|     def from_dict(self, settings: dict): | ||||
|         try: | ||||
|             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()}") | ||||
|   | ||||
| @@ -1,23 +1,19 @@ | ||||
| import traceback | ||||
|  | ||||
| from cpl_core.console import Console | ||||
| from cpl_core.logging import LoggingSettings | ||||
| from cpl_core.logging import LoggingSettings, LoggingLevelEnum | ||||
|  | ||||
|  | ||||
| class FileLoggingSettings(LoggingSettings): | ||||
|     def __init__(self): | ||||
|         LoggingSettings.__init__(self) | ||||
|     def __init__( | ||||
|         self, | ||||
|         key: str, | ||||
|         path: str = None, | ||||
|         filename: str = None, | ||||
|         console_log_level: LoggingLevelEnum = None, | ||||
|         file_log_level: LoggingLevelEnum = None, | ||||
|     ): | ||||
|         LoggingSettings.__init__(self, path, filename, console_log_level, file_log_level) | ||||
|  | ||||
|         self._key = "" | ||||
|         self._key = key | ||||
|  | ||||
|     @property | ||||
|     def key(self) -> str: | ||||
|         return self._key | ||||
|  | ||||
|     def from_dict(self, settings: dict): | ||||
|         try: | ||||
|             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()}") | ||||
|   | ||||
| @@ -1,28 +0,0 @@ | ||||
| import traceback | ||||
|  | ||||
| from cpl_core.configuration.configuration_model_abc import ConfigurationModelABC | ||||
| from cpl_core.console import Console | ||||
|  | ||||
|  | ||||
| class ServerSettings(ConfigurationModelABC): | ||||
|     def __init__(self): | ||||
|         ConfigurationModelABC.__init__(self) | ||||
|  | ||||
|         self._id: int = 0 | ||||
|         self._message_delete_timer: int = 0 | ||||
|  | ||||
|     @property | ||||
|     def id(self) -> int: | ||||
|         return self._id | ||||
|  | ||||
|     @property | ||||
|     def message_delete_timer(self) -> int: | ||||
|         return self._message_delete_timer | ||||
|  | ||||
|     def from_dict(self, settings: dict): | ||||
|         try: | ||||
|             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()}") | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_core.core_extension" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.0.7" | ||||
| __version__ = "1.1.5" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="0", micro="7") | ||||
| version_info = VersionInfo(major="1", minor="1", micro="5") | ||||
|   | ||||
| @@ -11,6 +11,8 @@ from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum | ||||
| from bot_core.events.core_on_ready_event import CoreOnReadyEvent | ||||
| from bot_core.pipes.date_time_offset_pipe import DateTimeOffsetPipe | ||||
| from bot_core.service.client_utils_service import ClientUtilsService | ||||
| from bot_core.service.config_service import ConfigService | ||||
| from bot_core.service.data_integrity_service import DataIntegrityService | ||||
| from bot_core.service.message_service import MessageService | ||||
|  | ||||
|  | ||||
| @@ -22,8 +24,10 @@ class CoreModule(ModuleABC): | ||||
|         pass | ||||
|  | ||||
|     def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC): | ||||
|         services.add_transient(ConfigService) | ||||
|         services.add_transient(MessageServiceABC, MessageService) | ||||
|         services.add_transient(ClientUtilsABC, ClientUtilsService) | ||||
|         services.add_transient(DataIntegrityService) | ||||
|  | ||||
|         # pipes | ||||
|         services.add_transient(DateTimeOffsetPipe) | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_core.events" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.0.7" | ||||
| __version__ = "1.1.5" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="0", micro="7") | ||||
| version_info = VersionInfo(major="1", minor="1", micro="5") | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_core.exception" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.0.7" | ||||
| __version__ = "1.1.5" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="0", micro="7") | ||||
| version_info = VersionInfo(major="1", minor="1", micro="5") | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_core.helper" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.0.7" | ||||
| __version__ = "1.1.5" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="0", micro="7") | ||||
| version_info = VersionInfo(major="1", minor="1", micro="5") | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_core.logging" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.0.7" | ||||
| __version__ = "1.1.5" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="0", micro="7") | ||||
| version_info = VersionInfo(major="1", minor="1", micro="5") | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_core.pipes" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.0.7" | ||||
| __version__ = "1.1.5" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="0", micro="7") | ||||
| version_info = VersionInfo(major="1", minor="1", micro="5") | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_core.service" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.0.7" | ||||
| __version__ = "1.1.5" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="0", micro="7") | ||||
| version_info = VersionInfo(major="1", minor="1", micro="5") | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| from datetime import datetime | ||||
| from typing import Callable | ||||
| from typing import Callable, Union | ||||
|  | ||||
| import discord | ||||
| from cpl_core.configuration import ConfigurationABC | ||||
| @@ -25,9 +25,9 @@ from bot_data.abc.user_message_count_per_hour_repository_abc import ( | ||||
|     UserMessageCountPerHourRepositoryABC, | ||||
| ) | ||||
| from bot_data.model.auto_role_rule import AutoRoleRule | ||||
| from bot_data.model.server_config import ServerConfig | ||||
| 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(ClientUtilsABC): | ||||
| @@ -139,7 +139,7 @@ class ClientUtilsService(ClientUtilsABC): | ||||
|         self, | ||||
|         created_at: datetime, | ||||
|         user: User, | ||||
|         settings: BaseServerSettings, | ||||
|         settings: ServerConfig, | ||||
|         is_reaction: bool = False, | ||||
|     ) -> bool: | ||||
|         umcph = None | ||||
| @@ -218,3 +218,20 @@ class ClientUtilsService(ClientUtilsABC): | ||||
|                 f"Cannot add reaction {rule.emoji_name} to message: {discord_message_id}", | ||||
|                 e, | ||||
|             ) | ||||
|  | ||||
|     async def check_default_role(self, member: Union[discord.User, discord.Member]): | ||||
|         try: | ||||
|             server = self._servers.get_server_by_discord_id(member.guild.id) | ||||
|             settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{server.discord_id}") | ||||
|  | ||||
|             if settings.default_role_id is None: | ||||
|                 return | ||||
|  | ||||
|             default_role = member.guild.get_role(settings.default_role_id) | ||||
|             if default_role in member.roles: | ||||
|                 return | ||||
|  | ||||
|             await member.add_roles(default_role) | ||||
|  | ||||
|         except Exception as e: | ||||
|             self._logger.error(__name__, f"Cannot check for default role for member {member.id}", e) | ||||
|   | ||||
							
								
								
									
										50
									
								
								kdb-bot/src/bot_core/service/config_service.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								kdb-bot/src/bot_core/service/config_service.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,50 @@ | ||||
| from cpl_core.configuration import ConfigurationABC | ||||
| from cpl_core.dependency_injection import ServiceProviderABC | ||||
|  | ||||
| from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings | ||||
| from bot_data.abc.server_config_repository_abc import ServerConfigRepositoryABC | ||||
| from bot_data.abc.technician_config_repository_abc import TechnicianConfigRepositoryABC | ||||
| from bot_data.model.server import Server | ||||
| from bot_data.model.technician_config import TechnicianConfig | ||||
| from bot_data.service.server_config_seeder import ServerConfigSeeder | ||||
| from bot_data.service.technician_config_seeder import TechnicianConfigSeeder | ||||
| from modules.permission.abc.permission_service_abc import PermissionServiceABC | ||||
|  | ||||
|  | ||||
| class ConfigService: | ||||
|     def __init__( | ||||
|         self, | ||||
|         config: ConfigurationABC, | ||||
|         services: ServiceProviderABC, | ||||
|         technician_config_repo: TechnicianConfigRepositoryABC, | ||||
|         server_config_repo: ServerConfigRepositoryABC, | ||||
|         tech_seeder: TechnicianConfigSeeder, | ||||
|         server_seeder: ServerConfigSeeder, | ||||
|     ): | ||||
|         self._config = config | ||||
|         self._services = services | ||||
|         self._technician_config_repo = technician_config_repo | ||||
|         self._server_config_repo = server_config_repo | ||||
|  | ||||
|         self._tech_seeder = tech_seeder | ||||
|         self._server_seeder = server_seeder | ||||
|  | ||||
|     async def reload_technician_config(self): | ||||
|         if not self._technician_config_repo.does_technician_config_exists(): | ||||
|             await self._tech_seeder.seed() | ||||
|  | ||||
|         technician_config = self._technician_config_repo.get_technician_config() | ||||
|         self._config.add_configuration(TechnicianConfig, technician_config) | ||||
|         self._config.add_configuration(FeatureFlagsSettings, FeatureFlagsSettings(**technician_config.feature_flags)) | ||||
|  | ||||
|     async def reload_server_config(self, server: Server): | ||||
|         if not self._server_config_repo.does_server_config_exists(server.id): | ||||
|             await self._server_seeder.seed() | ||||
|  | ||||
|         server_config = self._server_config_repo.get_server_config_by_server(server.id) | ||||
|         self._config.add_configuration( | ||||
|             f"{type(server_config).__name__}_{server_config.server.discord_id}", server_config | ||||
|         ) | ||||
|  | ||||
|         permissions: PermissionServiceABC = self._services.get_service(PermissionServiceABC) | ||||
|         permissions.on_ready() | ||||
							
								
								
									
										405
									
								
								kdb-bot/src/bot_core/service/data_integrity_service.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										405
									
								
								kdb-bot/src/bot_core/service/data_integrity_service.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,405 @@ | ||||
| from datetime import datetime, timedelta | ||||
| from typing import Union | ||||
|  | ||||
| import discord | ||||
| from cpl_core.configuration import ConfigurationABC | ||||
| from cpl_core.database.context import DatabaseContextABC | ||||
| from cpl_discord.service import DiscordBotServiceABC | ||||
|  | ||||
| from bot_core.abc.client_utils_abc import ClientUtilsABC | ||||
| from bot_core.logging.database_logger import DatabaseLogger | ||||
| 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_game_server_repository_abc import UserJoinedGameServerRepositoryABC | ||||
| from bot_data.abc.user_joined_server_repository_abc import UserJoinedServerRepositoryABC | ||||
| 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 | ||||
| from bot_data.model.server import Server | ||||
| from bot_data.model.server_config import ServerConfig | ||||
| from bot_data.model.user import User | ||||
| from bot_data.model.user_joined_server import UserJoinedServer | ||||
| from bot_data.model.user_joined_voice_channel import UserJoinedVoiceChannel | ||||
| from bot_data.service.seeder_service import SeederService | ||||
| from bot_data.service.user_repository_service import ServerRepositoryABC | ||||
| from modules.achievements.achievement_service import AchievementService | ||||
|  | ||||
|  | ||||
| class DataIntegrityService: | ||||
|     def __init__( | ||||
|         self, | ||||
|         config: ConfigurationABC, | ||||
|         logger: DatabaseLogger, | ||||
|         seeder: SeederService, | ||||
|         bot: DiscordBotServiceABC, | ||||
|         db_context: DatabaseContextABC, | ||||
|         server_repo: ServerRepositoryABC, | ||||
|         user_repo: UserRepositoryABC, | ||||
|         client_repo: ClientRepositoryABC, | ||||
|         known_users: KnownUserRepositoryABC, | ||||
|         user_joins: UserJoinedServerRepositoryABC, | ||||
|         user_joins_vc: UserJoinedVoiceChannelRepositoryABC, | ||||
|         user_joined_gs: UserJoinedGameServerRepositoryABC, | ||||
|         achievement_service: AchievementService, | ||||
|         client_utils: ClientUtilsABC, | ||||
|         dtp: DateTimeOffsetPipe, | ||||
|     ): | ||||
|         self._config = config | ||||
|  | ||||
|         self._logger = logger | ||||
|         self._seeder = seeder | ||||
|         self._bot = bot | ||||
|         self._db_context = db_context | ||||
|         self._servers = server_repo | ||||
|         self._users = user_repo | ||||
|         self._clients = client_repo | ||||
|         self._known_users = known_users | ||||
|         self._user_joins = user_joins | ||||
|         self._user_joins_vc = user_joins_vc | ||||
|         self._user_joined_gs = user_joined_gs | ||||
|         self._achievements = achievement_service | ||||
|         self._client_utils = client_utils | ||||
|         self._dtp = dtp | ||||
|  | ||||
|         self._is_for_shutdown = False | ||||
|  | ||||
|     def _check_known_users(self): | ||||
|         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") | ||||
|                     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._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.debug(__name__, f"Added user: {u.id}") | ||||
|             except Exception as e: | ||||
|                 self._logger.error(__name__, f"Cannot get user", e) | ||||
|  | ||||
|     def _check_servers(self): | ||||
|         self._logger.debug(__name__, f"Start checking Servers 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 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._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.debug(__name__, f"Added server: {g.id}") | ||||
|             except Exception as 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!") | ||||
|  | ||||
|     def _check_clients(self): | ||||
|         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}") | ||||
|  | ||||
|                 client = self._clients.find_client_by_server_id(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._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.id) | ||||
|                 if client is None: | ||||
|                     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}") | ||||
|             except Exception as 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!") | ||||
|  | ||||
|     def _check_users(self): | ||||
|         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}") | ||||
|  | ||||
|                 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") | ||||
|                         continue | ||||
|  | ||||
|                     user = self._users.find_user_by_discord_id_and_server_id(u.id, 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._users.add_user(User(u.id, 0, 0, 0, server)) | ||||
|                     self._db_context.save_changes() | ||||
|  | ||||
|                     self._logger.debug(__name__, f"Added User: {u.id}") | ||||
|             except Exception as 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!") | ||||
|  | ||||
|     def _check_user_joins(self): | ||||
|         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}") | ||||
|  | ||||
|             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") | ||||
|                         continue | ||||
|  | ||||
|                     user = self._users.find_user_by_discord_id_and_server_id(u.id, server.id) | ||||
|                     if user is None: | ||||
|                         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.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._db_context.save_changes() | ||||
|  | ||||
|                     self._logger.debug(__name__, f"Added UserJoinedServer: {u.id}") | ||||
|             except Exception as 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!") | ||||
|  | ||||
|             joins = self._user_joins.get_user_joined_servers() | ||||
|             for join in joins: | ||||
|                 join: UserJoinedServer = join | ||||
|                 if join.user.server.discord_id != guild.id: | ||||
|                     continue | ||||
|  | ||||
|                 if join.leaved_on is not None: | ||||
|                     continue | ||||
|  | ||||
|                 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.", | ||||
|                     ) | ||||
|                     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") | ||||
|         for guild in self._bot.guilds: | ||||
|             guild: discord.Guild = guild | ||||
|             settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{guild.id}") | ||||
|  | ||||
|             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}") | ||||
|  | ||||
|             try: | ||||
|                 # close open voice states | ||||
|                 for member in guild.members: | ||||
|                     if member.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.id) | ||||
|                     if user is None: | ||||
|                         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.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}", | ||||
|                         ) | ||||
|                         join.leaved_on = datetime.now() | ||||
|  | ||||
|                         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) | ||||
|  | ||||
|                         if self._is_for_shutdown: | ||||
|                             user.xp += round(join.time * settings.xp_per_ontime_hour) | ||||
|                             self._users.update_user(user) | ||||
|  | ||||
|                         self._db_context.save_changes() | ||||
|                         if self._is_for_shutdown: | ||||
|                             return | ||||
|  | ||||
|                 # add open voice states | ||||
|                 for member in guild.members: | ||||
|                     if member.bot: | ||||
|                         self._logger.trace(__name__, f"User {member.id} is ignored, because its a bot") | ||||
|                         continue | ||||
|  | ||||
|                     if member.voice is None or member.voice.channel.id in settings.afk_channel_ids: | ||||
|                         continue | ||||
|  | ||||
|                     user = self._users.find_user_by_discord_id_and_server_id(member.id, server.id) | ||||
|                     if user is None: | ||||
|                         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() | ||||
|  | ||||
|             except Exception as e: | ||||
|                 self._logger.error(__name__, f"Cannot get UserJoinedVoiceChannel", e) | ||||
|  | ||||
|     def _check_user_joined_gs(self): | ||||
|         self._logger.debug(__name__, f"Start checking UserJoinedGameServer 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}") | ||||
|  | ||||
|             try: | ||||
|                 for member in guild.members: | ||||
|                     if member.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.id) | ||||
|                     if user is None: | ||||
|                         self._logger.fatal(__name__, f"User not found in database: {member.id}") | ||||
|  | ||||
|                     joins = self._user_joined_gs.find_active_user_joined_game_servers_by_user_id(user.id) | ||||
|                     if joins is None or len(joins) == 0: | ||||
|                         continue | ||||
|  | ||||
|                     for join in joins: | ||||
|                         self._logger.warn( | ||||
|                             __name__, | ||||
|                             f"Active UserJoinedGameServer found in database: {guild.id}:{member.id}@{join.joined_on}", | ||||
|                         ) | ||||
|                         join.leaved_on = datetime.now() | ||||
|                         settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{guild.id}") | ||||
|  | ||||
|                         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_joined_gs.update_user_joined_game_server(join) | ||||
|                         if self._is_for_shutdown: | ||||
|                             user.xp += round(join.time * settings.xp_per_ontime_hour) | ||||
|                             self._users.update_user(user) | ||||
|  | ||||
|                         self._db_context.save_changes() | ||||
|             except Exception as e: | ||||
|                 self._logger.error(__name__, f"Cannot get UserJoinedGameServer", e) | ||||
|  | ||||
|     async def _check_for_user_achievements(self): | ||||
|         self._logger.debug(__name__, f"Start checking UserGotAchievement table") | ||||
|  | ||||
|         for guild in self._bot.guilds: | ||||
|             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}") | ||||
|  | ||||
|             for member in guild.members: | ||||
|                 if member.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.id) | ||||
|                 if user is None: | ||||
|                     self._logger.fatal(__name__, f"User not found in database: {member.id}") | ||||
|  | ||||
|                 await self._achievements.validate_achievements_for_user(user) | ||||
|  | ||||
|     async def _check_default_role(self): | ||||
|         for guild in self._bot.guilds: | ||||
|             for member in guild.members: | ||||
|                 await self._client_utils.check_default_role(member) | ||||
|  | ||||
|     async def check_data_integrity(self, is_for_shutdown=False): | ||||
|         if is_for_shutdown != self._is_for_shutdown: | ||||
|             self._is_for_shutdown = is_for_shutdown | ||||
|  | ||||
|         await self._check_default_role() | ||||
|         self._check_known_users() | ||||
|         self._check_servers() | ||||
|         self._check_clients() | ||||
|         self._check_users() | ||||
|         self._check_user_joins() | ||||
|         self._check_user_joins_vc() | ||||
|         self._check_user_joined_gs() | ||||
|         await self._check_for_user_achievements() | ||||
| @@ -10,10 +10,10 @@ from discord import Interaction | ||||
| from discord.ext.commands import Context | ||||
|  | ||||
| from bot_core.abc.message_service_abc import MessageServiceABC | ||||
| from bot_core.configuration.server_settings import ServerSettings | ||||
| 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.model.server_config import ServerConfig | ||||
|  | ||||
|  | ||||
| class MessageService(MessageServiceABC): | ||||
| @@ -33,7 +33,7 @@ class MessageService(MessageServiceABC): | ||||
|  | ||||
|     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}") | ||||
|         server_st: ServerConfig = self._config.get_configuration(f"ServerConfig_{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) | ||||
| @@ -50,7 +50,7 @@ class MessageService(MessageServiceABC): | ||||
|             else None | ||||
|         ) | ||||
|  | ||||
|         server_st: ServerSettings = self._config.get_configuration(f"ServerSettings_{guild_id}") | ||||
|         server_st: ServerConfig = self._config.get_configuration(f"ServerConfig_{guild_id}") | ||||
|         if not mass_delete: | ||||
|             await asyncio.sleep(server_st.message_delete_timer) | ||||
|         self._logger.debug( | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_data" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.0.7" | ||||
| __version__ = "1.1.5" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="0", micro="7") | ||||
| version_info = VersionInfo(major="1", minor="1", micro="5") | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_data.abc" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.0.7" | ||||
| __version__ = "1.1.5" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="0", micro="7") | ||||
| version_info = VersionInfo(major="1", minor="1", micro="5") | ||||
|   | ||||
							
								
								
									
										52
									
								
								kdb-bot/src/bot_data/abc/achievement_repository_abc.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								kdb-bot/src/bot_data/abc/achievement_repository_abc.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | ||||
| from abc import ABC, abstractmethod | ||||
|  | ||||
| from cpl_query.extension import List | ||||
|  | ||||
| from bot_data.model.achievement import Achievement | ||||
| from bot_data.model.user_got_achievement import UserGotAchievement | ||||
|  | ||||
|  | ||||
| class AchievementRepositoryABC(ABC): | ||||
|     @abstractmethod | ||||
|     def __init__(self): | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def get_achievements(self) -> List[Achievement]: | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def get_achievement_by_id(self, id: int) -> Achievement: | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def get_achievements_by_server_id(self, server_id: int) -> List[Achievement]: | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def get_achievements_by_user_id(self, user_id: int) -> List[Achievement]: | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def get_user_got_achievements_by_achievement_id(self, achievement_id: int) -> List[Achievement]: | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def add_achievement(self, achievement: Achievement): | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def update_achievement(self, achievement: Achievement): | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def delete_achievement(self, achievement: Achievement): | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def add_user_got_achievement(self, join: UserGotAchievement): | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def delete_user_got_achievement(self, join: UserGotAchievement): | ||||
|         pass | ||||
| @@ -14,6 +14,10 @@ class AuthUserRepositoryABC(ABC): | ||||
|     def __init__(self): | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def get_auth_user_relation_ids(self, auth_user: AuthUser) -> List[int]: | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def get_all_auth_users(self) -> List[AuthUser]: | ||||
|         pass | ||||
|   | ||||
| @@ -7,5 +7,5 @@ class DataSeederABC(ABC): | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def seed(self): | ||||
|     async def seed(self): | ||||
|         pass | ||||
|   | ||||
| @@ -23,7 +23,7 @@ class GameServerRepositoryABC(ABC): | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def get_game_server_by_api_key_id(self, id: int) -> GameServer: | ||||
|     def get_game_servers_by_api_key_id(self, id: int) -> List[GameServer]: | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|   | ||||
							
								
								
									
										59
									
								
								kdb-bot/src/bot_data/abc/server_config_repository_abc.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								kdb-bot/src/bot_data/abc/server_config_repository_abc.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | ||||
| from abc import ABC, abstractmethod | ||||
|  | ||||
| from bot_data.model.server_afk_channel_ids_config import ServerAFKChannelIdsConfig | ||||
| from bot_data.model.server_config import ServerConfig | ||||
| from bot_data.model.server_team_role_ids_config import ServerTeamRoleIdsConfig | ||||
|  | ||||
|  | ||||
| class ServerConfigRepositoryABC(ABC): | ||||
|     @abstractmethod | ||||
|     def __init__(self): | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def does_server_config_exists(self, server_id: int) -> bool: | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def get_server_config_by_server(self, server_id: int) -> ServerConfig: | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def get_server_config_by_id(self, config_id: int) -> ServerConfig: | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def add_server_config(self, server_config: ServerConfig): | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def update_server_config(self, server_config: ServerConfig): | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def delete_server_config(self, server_config: ServerConfig): | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def add_server_team_role_id_config(self, server_team_role_id: ServerTeamRoleIdsConfig): | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def update_server_team_role_id_config(self, server_team_role_id: ServerTeamRoleIdsConfig): | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def delete_server_team_role_id_config(self, server_team_role_id: ServerTeamRoleIdsConfig): | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def add_server_afk_channel_config(self, server_afk_channel: ServerAFKChannelIdsConfig): | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def update_server_afk_channel_config(self, server_afk_channel: ServerAFKChannelIdsConfig): | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def delete_server_afk_channel_config(self, server_afk_channel: ServerAFKChannelIdsConfig): | ||||
|         pass | ||||
							
								
								
									
										55
									
								
								kdb-bot/src/bot_data/abc/technician_config_repository_abc.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								kdb-bot/src/bot_data/abc/technician_config_repository_abc.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| from abc import ABC, abstractmethod | ||||
|  | ||||
| from bot_data.model.technician_config import TechnicianConfig | ||||
| from bot_data.model.technician_id_config import TechnicianIdConfig | ||||
| from bot_data.model.technician_ping_url_config import TechnicianPingUrlConfig | ||||
|  | ||||
|  | ||||
| class TechnicianConfigRepositoryABC(ABC): | ||||
|     @abstractmethod | ||||
|     def __init__(self): | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def does_technician_config_exists(self) -> bool: | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def get_technician_config(self) -> TechnicianConfig: | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def add_technician_config(self, technician_config: TechnicianConfig): | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def update_technician_config(self, technician_config: TechnicianConfig): | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def delete_technician_config(self, technician_config: TechnicianConfig): | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def add_technician_id_config(self, technician_id: TechnicianIdConfig): | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def update_technician_id_config(self, technician_id: TechnicianIdConfig): | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def delete_technician_id_config(self, technician_id: TechnicianIdConfig): | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def add_technician_ping_url_config(self, technician_ping_url: TechnicianPingUrlConfig): | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def update_technician_ping_url_config(self, technician_ping_url: TechnicianPingUrlConfig): | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def delete_technician_ping_url_config(self, technician_ping_url: TechnicianPingUrlConfig): | ||||
|         pass | ||||
| @@ -3,8 +3,8 @@ | ||||
|     "Name": "bot-data", | ||||
|     "Version": { | ||||
|       "Major": "1", | ||||
|       "Minor": "0", | ||||
|       "Micro": "7" | ||||
|       "Minor": "1", | ||||
|       "Micro": "5" | ||||
|     }, | ||||
|     "Author": "Sven Heidemann", | ||||
|     "AuthorEmail": "sven.heidemann@sh-edraft.de", | ||||
|   | ||||
| @@ -5,14 +5,18 @@ 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_data.abc.achievement_repository_abc import AchievementRepositoryABC | ||||
| from bot_data.abc.api_key_repository_abc import ApiKeyRepositoryABC | ||||
| from bot_data.abc.auth_user_repository_abc import AuthUserRepositoryABC | ||||
| from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC | ||||
| from bot_data.abc.client_repository_abc import ClientRepositoryABC | ||||
| from bot_data.abc.data_seeder_abc import DataSeederABC | ||||
| from bot_data.abc.game_server_repository_abc import GameServerRepositoryABC | ||||
| from bot_data.abc.known_user_repository_abc import KnownUserRepositoryABC | ||||
| from bot_data.abc.level_repository_abc import LevelRepositoryABC | ||||
| from bot_data.abc.server_config_repository_abc import ServerConfigRepositoryABC | ||||
| from bot_data.abc.server_repository_abc import ServerRepositoryABC | ||||
| from bot_data.abc.technician_config_repository_abc import TechnicianConfigRepositoryABC | ||||
| from bot_data.abc.user_game_ident_repository_abc import UserGameIdentRepositoryABC | ||||
| from bot_data.abc.user_joined_game_server_repository_abc import UserJoinedGameServerRepositoryABC | ||||
| from bot_data.abc.user_joined_server_repository_abc import UserJoinedServerRepositoryABC | ||||
| @@ -24,6 +28,7 @@ from bot_data.abc.user_message_count_per_hour_repository_abc import ( | ||||
| ) | ||||
| from bot_data.abc.user_repository_abc import UserRepositoryABC | ||||
| from bot_data.abc.user_warnings_repository_abc import UserWarningsRepositoryABC | ||||
| from bot_data.service.achievements_repository_service import AchievementRepositoryService | ||||
| from bot_data.service.api_key_repository_service import ApiKeyRepositoryService | ||||
| from bot_data.service.auth_user_repository_service import AuthUserRepositoryService | ||||
| from bot_data.service.auto_role_repository_service import AutoRoleRepositoryService | ||||
| @@ -33,7 +38,11 @@ from bot_data.service.game_server_repository_service import GameServerRepository | ||||
| from bot_data.service.known_user_repository_service import KnownUserRepositoryService | ||||
| from bot_data.service.level_repository_service import LevelRepositoryService | ||||
| from bot_data.service.seeder_service import SeederService | ||||
| from bot_data.service.server_config_repository_service import ServerConfigRepositoryService | ||||
| from bot_data.service.server_config_seeder import ServerConfigSeeder | ||||
| from bot_data.service.server_repository_service import ServerRepositoryService | ||||
| from bot_data.service.technician_config_repository_service import TechnicianConfigRepositoryService | ||||
| from bot_data.service.technician_config_seeder import TechnicianConfigSeeder | ||||
| from bot_data.service.user_game_ident_repository_service import UserGameIdentRepositoryService | ||||
| from bot_data.service.user_joined_game_server_repository_service import UserJoinedGameServerRepositoryService | ||||
| from bot_data.service.user_joined_server_repository_service import ( | ||||
| @@ -77,5 +86,10 @@ class DataModule(ModuleABC): | ||||
|         ) | ||||
|         services.add_transient(GameServerRepositoryABC, GameServerRepositoryService) | ||||
|         services.add_transient(UserGameIdentRepositoryABC, UserGameIdentRepositoryService) | ||||
|         services.add_transient(AchievementRepositoryABC, AchievementRepositoryService) | ||||
|         services.add_transient(TechnicianConfigRepositoryABC, TechnicianConfigRepositoryService) | ||||
|         services.add_transient(ServerConfigRepositoryABC, ServerConfigRepositoryService) | ||||
|  | ||||
|         services.add_transient(SeederService) | ||||
|         services.add_transient(DataSeederABC, TechnicianConfigSeeder) | ||||
|         services.add_transient(DataSeederABC, ServerConfigSeeder) | ||||
|   | ||||
| @@ -11,6 +11,7 @@ class DBContext(DatabaseContext): | ||||
|         self._logger = logger | ||||
|  | ||||
|         DatabaseContext.__init__(self) | ||||
|         self._fails = 0 | ||||
|  | ||||
|     def connect(self, database_settings: DatabaseSettings): | ||||
|         try: | ||||
| @@ -32,7 +33,11 @@ class DBContext(DatabaseContext): | ||||
|         try: | ||||
|             return super(DBContext, self).select(statement) | ||||
|         except Exception as e: | ||||
|             if self._fails >= 3: | ||||
|                 self._logger.fatal(__name__, f"Database error caused by {statement}", e) | ||||
|  | ||||
|             self._logger.error(__name__, f"Database error caused by {statement}", e) | ||||
|             self._fails += 1 | ||||
|             try: | ||||
|                 time.sleep(0.5) | ||||
|                 return self.select(statement) | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_data.migration" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.0.7" | ||||
| __version__ = "1.1.5" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="0", micro="7") | ||||
| version_info = VersionInfo(major="1", minor="1", micro="5") | ||||
|   | ||||
							
								
								
									
										127
									
								
								kdb-bot/src/bot_data/migration/achievements_migration.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								kdb-bot/src/bot_data/migration/achievements_migration.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,127 @@ | ||||
| from bot_core.logging.database_logger import DatabaseLogger | ||||
| from bot_data.abc.migration_abc import MigrationABC | ||||
| from bot_data.db_context import DBContext | ||||
|  | ||||
|  | ||||
| class AchievementsMigration(MigrationABC): | ||||
|     name = "1.1.0_AchievementsMigration" | ||||
|  | ||||
|     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 `Achievements` ( | ||||
|                         `Id` BIGINT NOT NULL AUTO_INCREMENT, | ||||
|                         `Name` VARCHAR(255) NOT NULL, | ||||
|                         `Description` VARCHAR(255) NOT NULL, | ||||
|                         `Attribute` VARCHAR(255) NOT NULL, | ||||
|                         `Operator` VARCHAR(255) NOT NULL, | ||||
|                         `Value` VARCHAR(255) NOT NULL, | ||||
|                         `ServerId` BIGINT, | ||||
|                         `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6), | ||||
|                         `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), | ||||
|                         PRIMARY KEY(`Id`), | ||||
|                         FOREIGN KEY (`ServerId`) REFERENCES `Servers`(`ServerId`) | ||||
|                     ); | ||||
|                 """ | ||||
|             ) | ||||
|         ) | ||||
|  | ||||
|         self._cursor.execute( | ||||
|             str( | ||||
|                 f""" | ||||
|                     CREATE TABLE IF NOT EXISTS `AchievementsHistory` | ||||
|                     ( | ||||
|                         `Id`    BIGINT(20)  NOT NULL, | ||||
|                         `Name` VARCHAR(255) NOT NULL, | ||||
|                         `Description` VARCHAR(255) NOT NULL, | ||||
|                         `Attribute` VARCHAR(255) NOT NULL, | ||||
|                         `Operator` VARCHAR(255) NOT NULL, | ||||
|                         `Value` VARCHAR(255) NOT NULL, | ||||
|                         `ServerId` BIGINT, | ||||
|                         `Deleted`   BOOL DEFAULT FALSE, | ||||
|                         `DateFrom`  DATETIME(6) NOT NULL, | ||||
|                         `DateTo`    DATETIME(6) NOT NULL | ||||
|                     ); | ||||
|                 """ | ||||
|             ) | ||||
|         ) | ||||
|  | ||||
|         self._cursor.execute( | ||||
|             str( | ||||
|                 f""" | ||||
|                     CREATE TABLE IF NOT EXISTS `UserGotAchievements` ( | ||||
|                         `Id` BIGINT NOT NULL AUTO_INCREMENT, | ||||
|                         `UserId` BIGINT, | ||||
|                         `AchievementId` BIGINT, | ||||
|                         `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6), | ||||
|                         `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), | ||||
|                         PRIMARY KEY(`Id`), | ||||
|                         FOREIGN KEY (`UserId`) REFERENCES `Users`(`UserId`), | ||||
|                         FOREIGN KEY (`AchievementId`) REFERENCES `Achievements`(`Id`) | ||||
|                     ); | ||||
|                 """ | ||||
|             ) | ||||
|         ) | ||||
|  | ||||
|         # A join table history between users and achievements is not necessary. | ||||
|  | ||||
|         self._cursor.execute(str(f"""ALTER TABLE Users ADD MessageCount BIGINT NOT NULL DEFAULT 0 AFTER XP;""")) | ||||
|         self._cursor.execute(str(f"""ALTER TABLE Users ADD ReactionCount BIGINT NOT NULL DEFAULT 0 AFTER XP;""")) | ||||
|         self._cursor.execute(str(f"""ALTER TABLE UsersHistory ADD MessageCount BIGINT NOT NULL DEFAULT 0 AFTER XP;""")) | ||||
|         self._cursor.execute(str(f"""ALTER TABLE UsersHistory ADD ReactionCount BIGINT NOT NULL DEFAULT 0 AFTER XP;""")) | ||||
|  | ||||
|         self._cursor.execute(str(f"""DROP TRIGGER IF EXISTS `TR_AchievementsUpdate`;""")) | ||||
|         self._cursor.execute( | ||||
|             str( | ||||
|                 f""" | ||||
|                     CREATE TRIGGER `TR_AchievementsUpdate` | ||||
|                         AFTER UPDATE | ||||
|                         ON `Achievements` | ||||
|                         FOR EACH ROW | ||||
|                     BEGIN | ||||
|                         INSERT INTO `AchievementsHistory` ( | ||||
|                             `Id`, `Name`, `Description`, `Attribute`, `Operator`, `Value`, `ServerId`, `DateFrom`, `DateTo` | ||||
|                         ) | ||||
|                         VALUES ( | ||||
|                             OLD.Id, OLD.Name, OLD.Description, OLD.Attribute, OLD.Operator, OLD.Value, OLD.ServerId, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) | ||||
|                         ); | ||||
|                     END; | ||||
|                 """ | ||||
|             ) | ||||
|         ) | ||||
|  | ||||
|         self._cursor.execute(str(f"""DROP TRIGGER IF EXISTS `TR_AchievementsDelete`;""")) | ||||
|  | ||||
|         self._cursor.execute( | ||||
|             str( | ||||
|                 f""" | ||||
|                     CREATE TRIGGER `TR_AchievementsDelete` | ||||
|                         AFTER DELETE | ||||
|                         ON `Achievements` | ||||
|                         FOR EACH ROW | ||||
|                     BEGIN | ||||
|                         INSERT INTO `AchievementsHistory` ( | ||||
|                             `Id`, `Name`, `Description`, `Attribute`, `Operator`, `Value`, `ServerId`, `Deleted`, `DateFrom`, `DateTo` | ||||
|                         ) | ||||
|                         VALUES ( | ||||
|                             OLD.Id, OLD.Name, OLD.Description, OLD.Attribute, OLD.Operator, OLD.Value, OLD.ServerId, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) | ||||
|                         ); | ||||
|                     END; | ||||
|                 """ | ||||
|             ) | ||||
|         ) | ||||
|  | ||||
|     def downgrade(self): | ||||
|         self._cursor.execute("DROP TABLE `Achievements`;") | ||||
|  | ||||
|         self._cursor.execute(str(f"""ALTER TABLE Users DROP COLUMN MessageCount;""")) | ||||
|         self._cursor.execute(str(f"""ALTER TABLE Users DROP COLUMN ReactionCount;""")) | ||||
| @@ -0,0 +1,29 @@ | ||||
| from bot_core.logging.database_logger import DatabaseLogger | ||||
| from bot_data.abc.migration_abc import MigrationABC | ||||
| from bot_data.db_context import DBContext | ||||
|  | ||||
|  | ||||
| class ConfigFeatureFlagsMigration(MigrationABC): | ||||
|     name = "1.1.0_ConfigFeatureFlagsMigration" | ||||
|  | ||||
|     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("""ALTER TABLE CFG_Technician ADD FeatureFlags JSON NULL DEFAULT ('{}') AFTER CacheMaxMessages;""") | ||||
|         ) | ||||
|  | ||||
|         self._cursor.execute( | ||||
|             str("""ALTER TABLE CFG_Server ADD FeatureFlags JSON NULL DEFAULT ('{}') AFTER LoginMessageChannelId;""") | ||||
|         ) | ||||
|  | ||||
|     def downgrade(self): | ||||
|         self._logger.debug(__name__, "Running downgrade") | ||||
|         self._cursor.execute("ALTER TABLE CFG_Technician DROP COLUMN FeatureFlags;") | ||||
|         self._cursor.execute("ALTER TABLE CFG_Server DROP COLUMN FeatureFlags;") | ||||
							
								
								
									
										155
									
								
								kdb-bot/src/bot_data/migration/config_migration.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								kdb-bot/src/bot_data/migration/config_migration.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,155 @@ | ||||
| import os | ||||
|  | ||||
| from bot_core.logging.database_logger import DatabaseLogger | ||||
| from bot_data.abc.migration_abc import MigrationABC | ||||
| from bot_data.db_context import DBContext | ||||
|  | ||||
|  | ||||
| class ConfigMigration(MigrationABC): | ||||
|     name = "1.1.0_ConfigMigration" | ||||
|  | ||||
|     def __init__(self, logger: DatabaseLogger, db: DBContext): | ||||
|         MigrationABC.__init__(self) | ||||
|         self._logger = logger | ||||
|         self._db = db | ||||
|         self._cursor = db.cursor | ||||
|  | ||||
|     def _exec(self, file: str): | ||||
|         path = f"{os.path.dirname(os.path.realpath(__file__))}/db_history_scripts" | ||||
|         sql = open(f"{path}/{file}").read() | ||||
|  | ||||
|         for statement in sql.split("\n\n"): | ||||
|             self._cursor.execute(statement + ";") | ||||
|  | ||||
|     def upgrade(self): | ||||
|         self._logger.debug(__name__, "Running upgrade") | ||||
|         self._server_upgrade() | ||||
|         self._technician_upgrade() | ||||
|  | ||||
|         self._exec("config/server.sql") | ||||
|         self._exec("config/server_afk_channels.sql") | ||||
|         self._exec("config/server_team_roles.sql") | ||||
|         self._exec("config/technician.sql") | ||||
|         self._exec("config/technician_ids.sql") | ||||
|         self._exec("config/technician_ping_urls.sql") | ||||
|  | ||||
|     def _server_upgrade(self): | ||||
|         self._cursor.execute( | ||||
|             str( | ||||
|                 f""" | ||||
|                     CREATE TABLE IF NOT EXISTS `CFG_Server` ( | ||||
|                         `Id` BIGINT NOT NULL AUTO_INCREMENT, | ||||
|                         `MessageDeleteTimer` BIGINT NOT NULL DEFAULT 6, | ||||
|                         `NotificationChatId` BIGINT NOT NULL, | ||||
|                         `MaxVoiceStateHours` BIGINT NOT NULL DEFAULT 6, | ||||
|                         `XpPerMessage` BIGINT NOT NULL DEFAULT 1, | ||||
|                         `XpPerReaction` BIGINT NOT NULL DEFAULT 1, | ||||
|                         `MaxMessageXpPerHour` BIGINT NOT NULL DEFAULT 20, | ||||
|                         `XpPerOntimeHour` BIGINT NOT NULL DEFAULT 10, | ||||
|                         `XpPerEventParticipation` BIGINT NOT NULL DEFAULT 10, | ||||
|                         `XpPerAchievement` BIGINT NOT NULL DEFAULT 10, | ||||
|                         `AFKCommandChannelId` BIGINT NOT NULL, | ||||
|                         `HelpVoiceChannelId` BIGINT NOT NULL, | ||||
|                         `TeamChannelId` BIGINT NOT NULL, | ||||
|                         `LoginMessageChannelId` BIGINT NOT NULL, | ||||
|                         `ServerId` BIGINT NOT NULL, | ||||
|                         `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6), | ||||
|                         `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), | ||||
|                         PRIMARY KEY(`Id`), | ||||
|                         FOREIGN KEY (`ServerId`) REFERENCES `Servers`(`ServerId`) | ||||
|                     ); | ||||
|                 """ | ||||
|             ) | ||||
|         ) | ||||
|  | ||||
|         self._cursor.execute( | ||||
|             str( | ||||
|                 f""" | ||||
|                     CREATE TABLE IF NOT EXISTS `CFG_ServerAFKChannelIds` ( | ||||
|                         `Id` BIGINT NOT NULL AUTO_INCREMENT, | ||||
|                         `ChannelId` BIGINT NOT NULL, | ||||
|                         `ServerId` BIGINT NOT NULL, | ||||
|                         `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6), | ||||
|                         `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), | ||||
|                         PRIMARY KEY(`Id`), | ||||
|                         FOREIGN KEY (`ServerId`) REFERENCES `Servers`(`ServerId`) | ||||
|                     ); | ||||
|                 """ | ||||
|             ) | ||||
|         ) | ||||
|  | ||||
|         self._cursor.execute( | ||||
|             str( | ||||
|                 f""" | ||||
|                     CREATE TABLE IF NOT EXISTS `CFG_ServerTeamRoleIds` ( | ||||
|                         `Id` BIGINT NOT NULL AUTO_INCREMENT, | ||||
|                         `RoleId` BIGINT NOT NULL, | ||||
|                         `TeamMemberType` ENUM('Moderator', 'Admin') NOT NULL, | ||||
|                         `ServerId` BIGINT NOT NULL, | ||||
|                         `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6), | ||||
|                         `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), | ||||
|                         PRIMARY KEY(`Id`), | ||||
|                         FOREIGN KEY (`ServerId`) REFERENCES `Servers`(`ServerId`) | ||||
|                     ); | ||||
|                 """ | ||||
|             ) | ||||
|         ) | ||||
|  | ||||
|     def _technician_upgrade(self): | ||||
|         self._cursor.execute( | ||||
|             str( | ||||
|                 f""" | ||||
|                     CREATE TABLE IF NOT EXISTS `CFG_Technician` ( | ||||
|                         `Id` BIGINT NOT NULL AUTO_INCREMENT, | ||||
|                         `HelpCommandReferenceUrl` VARCHAR(255) NOT NULL, | ||||
|                         `WaitForRestart` BIGINT NOT NULL DEFAULT 8, | ||||
|                         `WaitForShutdown` BIGINT NOT NULL DEFAULT 8, | ||||
|                         `CacheMaxMessages` BIGINT NOT NULL DEFAULT 1000000, | ||||
|                         `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6), | ||||
|                         `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), | ||||
|                         PRIMARY KEY(`Id`) | ||||
|                     ); | ||||
|                 """ | ||||
|             ) | ||||
|         ) | ||||
|  | ||||
|         self._cursor.execute( | ||||
|             str( | ||||
|                 f""" | ||||
|                     CREATE TABLE IF NOT EXISTS `CFG_TechnicianPingUrls` ( | ||||
|                         `Id` BIGINT NOT NULL AUTO_INCREMENT, | ||||
|                         `URL` VARCHAR(255) NOT NULL, | ||||
|                         `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6), | ||||
|                         `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), | ||||
|                         PRIMARY KEY(`Id`) | ||||
|                     ); | ||||
|                 """ | ||||
|             ) | ||||
|         ) | ||||
|  | ||||
|         self._cursor.execute( | ||||
|             str( | ||||
|                 f""" | ||||
|                     CREATE TABLE IF NOT EXISTS `CFG_TechnicianIds` ( | ||||
|                         `Id` BIGINT NOT NULL AUTO_INCREMENT, | ||||
|                         `TechnicianId` BIGINT NOT NULL, | ||||
|                         `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6), | ||||
|                         `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), | ||||
|                         PRIMARY KEY(`Id`) | ||||
|                     ); | ||||
|                 """ | ||||
|             ) | ||||
|         ) | ||||
|  | ||||
|     def downgrade(self): | ||||
|         self._logger.debug(__name__, "Running downgrade") | ||||
|         self._server_downgrade() | ||||
|         self._technician_downgrade() | ||||
|  | ||||
|     def _server_downgrade(self): | ||||
|         self._cursor.execute("DROP TABLE `CFG_Server`;") | ||||
|  | ||||
|     def _technician_downgrade(self): | ||||
|         self._cursor.execute("DROP TABLE `CFG_Technician`;") | ||||
|         self._cursor.execute("DROP TABLE `CFG_TechnicianPingUrls`;") | ||||
|         self._cursor.execute("DROP TABLE `CFG_TechnicianIds`;") | ||||
| @@ -0,0 +1,117 @@ | ||||
| CREATE TABLE IF NOT EXISTS `CFG_ServerHistory` | ||||
| ( | ||||
|     `Id`    BIGINT(20)  NOT NULL, | ||||
|     `MessageDeleteTimer` BIGINT NOT NULL DEFAULT 6, | ||||
|     `NotificationChatId` BIGINT NOT NULL, | ||||
|     `MaxVoiceStateHours` BIGINT NOT NULL DEFAULT 6, | ||||
|     `XpPerMessage` BIGINT NOT NULL DEFAULT 1, | ||||
|     `XpPerReaction` BIGINT NOT NULL DEFAULT 1, | ||||
|     `MaxMessageXpPerHour` BIGINT NOT NULL DEFAULT 20, | ||||
|     `XpPerOntimeHour` BIGINT NOT NULL DEFAULT 10, | ||||
|     `XpPerEventParticipation` BIGINT NOT NULL DEFAULT 10, | ||||
|     `XpPerAchievement` BIGINT NOT NULL DEFAULT 10, | ||||
|     `AFKCommandChannelId` BIGINT NOT NULL, | ||||
|     `HelpVoiceChannelId` BIGINT NOT NULL, | ||||
|     `TeamChannelId` BIGINT NOT NULL, | ||||
|     `LoginMessageChannelId` BIGINT NOT NULL, | ||||
|     `ServerId` BIGINT NOT NULL, | ||||
|     `Deleted` BOOL DEFAULT FALSE, | ||||
|     `DateFrom` DATETIME(6) NOT NULL, | ||||
|     `DateTo` DATETIME(6) NOT NULL | ||||
| ); | ||||
|  | ||||
| DROP TRIGGER IF EXISTS `TR_CFG_ServerUpdate`; | ||||
|  | ||||
| CREATE TRIGGER `TR_CFG_ServerUpdate` | ||||
|     AFTER UPDATE | ||||
|     ON `CFG_Server` | ||||
|     FOR EACH ROW | ||||
| BEGIN | ||||
|     INSERT INTO `CFG_ServerHistory` ( | ||||
|         `Id`, | ||||
|         `MessageDeleteTimer`, | ||||
|         `NotificationChatId`, | ||||
|         `MaxVoiceStateHours`, | ||||
|         `XpPerMessage`, | ||||
|         `XpPerReaction`, | ||||
|         `MaxMessageXpPerHour`, | ||||
|         `XpPerOntimeHour`, | ||||
|         `XpPerEventParticipation`, | ||||
|         `XpPerAchievement`, | ||||
|         `AFKCommandChannelId`, | ||||
|         `HelpVoiceChannelId`, | ||||
|         `TeamChannelId`, | ||||
|         `LoginMessageChannelId`, | ||||
|         `ServerId`, | ||||
|         `DateFrom`, | ||||
|         `DateTo` | ||||
|     ) | ||||
|     VALUES ( | ||||
|         OLD.Id, | ||||
|         OLD.MessageDeleteTimer, | ||||
|         OLD.NotificationChatId, | ||||
|         OLD.MaxVoiceStateHours, | ||||
|         OLD.XpPerMessage, | ||||
|         OLD.XpPerReaction, | ||||
|         OLD.MaxMessageXpPerHour, | ||||
|         OLD.XpPerOntimeHour, | ||||
|         OLD.XpPerEventParticipation, | ||||
|         OLD.XpPerAchievement, | ||||
|         OLD.AFKCommandChannelId, | ||||
|         OLD.HelpVoiceChannelId, | ||||
|         OLD.TeamChannelId, | ||||
|         OLD.LoginMessageChannelId, | ||||
|         OLD.ServerId, | ||||
|         OLD.LastModifiedAt, | ||||
|         CURRENT_TIMESTAMP(6) | ||||
|     ); | ||||
| END; | ||||
|  | ||||
| DROP TRIGGER IF EXISTS `TR_CFG_ServerDelete`; | ||||
|  | ||||
| CREATE TRIGGER `TR_CFG_ServerDelete` | ||||
|     AFTER DELETE | ||||
|     ON `CFG_Server` | ||||
|     FOR EACH ROW | ||||
| BEGIN | ||||
|     INSERT INTO `CFG_ServerHistory` ( | ||||
|         `Id`, | ||||
|         `MessageDeleteTimer`, | ||||
|         `NotificationChatId`, | ||||
|         `MaxVoiceStateHours`, | ||||
|         `XpPerMessage`, | ||||
|         `XpPerReaction`, | ||||
|         `MaxMessageXpPerHour`, | ||||
|         `XpPerOntimeHour`, | ||||
|         `XpPerEventParticipation`, | ||||
|         `XpPerAchievement`, | ||||
|         `AFKCommandChannelId`, | ||||
|         `HelpVoiceChannelId`, | ||||
|         `TeamChannelId`, | ||||
|         `LoginMessageChannelId`, | ||||
|         `ServerId`, | ||||
|         `Deleted`, | ||||
|         `DateFrom`, | ||||
|         `DateTo` | ||||
|     ) | ||||
|     VALUES ( | ||||
|         OLD.Id, | ||||
|         OLD.MessageDeleteTimer, | ||||
|         OLD.NotificationChatId, | ||||
|         OLD.MaxVoiceStateHours, | ||||
|         OLD.XpPerMessage, | ||||
|         OLD.XpPerReaction, | ||||
|         OLD.MaxMessageXpPerHour, | ||||
|         OLD.XpPerOntimeHour, | ||||
|         OLD.XpPerEventParticipation, | ||||
|         OLD.XpPerAchievement, | ||||
|         OLD.AFKCommandChannelId, | ||||
|         OLD.HelpVoiceChannelId, | ||||
|         OLD.TeamChannelId, | ||||
|         OLD.LoginMessageChannelId, | ||||
|         OLD.ServerId, | ||||
|         TRUE, | ||||
|         OLD.LastModifiedAt, | ||||
|         CURRENT_TIMESTAMP(6) | ||||
|     ); | ||||
| END; | ||||
| @@ -0,0 +1,57 @@ | ||||
| CREATE TABLE IF NOT EXISTS `CFG_ServerAFKChannelIdsHistory` | ||||
| ( | ||||
|     `Id`    BIGINT(20)  NOT NULL, | ||||
|     `ChannelId` BIGINT NOT NULL, | ||||
|     `ServerId` BIGINT NOT NULL, | ||||
|     `Deleted` BOOL DEFAULT FALSE, | ||||
|     `DateFrom` DATETIME(6) NOT NULL, | ||||
|     `DateTo` DATETIME(6) NOT NULL | ||||
| ); | ||||
|  | ||||
| DROP TRIGGER IF EXISTS `TR_CFG_ServerAFKChannelIdsUpdate`; | ||||
|  | ||||
| CREATE TRIGGER `TR_CFG_ServerAFKChannelIdsUpdate` | ||||
|     AFTER UPDATE | ||||
|     ON `CFG_ServerAFKChannelIds` | ||||
|     FOR EACH ROW | ||||
| BEGIN | ||||
|     INSERT INTO `CFG_ServerAFKChannelIdsHistory` ( | ||||
|         `Id`, | ||||
|         `ChannelId`, | ||||
|         `ServerId`, | ||||
|         `DateFrom`, | ||||
|         `DateTo` | ||||
|     ) | ||||
|     VALUES ( | ||||
|         OLD.Id, | ||||
|         OLD.ChannelId, | ||||
|         OLD.ServerId, | ||||
|         OLD.LastModifiedAt, | ||||
|         CURRENT_TIMESTAMP(6) | ||||
|     ); | ||||
| END; | ||||
|  | ||||
| DROP TRIGGER IF EXISTS `TR_CFG_ServerAFKChannelIdsDelete`; | ||||
|  | ||||
| CREATE TRIGGER `TR_CFG_ServerAFKChannelIdsDelete` | ||||
|     AFTER DELETE | ||||
|     ON `CFG_ServerAFKChannelIds` | ||||
|     FOR EACH ROW | ||||
| BEGIN | ||||
|     INSERT INTO `CFG_ServerAFKChannelIdsHistory` ( | ||||
|         `Id`, | ||||
|         `ChannelId`, | ||||
|         `ServerId`, | ||||
|         `Deleted`, | ||||
|         `DateFrom`, | ||||
|         `DateTo` | ||||
|     ) | ||||
|     VALUES ( | ||||
|         OLD.Id, | ||||
|         OLD.ChannelId, | ||||
|         OLD.ServerId, | ||||
|         TRUE, | ||||
|         OLD.LastModifiedAt, | ||||
|         CURRENT_TIMESTAMP(6) | ||||
|     ); | ||||
| END; | ||||
| @@ -0,0 +1,62 @@ | ||||
| CREATE TABLE IF NOT EXISTS `CFG_ServerTeamRoleIdsHistory` | ||||
| ( | ||||
|     `Id`    BIGINT(20)  NOT NULL, | ||||
|     `RoleId` BIGINT NOT NULL, | ||||
|     `TeamMemberType` ENUM('Moderator', 'Admin') NOT NULL, | ||||
|     `ServerId` BIGINT NOT NULL, | ||||
|     `Deleted` BOOL DEFAULT FALSE, | ||||
|     `DateFrom` DATETIME(6) NOT NULL, | ||||
|     `DateTo` DATETIME(6) NOT NULL | ||||
| ); | ||||
|  | ||||
| DROP TRIGGER IF EXISTS `TR_CFG_ServerTeamRoleIdsUpdate`; | ||||
|  | ||||
| CREATE TRIGGER `TR_CFG_ServerTeamRoleIdsUpdate` | ||||
|     AFTER UPDATE | ||||
|     ON `CFG_ServerTeamRoleIds` | ||||
|     FOR EACH ROW | ||||
| BEGIN | ||||
|     INSERT INTO `CFG_ServerTeamRoleIdsHistory` ( | ||||
|         `Id`, | ||||
|         `RoleId`, | ||||
|         `TeamMemberType`, | ||||
|         `ServerId`, | ||||
|         `DateFrom`, | ||||
|         `DateTo` | ||||
|     ) | ||||
|     VALUES ( | ||||
|         OLD.Id, | ||||
|         OLD.RoleId, | ||||
|         OLD.TeamMemberType, | ||||
|         OLD.ServerId, | ||||
|         OLD.LastModifiedAt, | ||||
|         CURRENT_TIMESTAMP(6) | ||||
|     ); | ||||
| END; | ||||
|  | ||||
| DROP TRIGGER IF EXISTS `TR_CFG_ServerTeamRoleIdsDelete`; | ||||
|  | ||||
| CREATE TRIGGER `TR_CFG_ServerTeamRoleIdsDelete` | ||||
|     AFTER DELETE | ||||
|     ON `CFG_ServerTeamRoleIds` | ||||
|     FOR EACH ROW | ||||
| BEGIN | ||||
|     INSERT INTO `CFG_ServerTeamRoleIdsHistory` ( | ||||
|         `Id`, | ||||
|         `RoleId`, | ||||
|         `TeamMemberType`, | ||||
|         `ServerId`, | ||||
|         `Deleted`, | ||||
|         `DateFrom`, | ||||
|         `DateTo` | ||||
|     ) | ||||
|     VALUES ( | ||||
|         OLD.Id, | ||||
|         OLD.RoleId, | ||||
|         OLD.TeamMemberType, | ||||
|         OLD.ServerId, | ||||
|         TRUE, | ||||
|         OLD.LastModifiedAt, | ||||
|         CURRENT_TIMESTAMP(6) | ||||
|     ); | ||||
| END; | ||||
| @@ -0,0 +1,67 @@ | ||||
| CREATE TABLE IF NOT EXISTS `CFG_TechnicianHistory` | ||||
| ( | ||||
|     `Id`    BIGINT(20)  NOT NULL, | ||||
|     `HelpCommandReferenceUrl` VARCHAR(255) NOT NULL, | ||||
|     `WaitForRestart` BIGINT NOT NULL DEFAULT 8, | ||||
|     `WaitForShutdown` BIGINT NOT NULL DEFAULT 8, | ||||
|     `CacheMaxMessages` BIGINT NOT NULL DEFAULT 1000000, | ||||
|     `Deleted` BOOL DEFAULT FALSE, | ||||
|     `DateFrom` DATETIME(6) NOT NULL, | ||||
|     `DateTo` DATETIME(6) NOT NULL | ||||
| ); | ||||
|  | ||||
| DROP TRIGGER IF EXISTS `TR_CFG_TechnicianUpdate`; | ||||
|  | ||||
| CREATE TRIGGER `TR_CFG_TechnicianUpdate` | ||||
|     AFTER UPDATE | ||||
|     ON `CFG_Technician` | ||||
|     FOR EACH ROW | ||||
| BEGIN | ||||
|     INSERT INTO `CFG_TechnicianHistory` ( | ||||
|         `Id`, | ||||
|         `HelpCommandReferenceUrl`, | ||||
|         `WaitForRestart`, | ||||
|         `WaitForShutdown`, | ||||
|         `CacheMaxMessages`, | ||||
|         `DateFrom`, | ||||
|         `DateTo` | ||||
|     ) | ||||
|     VALUES ( | ||||
|         OLD.Id, | ||||
|         OLD.HelpCommandReferenceUrl, | ||||
|         OLD.WaitForRestart, | ||||
|         OLD.WaitForShutdown, | ||||
|         OLD.CacheMaxMessages, | ||||
|         OLD.LastModifiedAt, | ||||
|         CURRENT_TIMESTAMP(6) | ||||
|     ); | ||||
| END; | ||||
|  | ||||
| DROP TRIGGER IF EXISTS `TR_CFG_TechnicianDelete`; | ||||
|  | ||||
| CREATE TRIGGER `TR_CFG_TechnicianDelete` | ||||
|     AFTER DELETE | ||||
|     ON `CFG_Technician` | ||||
|     FOR EACH ROW | ||||
| BEGIN | ||||
|     INSERT INTO `CFG_TechnicianHistory` ( | ||||
|         `Id`, | ||||
|         `HelpCommandReferenceUrl`, | ||||
|         `WaitForRestart`, | ||||
|         `WaitForShutdown`, | ||||
|         `CacheMaxMessages`, | ||||
|         `Deleted`, | ||||
|         `DateFrom`, | ||||
|         `DateTo` | ||||
|     ) | ||||
|     VALUES ( | ||||
|         OLD.Id, | ||||
|         OLD.HelpCommandReferenceUrl, | ||||
|         OLD.WaitForRestart, | ||||
|         OLD.WaitForShutdown, | ||||
|         OLD.CacheMaxMessages, | ||||
|         TRUE, | ||||
|         OLD.LastModifiedAt, | ||||
|         CURRENT_TIMESTAMP(6) | ||||
|     ); | ||||
| END; | ||||
| @@ -0,0 +1,52 @@ | ||||
| CREATE TABLE IF NOT EXISTS `CFG_TechnicianIdsHistory` | ||||
| ( | ||||
|     `Id`    BIGINT(20)  NOT NULL, | ||||
|     `TechnicianId` BIGINT NOT NULL, | ||||
|     `Deleted` BOOL DEFAULT FALSE, | ||||
|     `DateFrom` DATETIME(6) NOT NULL, | ||||
|     `DateTo` DATETIME(6) NOT NULL | ||||
| ); | ||||
|  | ||||
| DROP TRIGGER IF EXISTS `TR_CFG_TechnicianIdsUpdate`; | ||||
|  | ||||
| CREATE TRIGGER `TR_CFG_TechnicianIdsUpdate` | ||||
|     AFTER UPDATE | ||||
|     ON `CFG_TechnicianIds` | ||||
|     FOR EACH ROW | ||||
| BEGIN | ||||
|     INSERT INTO `CFG_TechnicianIdsHistory` ( | ||||
|         `Id`, | ||||
|         `TechnicianId`, | ||||
|         `DateFrom`, | ||||
|         `DateTo` | ||||
|     ) | ||||
|     VALUES ( | ||||
|         OLD.Id, | ||||
|         OLD.TechnicianId, | ||||
|         OLD.LastModifiedAt, | ||||
|         CURRENT_TIMESTAMP(6) | ||||
|     ); | ||||
| END; | ||||
|  | ||||
| DROP TRIGGER IF EXISTS `TR_CFG_TechnicianIdsDelete`; | ||||
|  | ||||
| CREATE TRIGGER `TR_CFG_TechnicianIdsDelete` | ||||
|     AFTER DELETE | ||||
|     ON `CFG_TechnicianIds` | ||||
|     FOR EACH ROW | ||||
| BEGIN | ||||
|     INSERT INTO `CFG_TechnicianIdsHistory` ( | ||||
|         `Id`, | ||||
|         `TechnicianId`, | ||||
|         `Deleted`, | ||||
|         `DateFrom`, | ||||
|         `DateTo` | ||||
|     ) | ||||
|     VALUES ( | ||||
|         OLD.Id, | ||||
|         OLD.TechnicianId, | ||||
|         TRUE, | ||||
|         OLD.LastModifiedAt, | ||||
|         CURRENT_TIMESTAMP(6) | ||||
|     ); | ||||
| END; | ||||
| @@ -0,0 +1,52 @@ | ||||
| CREATE TABLE IF NOT EXISTS `CFG_TechnicianPingUrlsHistory` | ||||
| ( | ||||
|     `Id`    BIGINT(20)  NOT NULL, | ||||
|     `URL` VARCHAR(255) NOT NULL, | ||||
|     `Deleted` BOOL DEFAULT FALSE, | ||||
|     `DateFrom` DATETIME(6) NOT NULL, | ||||
|     `DateTo` DATETIME(6) NOT NULL | ||||
| ); | ||||
|  | ||||
| DROP TRIGGER IF EXISTS `TR_CFG_TechnicianPingUrlsUpdate`; | ||||
|  | ||||
| CREATE TRIGGER `TR_CFG_TechnicianPingUrlsUpdate` | ||||
|     AFTER UPDATE | ||||
|     ON `CFG_TechnicianPingUrls` | ||||
|     FOR EACH ROW | ||||
| BEGIN | ||||
|     INSERT INTO `CFG_TechnicianPingUrlsHistory` ( | ||||
|         `Id`, | ||||
|         `URL`, | ||||
|         `DateFrom`, | ||||
|         `DateTo` | ||||
|     ) | ||||
|     VALUES ( | ||||
|         OLD.Id, | ||||
|         OLD.URL, | ||||
|         OLD.LastModifiedAt, | ||||
|         CURRENT_TIMESTAMP(6) | ||||
|     ); | ||||
| END; | ||||
|  | ||||
| DROP TRIGGER IF EXISTS `TR_CFG_TechnicianPingUrlsDelete`; | ||||
|  | ||||
| CREATE TRIGGER `TR_CFG_TechnicianPingUrlsDelete` | ||||
|     AFTER DELETE | ||||
|     ON `CFG_TechnicianPingUrls` | ||||
|     FOR EACH ROW | ||||
| BEGIN | ||||
|     INSERT INTO `CFG_TechnicianPingUrlsHistory` ( | ||||
|         `Id`, | ||||
|         `URL`, | ||||
|         `Deleted`, | ||||
|         `DateFrom`, | ||||
|         `DateTo` | ||||
|     ) | ||||
|     VALUES ( | ||||
|         OLD.Id, | ||||
|         OLD.URL, | ||||
|         TRUE, | ||||
|         OLD.LastModifiedAt, | ||||
|         CURRENT_TIMESTAMP(6) | ||||
|     ); | ||||
| END; | ||||
							
								
								
									
										34
									
								
								kdb-bot/src/bot_data/migration/default_role_migration.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								kdb-bot/src/bot_data/migration/default_role_migration.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| from bot_core.logging.database_logger import DatabaseLogger | ||||
| from bot_data.abc.migration_abc import MigrationABC | ||||
| from bot_data.db_context import DBContext | ||||
|  | ||||
|  | ||||
| class DefaultRoleMigration(MigrationABC): | ||||
|     name = "1.1.3_DefaultRoleMigration" | ||||
|  | ||||
|     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""" | ||||
|                     ALTER TABLE CFG_Server | ||||
|                     ADD DefaultRoleId BIGINT NULL AFTER LoginMessageChannelId; | ||||
|                 """ | ||||
|             ) | ||||
|         ) | ||||
|  | ||||
|     def downgrade(self): | ||||
|         self._cursor.execute( | ||||
|             str( | ||||
|                 f""" | ||||
|                     ALTER TABLE CFG_Server DROP COLUMN DefaultRoleId; | ||||
|                 """ | ||||
|             ) | ||||
|         ) | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_data.model" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.0.7" | ||||
| __version__ = "1.1.5" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="0", micro="7") | ||||
| version_info = VersionInfo(major="1", minor="1", micro="5") | ||||
|   | ||||
							
								
								
									
										158
									
								
								kdb-bot/src/bot_data/model/achievement.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								kdb-bot/src/bot_data/model/achievement.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,158 @@ | ||||
| from datetime import datetime | ||||
| from typing import Optional | ||||
|  | ||||
| from cpl_core.database import TableABC | ||||
| from cpl_core.dependency_injection import ServiceProviderABC | ||||
|  | ||||
| from bot_data.model.server import Server | ||||
|  | ||||
|  | ||||
| class Achievement(TableABC): | ||||
|     def __init__( | ||||
|         self, | ||||
|         name: str, | ||||
|         description: str, | ||||
|         attribute: str, | ||||
|         operator: str, | ||||
|         value: str, | ||||
|         server: Optional[Server], | ||||
|         created_at: datetime = None, | ||||
|         modified_at: datetime = None, | ||||
|         id=0, | ||||
|     ): | ||||
|         self._id = id | ||||
|         self._name = name | ||||
|         self._description = description | ||||
|         self._attribute = attribute | ||||
|  | ||||
|         if self._is_operator_valid(operator): | ||||
|             raise ValueError("Operator invalid") | ||||
|  | ||||
|         self._operator = operator | ||||
|         self._value = value | ||||
|         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 | ||||
|  | ||||
|     @ServiceProviderABC.inject | ||||
|     def _is_operator_valid(self, operator, service: ServiceProviderABC) -> bool: | ||||
|         from modules.achievements.achievement_service import AchievementService | ||||
|  | ||||
|         achievements: AchievementService = service.get_service(AchievementService) | ||||
|         return operator not in achievements.get_operators() | ||||
|  | ||||
|     @property | ||||
|     def id(self) -> int: | ||||
|         return self._id | ||||
|  | ||||
|     @property | ||||
|     def name(self) -> str: | ||||
|         return self._name | ||||
|  | ||||
|     @name.setter | ||||
|     def name(self, value: str): | ||||
|         self._name = value | ||||
|  | ||||
|     @property | ||||
|     def description(self) -> str: | ||||
|         return self._description | ||||
|  | ||||
|     @description.setter | ||||
|     def description(self, value: str): | ||||
|         self._description = value | ||||
|  | ||||
|     @property | ||||
|     def attribute(self) -> str: | ||||
|         return self._attribute | ||||
|  | ||||
|     @attribute.setter | ||||
|     def attribute(self, value: str): | ||||
|         self._attribute = value | ||||
|  | ||||
|     @property | ||||
|     def operator(self) -> str: | ||||
|         return self._operator | ||||
|  | ||||
|     @operator.setter | ||||
|     def operator(self, value: str): | ||||
|         self._operator = value | ||||
|  | ||||
|     @property | ||||
|     def value(self) -> str: | ||||
|         return self._value | ||||
|  | ||||
|     @value.setter | ||||
|     def value(self, value: str): | ||||
|         self._value = value | ||||
|  | ||||
|     @property | ||||
|     def server(self) -> Server: | ||||
|         return self._server | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_select_all_string() -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|             SELECT * FROM `Achievements`; | ||||
|         """ | ||||
|         ) | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_select_by_id_string(id: int) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|             SELECT * FROM `Achievements` | ||||
|             WHERE `Id` = {id}; | ||||
|         """ | ||||
|         ) | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_select_by_server_id_string(id: int) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|             SELECT * FROM `Achievements` | ||||
|             WHERE `ServerId` = {id}; | ||||
|         """ | ||||
|         ) | ||||
|  | ||||
|     @property | ||||
|     def insert_string(self) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|             INSERT INTO `Achievements` ( | ||||
|                 `Name`, `Description`, `Attribute`, `Operator`, `Value`, `ServerId` | ||||
|             ) VALUES ( | ||||
|                 '{self._name}', | ||||
|                 '{self._description}', | ||||
|                 '{self._attribute}', | ||||
|                 '{self._operator}', | ||||
|                 '{self._value}', | ||||
|                 {self._server.id} | ||||
|             ); | ||||
|         """ | ||||
|         ) | ||||
|  | ||||
|     @property | ||||
|     def udpate_string(self) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                     UPDATE `Achievements` | ||||
|                     SET `Name` = '{self._name}', | ||||
|                     `Description` = '{self._description}', | ||||
|                     `Attribute` = '{self._attribute}', | ||||
|                     `Operator` = '{self._operator}', | ||||
|                     `Value` = '{self._value}' | ||||
|                     WHERE `Id` = {self._id}; | ||||
|                 """ | ||||
|         ) | ||||
|  | ||||
|     @property | ||||
|     def delete_string(self) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|             DELETE FROM `Achievements` | ||||
|             WHERE `Id` = {self._id}; | ||||
|         """ | ||||
|         ) | ||||
							
								
								
									
										58
									
								
								kdb-bot/src/bot_data/model/achievement_history.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								kdb-bot/src/bot_data/model/achievement_history.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,58 @@ | ||||
| from bot_data.abc.history_table_abc import HistoryTableABC | ||||
|  | ||||
|  | ||||
| class AchievementHistory(HistoryTableABC): | ||||
|     def __init__( | ||||
|         self, | ||||
|         name: str, | ||||
|         description: str, | ||||
|         attribute: str, | ||||
|         operator: str, | ||||
|         value: str, | ||||
|         server: int, | ||||
|         deleted: bool, | ||||
|         date_from: str, | ||||
|         date_to: str, | ||||
|         id=0, | ||||
|     ): | ||||
|         HistoryTableABC.__init__(self) | ||||
|  | ||||
|         self._id = id | ||||
|         self._name = name | ||||
|         self._description = description | ||||
|         self._attribute = attribute | ||||
|         self._operator = operator | ||||
|         self._value = value | ||||
|         self._server = server | ||||
|  | ||||
|         self._deleted = deleted | ||||
|         self._date_from = date_from | ||||
|         self._date_to = date_to | ||||
|  | ||||
|     @property | ||||
|     def id(self) -> int: | ||||
|         return self._id | ||||
|  | ||||
|     @property | ||||
|     def name(self) -> str: | ||||
|         return self._name | ||||
|  | ||||
|     @property | ||||
|     def description(self) -> str: | ||||
|         return self._description | ||||
|  | ||||
|     @property | ||||
|     def attribute(self) -> str: | ||||
|         return self._attribute | ||||
|  | ||||
|     @property | ||||
|     def operator(self) -> str: | ||||
|         return self._operator | ||||
|  | ||||
|     @property | ||||
|     def value(self) -> str: | ||||
|         return self._value | ||||
|  | ||||
|     @property | ||||
|     def server(self) -> int: | ||||
|         return self._server | ||||
							
								
								
									
										85
									
								
								kdb-bot/src/bot_data/model/server_afk_channel_ids_config.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								kdb-bot/src/bot_data/model/server_afk_channel_ids_config.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,85 @@ | ||||
| from datetime import datetime | ||||
|  | ||||
| from cpl_core.database import TableABC | ||||
|  | ||||
|  | ||||
| class ServerAFKChannelIdsConfig(TableABC): | ||||
|     def __init__( | ||||
|         self, | ||||
|         channel_id: int, | ||||
|         server_id: int, | ||||
|         created_at: datetime = None, | ||||
|         modified_at: datetime = None, | ||||
|         id=0, | ||||
|     ): | ||||
|         self._id = id | ||||
|         self._channel_id = channel_id | ||||
|         self._server_id = server_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 channel_id(self) -> int: | ||||
|         return self._channel_id | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_select_all_string() -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 SELECT * FROM `CFG_ServerAFKChannelIds`; | ||||
|             """ | ||||
|         ) | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_select_by_id_string(id: int) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 SELECT * FROM `CFG_ServerAFKChannelIds` | ||||
|                 WHERE `Id` = {id}; | ||||
|             """ | ||||
|         ) | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_select_by_server_id_string(server_id: int) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 SELECT * FROM `CFG_ServerAFKChannelIds` | ||||
|                 WHERE `ServerId` = {server_id}; | ||||
|             """ | ||||
|         ) | ||||
|  | ||||
|     @property | ||||
|     def insert_string(self) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 INSERT INTO `CFG_ServerAFKChannelIds` ( | ||||
|                     `ChannelId`, | ||||
|                     `ServerId` | ||||
|                 ) VALUES ( | ||||
|                     {self._channel_id}, | ||||
|                     {self._server_id} | ||||
|                 ); | ||||
|             """ | ||||
|         ) | ||||
|  | ||||
|     @property | ||||
|     def udpate_string(self) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 UPDATE `CFG_ServerAFKChannelIds` | ||||
|                 SET `ChannelId` = {self._channel_id}, | ||||
|                 `ServerId` = {self._server_id} | ||||
|                 WHERE `Id` = {self._id}; | ||||
|             """ | ||||
|         ) | ||||
|  | ||||
|     @property | ||||
|     def delete_string(self) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 DELETE FROM `CFG_ServerAFKChannelIds` | ||||
|                 WHERE `ChannelId` = {self._channel_id}; | ||||
|             """ | ||||
|         ) | ||||
							
								
								
									
										306
									
								
								kdb-bot/src/bot_data/model/server_config.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										306
									
								
								kdb-bot/src/bot_data/model/server_config.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,306 @@ | ||||
| import json | ||||
| from datetime import datetime | ||||
|  | ||||
| from cpl_core.configuration import ConfigurationModelABC | ||||
| from cpl_core.database import TableABC | ||||
| from cpl_query.extension import List | ||||
|  | ||||
| from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum | ||||
| from bot_data.model.server import Server | ||||
| from bot_data.model.server_team_role_ids_config import ServerTeamRoleIdsConfig | ||||
|  | ||||
|  | ||||
| class ServerConfig(TableABC, ConfigurationModelABC): | ||||
|     def __init__( | ||||
|         self, | ||||
|         message_delete_timer: int, | ||||
|         notification_chat_id: int, | ||||
|         max_voice_state_hours: int, | ||||
|         xp_per_message: int, | ||||
|         xp_per_reaction: int, | ||||
|         max_message_xp_per_hour: int, | ||||
|         xp_per_ontime_hour: int, | ||||
|         xp_per_event_participation: int, | ||||
|         xp_per_achievement: int, | ||||
|         afk_command_channel_id: int, | ||||
|         help_voice_channel_id: int, | ||||
|         team_channel_id: int, | ||||
|         login_message_channel_id: int, | ||||
|         default_role_id: int, | ||||
|         feature_flags: dict[FeatureFlagsEnum], | ||||
|         server: Server, | ||||
|         afk_channel_ids: List[int], | ||||
|         team_role_ids: List[ServerTeamRoleIdsConfig], | ||||
|         created_at: datetime = None, | ||||
|         modified_at: datetime = None, | ||||
|         id=0, | ||||
|     ): | ||||
|         self._id = id | ||||
|         self._message_delete_timer = message_delete_timer | ||||
|         self._notification_chat_id = notification_chat_id | ||||
|         self._max_voice_state_hours = max_voice_state_hours | ||||
|         self._xp_per_message = xp_per_message | ||||
|         self._xp_per_reaction = xp_per_reaction | ||||
|         self._max_message_xp_per_hour = max_message_xp_per_hour | ||||
|         self._xp_per_ontime_hour = xp_per_ontime_hour | ||||
|         self._xp_per_event_participation = xp_per_event_participation | ||||
|         self._xp_per_achievement = xp_per_achievement | ||||
|         self._afk_command_channel_id = afk_command_channel_id | ||||
|         self._help_voice_channel_id = help_voice_channel_id | ||||
|         self._team_channel_id = team_channel_id | ||||
|         self._login_message_channel_id = login_message_channel_id | ||||
|         self._default_role_id = default_role_id | ||||
|         self._feature_flags = feature_flags | ||||
|         self._server = server | ||||
|         self._afk_channel_ids = afk_channel_ids | ||||
|         self._team_role_ids = team_role_ids | ||||
|  | ||||
|         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 message_delete_timer(self) -> int: | ||||
|         return self._message_delete_timer | ||||
|  | ||||
|     @message_delete_timer.setter | ||||
|     def message_delete_timer(self, value: int): | ||||
|         self._message_delete_timer = value | ||||
|  | ||||
|     @property | ||||
|     def notification_chat_id(self) -> int: | ||||
|         return self._notification_chat_id | ||||
|  | ||||
|     @notification_chat_id.setter | ||||
|     def notification_chat_id(self, value: int): | ||||
|         self._notification_chat_id = value | ||||
|  | ||||
|     @property | ||||
|     def max_voice_state_hours(self) -> int: | ||||
|         return self._max_voice_state_hours | ||||
|  | ||||
|     @max_voice_state_hours.setter | ||||
|     def max_voice_state_hours(self, value: int): | ||||
|         self._max_voice_state_hours = value | ||||
|  | ||||
|     @property | ||||
|     def xp_per_message(self) -> int: | ||||
|         return self._xp_per_message | ||||
|  | ||||
|     @xp_per_message.setter | ||||
|     def xp_per_message(self, value: int): | ||||
|         self._xp_per_message = value | ||||
|  | ||||
|     @property | ||||
|     def xp_per_reaction(self) -> int: | ||||
|         return self._xp_per_reaction | ||||
|  | ||||
|     @xp_per_reaction.setter | ||||
|     def xp_per_reaction(self, value: int): | ||||
|         self._xp_per_reaction = value | ||||
|  | ||||
|     @property | ||||
|     def max_message_xp_per_hour(self) -> int: | ||||
|         return self._max_message_xp_per_hour | ||||
|  | ||||
|     @max_message_xp_per_hour.setter | ||||
|     def max_message_xp_per_hour(self, value: int): | ||||
|         self._max_message_xp_per_hour = value | ||||
|  | ||||
|     @property | ||||
|     def xp_per_ontime_hour(self) -> int: | ||||
|         return self._xp_per_ontime_hour | ||||
|  | ||||
|     @xp_per_ontime_hour.setter | ||||
|     def xp_per_ontime_hour(self, value: int): | ||||
|         self._xp_per_ontime_hour = value | ||||
|  | ||||
|     @property | ||||
|     def xp_per_event_participation(self) -> int: | ||||
|         return self._xp_per_event_participation | ||||
|  | ||||
|     @xp_per_event_participation.setter | ||||
|     def xp_per_event_participation(self, value: int): | ||||
|         self._xp_per_event_participation = value | ||||
|  | ||||
|     @property | ||||
|     def xp_per_achievement(self) -> int: | ||||
|         return self._xp_per_achievement | ||||
|  | ||||
|     @xp_per_achievement.setter | ||||
|     def xp_per_achievement(self, value: int): | ||||
|         self._xp_per_achievement = value | ||||
|  | ||||
|     @property | ||||
|     def afk_command_channel_id(self) -> int: | ||||
|         return self._afk_command_channel_id | ||||
|  | ||||
|     @afk_command_channel_id.setter | ||||
|     def afk_command_channel_id(self, value: int): | ||||
|         self._afk_command_channel_id = value | ||||
|  | ||||
|     @property | ||||
|     def help_voice_channel_id(self) -> int: | ||||
|         return self._help_voice_channel_id | ||||
|  | ||||
|     @help_voice_channel_id.setter | ||||
|     def help_voice_channel_id(self, value: int): | ||||
|         self._help_voice_channel_id = value | ||||
|  | ||||
|     @property | ||||
|     def team_channel_id(self) -> int: | ||||
|         return self._team_channel_id | ||||
|  | ||||
|     @team_channel_id.setter | ||||
|     def team_channel_id(self, value: int): | ||||
|         self._team_channel_id = value | ||||
|  | ||||
|     @property | ||||
|     def login_message_channel_id(self) -> int: | ||||
|         return self._login_message_channel_id | ||||
|  | ||||
|     @login_message_channel_id.setter | ||||
|     def login_message_channel_id(self, value: int): | ||||
|         self._login_message_channel_id = value | ||||
|  | ||||
|     @property | ||||
|     def default_role_id(self) -> int: | ||||
|         return self._default_role_id | ||||
|  | ||||
|     @default_role_id.setter | ||||
|     def default_role_id(self, value: int): | ||||
|         self._default_role_id = value | ||||
|  | ||||
|     @property | ||||
|     def feature_flags(self) -> dict[FeatureFlagsEnum]: | ||||
|         return self._feature_flags | ||||
|  | ||||
|     @feature_flags.setter | ||||
|     def feature_flags(self, value: dict[FeatureFlagsEnum]): | ||||
|         self._feature_flags = value | ||||
|  | ||||
|     @property | ||||
|     def afk_channel_ids(self) -> List[int]: | ||||
|         return self._afk_channel_ids | ||||
|  | ||||
|     @afk_channel_ids.setter | ||||
|     def afk_channel_ids(self, value: List[int]): | ||||
|         self._afk_channel_ids = value | ||||
|  | ||||
|     @property | ||||
|     def team_role_ids(self) -> List[ServerTeamRoleIdsConfig]: | ||||
|         return self._team_role_ids | ||||
|  | ||||
|     @team_role_ids.setter | ||||
|     def team_role_ids(self, value: List[ServerTeamRoleIdsConfig]): | ||||
|         self._team_role_ids = value | ||||
|  | ||||
|     @property | ||||
|     def server(self) -> Server: | ||||
|         return self._server | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_select_all_string() -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 SELECT * FROM `CFG_Server`; | ||||
|             """ | ||||
|         ) | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_select_by_id_string(id: int) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 SELECT * FROM `CFG_Server` | ||||
|                 WHERE `Id` = {id}; | ||||
|             """ | ||||
|         ) | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_select_by_server_id_string(server_id: int) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 SELECT * FROM `CFG_Server` | ||||
|                 WHERE `ServerId` = {server_id}; | ||||
|             """ | ||||
|         ) | ||||
|  | ||||
|     @property | ||||
|     def insert_string(self) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 INSERT INTO `CFG_Server` ( | ||||
|                     `MessageDeleteTimer`, | ||||
|                     `NotificationChatId`, | ||||
|                     `MaxVoiceStateHours`, | ||||
|                     `XpPerMessage`, | ||||
|                     `XpPerReaction`, | ||||
|                     `MaxMessageXpPerHour`, | ||||
|                     `XpPerOntimeHour`, | ||||
|                     `XpPerEventParticipation`, | ||||
|                     `XpPerAchievement`, | ||||
|                     `AFKCommandChannelId`, | ||||
|                     `HelpVoiceChannelId`, | ||||
|                     `TeamChannelId`, | ||||
|                     `LoginMessageChannelId`, | ||||
|                     `DefaultRoleId`, | ||||
|                     `FeatureFlags`, | ||||
|                     `ServerId` | ||||
|                 ) VALUES ( | ||||
|                     {self._message_delete_timer}, | ||||
|                     {self._notification_chat_id}, | ||||
|                     {self._max_voice_state_hours}, | ||||
|                     {self._xp_per_message}, | ||||
|                     {self._xp_per_reaction}, | ||||
|                     {self._max_message_xp_per_hour}, | ||||
|                     {self._xp_per_ontime_hour}, | ||||
|                     {self._xp_per_event_participation}, | ||||
|                     {self._xp_per_achievement}, | ||||
|                     {self._afk_command_channel_id}, | ||||
|                     {self._help_voice_channel_id}, | ||||
|                     {self._team_channel_id}, | ||||
|                     {self._login_message_channel_id}, | ||||
|                     {self._default_role_id}, | ||||
|                     '{json.dumps(self._feature_flags)}', | ||||
|                     {self._server.id} | ||||
|                 ); | ||||
|             """ | ||||
|         ) | ||||
|  | ||||
|     @property | ||||
|     def udpate_string(self) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 UPDATE `CFG_Server` | ||||
|                 SET `MessageDeleteTimer` = {self._message_delete_timer}, | ||||
|                 `NotificationChatId` = {self._notification_chat_id}, | ||||
|                 `MaxVoiceStateHours` = {self._max_voice_state_hours}, | ||||
|                 `XpPerMessage` = {self._xp_per_message}, | ||||
|                 `XpPerReaction` = {self._xp_per_reaction}, | ||||
|                 `MaxMessageXpPerHour` = {self._max_message_xp_per_hour}, | ||||
|                 `XpPerOntimeHour` = {self._xp_per_ontime_hour}, | ||||
|                 `XpPerEventParticipation` = {self._xp_per_event_participation}, | ||||
|                 `XpPerAchievement` = {self._xp_per_achievement}, | ||||
|                 `AFKCommandChannelId` = {self._afk_command_channel_id}, | ||||
|                 `HelpVoiceChannelId` = {self._help_voice_channel_id}, | ||||
|                 `TeamChannelId` = {self._team_channel_id}, | ||||
|                 `LoginMessageChannelId` = {self._login_message_channel_id}, | ||||
|                 `DefaultRoleId` = {self._default_role_id}, | ||||
|                 `FeatureFlags` = '{json.dumps(self._feature_flags)}', | ||||
|                 `ServerId` = {self._server.id} | ||||
|                 WHERE `Id` = {self._id}; | ||||
|             """ | ||||
|         ) | ||||
|  | ||||
|     @property | ||||
|     def delete_string(self) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 DELETE FROM `CFG_Server` | ||||
|                 WHERE `Id` = {self._id}; | ||||
|             """ | ||||
|         ) | ||||
							
								
								
									
										114
									
								
								kdb-bot/src/bot_data/model/server_config_history.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								kdb-bot/src/bot_data/model/server_config_history.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,114 @@ | ||||
| from bot_data.abc.history_table_abc import HistoryTableABC | ||||
|  | ||||
|  | ||||
| class ServerConfigHistory(HistoryTableABC): | ||||
|     def __init__( | ||||
|         self, | ||||
|         message_delete_timer: int, | ||||
|         notification_chat_id: int, | ||||
|         max_voice_state_hours: int, | ||||
|         xp_per_message: int, | ||||
|         xp_per_reaction: int, | ||||
|         max_message_xp_per_hour: int, | ||||
|         xp_per_ontime_hour: int, | ||||
|         xp_per_event_participation: int, | ||||
|         xp_per_achievement: int, | ||||
|         afk_command_channel_id: int, | ||||
|         help_voice_channel_id: int, | ||||
|         team_channel_id: int, | ||||
|         login_message_channel_id: int, | ||||
|         default_role_id: int, | ||||
|         feature_flags: dict[str], | ||||
|         server_id: int, | ||||
|         deleted: bool, | ||||
|         date_from: str, | ||||
|         date_to: str, | ||||
|         id=0, | ||||
|     ): | ||||
|         HistoryTableABC.__init__(self) | ||||
|  | ||||
|         self._id = id | ||||
|         self._message_delete_timer = message_delete_timer | ||||
|         self._notification_chat_id = notification_chat_id | ||||
|         self._max_voice_state_hours = max_voice_state_hours | ||||
|         self._xp_per_message = xp_per_message | ||||
|         self._xp_per_reaction = xp_per_reaction | ||||
|         self._max_message_xp_per_hour = max_message_xp_per_hour | ||||
|         self._xp_per_ontime_hour = xp_per_ontime_hour | ||||
|         self._xp_per_event_participation = xp_per_event_participation | ||||
|         self._xp_per_achievement = xp_per_achievement | ||||
|         self._afk_command_channel_id = afk_command_channel_id | ||||
|         self._help_voice_channel_id = help_voice_channel_id | ||||
|         self._team_channel_id = team_channel_id | ||||
|         self._login_message_channel_id = login_message_channel_id | ||||
|         self._default_role_id = default_role_id | ||||
|         self._feature_flags = feature_flags | ||||
|         self._server_id = server_id | ||||
|  | ||||
|         self._deleted = deleted | ||||
|         self._date_from = date_from | ||||
|         self._date_to = date_to | ||||
|  | ||||
|     @property | ||||
|     def message_delete_timer(self) -> int: | ||||
|         return self._message_delete_timer | ||||
|  | ||||
|     @property | ||||
|     def notification_chat_id(self) -> int: | ||||
|         return self._notification_chat_id | ||||
|  | ||||
|     @property | ||||
|     def max_voice_state_hours(self) -> int: | ||||
|         return self._max_voice_state_hours | ||||
|  | ||||
|     @property | ||||
|     def xp_per_message(self) -> int: | ||||
|         return self._xp_per_message | ||||
|  | ||||
|     @property | ||||
|     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 | ||||
|  | ||||
|     @property | ||||
|     def xp_per_event_participation(self) -> int: | ||||
|         return self._xp_per_event_participation | ||||
|  | ||||
|     @property | ||||
|     def xp_per_achievement(self) -> int: | ||||
|         return self._xp_per_achievement | ||||
|  | ||||
|     @property | ||||
|     def afk_command_channel_id(self) -> int: | ||||
|         return self._afk_command_channel_id | ||||
|  | ||||
|     @property | ||||
|     def help_voice_channel_id(self) -> int: | ||||
|         return self._help_voice_channel_id | ||||
|  | ||||
|     @property | ||||
|     def team_channel_id(self) -> int: | ||||
|         return self._team_channel_id | ||||
|  | ||||
|     @property | ||||
|     def login_message_channel_id(self) -> int: | ||||
|         return self._login_message_channel_id | ||||
|  | ||||
|     @property | ||||
|     def default_role_id(self) -> int: | ||||
|         return self._default_role_id | ||||
|  | ||||
|     @property | ||||
|     def feature_flags(self) -> dict[str]: | ||||
|         return self._feature_flags | ||||
|  | ||||
|     @property | ||||
|     def server_id(self) -> int: | ||||
|         return self._server_id | ||||
							
								
								
									
										100
									
								
								kdb-bot/src/bot_data/model/server_team_role_ids_config.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								kdb-bot/src/bot_data/model/server_team_role_ids_config.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,100 @@ | ||||
| from datetime import datetime | ||||
|  | ||||
| from cpl_core.database import TableABC | ||||
|  | ||||
| from bot_data.model.team_member_type_enum import TeamMemberTypeEnum | ||||
|  | ||||
|  | ||||
| class ServerTeamRoleIdsConfig(TableABC): | ||||
|     def __init__( | ||||
|         self, | ||||
|         role_id: int, | ||||
|         team_member_type: TeamMemberTypeEnum, | ||||
|         server_id: int, | ||||
|         created_at: datetime = None, | ||||
|         modified_at: datetime = None, | ||||
|         id=0, | ||||
|     ): | ||||
|         self._id = id | ||||
|         self._role_id = role_id | ||||
|         self._team_member_type = team_member_type | ||||
|         self._server_id = server_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 id(self) -> int: | ||||
|         return self._id | ||||
|  | ||||
|     @property | ||||
|     def role_id(self) -> int: | ||||
|         return self._role_id | ||||
|  | ||||
|     @property | ||||
|     def team_member_type(self) -> TeamMemberTypeEnum: | ||||
|         return self._team_member_type | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_select_all_string() -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 SELECT * FROM `CFG_ServerTeamRoleIds`; | ||||
|             """ | ||||
|         ) | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_select_by_id_string(id: int) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 SELECT * FROM `CFG_ServerTeamRoleIds` | ||||
|                 WHERE `Id` = {id}; | ||||
|             """ | ||||
|         ) | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_select_by_server_id_string(server_id: int) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 SELECT * FROM `CFG_ServerTeamRoleIds` | ||||
|                 WHERE `ServerId` = {server_id}; | ||||
|             """ | ||||
|         ) | ||||
|  | ||||
|     @property | ||||
|     def insert_string(self) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 INSERT INTO `CFG_ServerTeamRoleIds` ( | ||||
|                     `RoleId`, | ||||
|                     `TeamMemberType`, | ||||
|                     `ServerId` | ||||
|                 ) VALUES ( | ||||
|                     {self._role_id}, | ||||
|                     '{self._team_member_type.value}', | ||||
|                     {self._server_id} | ||||
|                 ); | ||||
|             """ | ||||
|         ) | ||||
|  | ||||
|     @property | ||||
|     def udpate_string(self) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 UPDATE `CFG_ServerTeamRoleIds` | ||||
|                 SET `RoleId` = {self._role_id}, | ||||
|                 `TeamMemberType` = '{self._team_member_type.value}', | ||||
|                 `ServerId` = {self._server_id} | ||||
|                 WHERE `Id` = {self._id}; | ||||
|             """ | ||||
|         ) | ||||
|  | ||||
|     @property | ||||
|     def delete_string(self) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 DELETE FROM `CFG_ServerTeamRoleIds` | ||||
|                 WHERE `RoleId` = {self._role_id}; | ||||
|             """ | ||||
|         ) | ||||
							
								
								
									
										6
									
								
								kdb-bot/src/bot_data/model/team_member_type_enum.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								kdb-bot/src/bot_data/model/team_member_type_enum.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| from enum import Enum | ||||
|  | ||||
|  | ||||
| class TeamMemberTypeEnum(Enum): | ||||
|     moderator = "Moderator" | ||||
|     admin = "Admin" | ||||
							
								
								
									
										152
									
								
								kdb-bot/src/bot_data/model/technician_config.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										152
									
								
								kdb-bot/src/bot_data/model/technician_config.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,152 @@ | ||||
| import json | ||||
| from datetime import datetime | ||||
|  | ||||
| from cpl_core.configuration import ConfigurationModelABC | ||||
| from cpl_core.database import TableABC | ||||
| from cpl_query.extension import List | ||||
|  | ||||
| from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum | ||||
|  | ||||
|  | ||||
| class TechnicianConfig(TableABC, ConfigurationModelABC): | ||||
|     def __init__( | ||||
|         self, | ||||
|         help_command_reference_url: str, | ||||
|         wait_for_restart: int, | ||||
|         wait_for_shutdown: int, | ||||
|         cache_max_messages: int, | ||||
|         feature_flags: dict[FeatureFlagsEnum], | ||||
|         technician_ids: List[int], | ||||
|         ping_urls: List[str], | ||||
|         created_at: datetime = None, | ||||
|         modified_at: datetime = None, | ||||
|         id=0, | ||||
|     ): | ||||
|         self._id = id | ||||
|         self._help_command_reference_url = help_command_reference_url | ||||
|         self._wait_for_restart = wait_for_restart | ||||
|         self._wait_for_shutdown = wait_for_shutdown | ||||
|         self._cache_max_messages = cache_max_messages | ||||
|         self._feature_flags = feature_flags | ||||
|         self._technician_ids = technician_ids | ||||
|         self._ping_urls = ping_urls | ||||
|  | ||||
|         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 help_command_reference_url(self) -> str: | ||||
|         return self._help_command_reference_url | ||||
|  | ||||
|     @help_command_reference_url.setter | ||||
|     def help_command_reference_url(self, value: str): | ||||
|         self._help_command_reference_url = value | ||||
|  | ||||
|     @property | ||||
|     def wait_for_restart(self) -> int: | ||||
|         return self._wait_for_restart | ||||
|  | ||||
|     @wait_for_restart.setter | ||||
|     def wait_for_restart(self, value: int): | ||||
|         self._wait_for_restart = value | ||||
|  | ||||
|     @property | ||||
|     def wait_for_shutdown(self) -> int: | ||||
|         return self._wait_for_shutdown | ||||
|  | ||||
|     @wait_for_shutdown.setter | ||||
|     def wait_for_shutdown(self, value: int): | ||||
|         self._wait_for_shutdown = value | ||||
|  | ||||
|     @property | ||||
|     def cache_max_messages(self) -> int: | ||||
|         return self._cache_max_messages | ||||
|  | ||||
|     @cache_max_messages.setter | ||||
|     def cache_max_messages(self, value: int): | ||||
|         self._cache_max_messages = value | ||||
|  | ||||
|     @property | ||||
|     def feature_flags(self) -> dict[FeatureFlagsEnum]: | ||||
|         return self._feature_flags | ||||
|  | ||||
|     @feature_flags.setter | ||||
|     def feature_flags(self, value: dict[FeatureFlagsEnum]): | ||||
|         self._feature_flags = value | ||||
|  | ||||
|     @property | ||||
|     def technician_ids(self) -> List[int]: | ||||
|         return self._technician_ids | ||||
|  | ||||
|     @technician_ids.setter | ||||
|     def technician_ids(self, value: List[int]): | ||||
|         self._technician_ids = value | ||||
|  | ||||
|     @property | ||||
|     def ping_urls(self) -> List[str]: | ||||
|         return self._ping_urls | ||||
|  | ||||
|     @ping_urls.setter | ||||
|     def ping_urls(self, value: List[str]): | ||||
|         self._ping_urls = value | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_select_all_string() -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 SELECT * FROM `CFG_Technician`; | ||||
|             """ | ||||
|         ) | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_select_by_id_string(id: int) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 SELECT * FROM `CFG_Technician` | ||||
|                 WHERE `Id` = {id}; | ||||
|             """ | ||||
|         ) | ||||
|  | ||||
|     @property | ||||
|     def insert_string(self) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 INSERT INTO `CFG_Technician` ( | ||||
|                     `HelpCommandReferenceUrl`, `WaitForRestart`, `WaitForShutdown`, `CacheMaxMessages`, `FeatureFlags` | ||||
|                 ) VALUES ( | ||||
|                     '{self._help_command_reference_url}', | ||||
|                     {self._wait_for_restart}, | ||||
|                     {self._wait_for_shutdown}, | ||||
|                     {self._cache_max_messages}, | ||||
|                     '{json.dumps(self._feature_flags)}' | ||||
|                 ); | ||||
|             """ | ||||
|         ) | ||||
|  | ||||
|     @property | ||||
|     def udpate_string(self) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 UPDATE `CFG_Technician` | ||||
|                 SET `HelpCommandReferenceUrl` = '{self._help_command_reference_url}', | ||||
|                 `WaitForRestart` = {self._wait_for_restart}, | ||||
|                 `WaitForShutdown` = {self._wait_for_shutdown}, | ||||
|                 `CacheMaxMessages` = {self._cache_max_messages}, | ||||
|                 `FeatureFlags` = '{json.dumps(self._feature_flags)}' | ||||
|                 WHERE `Id` = {self._id}; | ||||
|             """ | ||||
|         ) | ||||
|  | ||||
|     @property | ||||
|     def delete_string(self) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 DELETE FROM `CFG_Technician` | ||||
|                 WHERE `Id` = {self._id}; | ||||
|             """ | ||||
|         ) | ||||
							
								
								
									
										58
									
								
								kdb-bot/src/bot_data/model/technician_config_history.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								kdb-bot/src/bot_data/model/technician_config_history.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,58 @@ | ||||
| from bot_data.abc.history_table_abc import HistoryTableABC | ||||
|  | ||||
|  | ||||
| class TechnicianConfigHistory(HistoryTableABC): | ||||
|     def __init__( | ||||
|         self, | ||||
|         help_command_reference_url: str, | ||||
|         wait_for_restart: int, | ||||
|         wait_for_shutdown: int, | ||||
|         cache_max_messages: int, | ||||
|         deleted: bool, | ||||
|         date_from: str, | ||||
|         date_to: str, | ||||
|         id=0, | ||||
|     ): | ||||
|         HistoryTableABC.__init__(self) | ||||
|  | ||||
|         self._id = id | ||||
|         self._help_command_reference_url = help_command_reference_url | ||||
|         self._wait_for_restart = wait_for_restart | ||||
|         self._wait_for_shutdown = wait_for_shutdown | ||||
|         self._cache_max_messages = cache_max_messages | ||||
|  | ||||
|         self._deleted = deleted | ||||
|         self._date_from = date_from | ||||
|         self._date_to = date_to | ||||
|  | ||||
|     @property | ||||
|     def help_command_reference_url(self) -> str: | ||||
|         return self._help_command_reference_url | ||||
|  | ||||
|     @help_command_reference_url.setter | ||||
|     def help_command_reference_url(self, value: str): | ||||
|         self._help_command_reference_url = value | ||||
|  | ||||
|     @property | ||||
|     def wait_for_restart(self) -> int: | ||||
|         return self._wait_for_restart | ||||
|  | ||||
|     @wait_for_restart.setter | ||||
|     def wait_for_restart(self, value: int): | ||||
|         self._wait_for_restart = value | ||||
|  | ||||
|     @property | ||||
|     def wait_for_shutdown(self) -> int: | ||||
|         return self._wait_for_shutdown | ||||
|  | ||||
|     @wait_for_shutdown.setter | ||||
|     def wait_for_shutdown(self, value: int): | ||||
|         self._wait_for_shutdown = value | ||||
|  | ||||
|     @property | ||||
|     def cache_max_messages(self) -> int: | ||||
|         return self._cache_max_messages | ||||
|  | ||||
|     @cache_max_messages.setter | ||||
|     def cache_max_messages(self, value: int): | ||||
|         self._cache_max_messages = value | ||||
							
								
								
									
										79
									
								
								kdb-bot/src/bot_data/model/technician_id_config.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								kdb-bot/src/bot_data/model/technician_id_config.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,79 @@ | ||||
| from datetime import datetime | ||||
|  | ||||
| from cpl_core.database import TableABC | ||||
|  | ||||
|  | ||||
| class TechnicianIdConfig(TableABC): | ||||
|     def __init__( | ||||
|         self, | ||||
|         technician_id: str, | ||||
|         created_at: datetime = None, | ||||
|         modified_at: datetime = None, | ||||
|         id=0, | ||||
|     ): | ||||
|         self._id = id | ||||
|         self._technician_id = technician_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 id(self) -> int: | ||||
|         return self._id | ||||
|  | ||||
|     @property | ||||
|     def technician_id(self) -> str: | ||||
|         return self._technician_id | ||||
|  | ||||
|     @technician_id.setter | ||||
|     def technician_id(self, value: str): | ||||
|         self._technician_id = value | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_select_all_string() -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 SELECT * FROM `CFG_TechnicianIds`; | ||||
|             """ | ||||
|         ) | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_select_by_id_string(id: int) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 SELECT * FROM `CFG_TechnicianIds` | ||||
|                 WHERE `Id` = {id}; | ||||
|             """ | ||||
|         ) | ||||
|  | ||||
|     @property | ||||
|     def insert_string(self) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 INSERT INTO `CFG_TechnicianIds` ( | ||||
|                     `TechnicianId` | ||||
|                 ) VALUES ( | ||||
|                     '{self._technician_id}' | ||||
|                 ); | ||||
|             """ | ||||
|         ) | ||||
|  | ||||
|     @property | ||||
|     def udpate_string(self) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 UPDATE `CFG_TechnicianIds` | ||||
|                 SET `TechnicianId` = '{self._technician_id}' | ||||
|                 WHERE `Id` = {self._id}; | ||||
|             """ | ||||
|         ) | ||||
|  | ||||
|     @property | ||||
|     def delete_string(self) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 DELETE FROM `CFG_TechnicianIds` | ||||
|                 WHERE `TechnicianId` = {self._technician_id}; | ||||
|             """ | ||||
|         ) | ||||
							
								
								
									
										28
									
								
								kdb-bot/src/bot_data/model/technician_id_config_history.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								kdb-bot/src/bot_data/model/technician_id_config_history.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| from bot_data.abc.history_table_abc import HistoryTableABC | ||||
|  | ||||
|  | ||||
| class TechnicianIdConfigHistory(HistoryTableABC): | ||||
|     def __init__( | ||||
|         self, | ||||
|         technician_id: int, | ||||
|         deleted: bool, | ||||
|         date_from: str, | ||||
|         date_to: str, | ||||
|         id=0, | ||||
|     ): | ||||
|         HistoryTableABC.__init__(self) | ||||
|  | ||||
|         self._id = id | ||||
|         self._technician_id = technician_id | ||||
|  | ||||
|         self._deleted = deleted | ||||
|         self._date_from = date_from | ||||
|         self._date_to = date_to | ||||
|  | ||||
|     @property | ||||
|     def technician_id(self) -> int: | ||||
|         return self._technician_id | ||||
|  | ||||
|     @technician_id.setter | ||||
|     def technician_id(self, value: int): | ||||
|         self._technician_id = value | ||||
							
								
								
									
										79
									
								
								kdb-bot/src/bot_data/model/technician_ping_url_config.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								kdb-bot/src/bot_data/model/technician_ping_url_config.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,79 @@ | ||||
| from datetime import datetime | ||||
|  | ||||
| from cpl_core.database import TableABC | ||||
|  | ||||
|  | ||||
| class TechnicianPingUrlConfig(TableABC): | ||||
|     def __init__( | ||||
|         self, | ||||
|         ping_url: str, | ||||
|         created_at: datetime = None, | ||||
|         modified_at: datetime = None, | ||||
|         id=0, | ||||
|     ): | ||||
|         self._id = id | ||||
|         self._ping_url = ping_url | ||||
|  | ||||
|         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 ping_url(self) -> str: | ||||
|         return self._ping_url | ||||
|  | ||||
|     @ping_url.setter | ||||
|     def ping_url(self, value: str): | ||||
|         self._ping_url = value | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_select_all_string() -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 SELECT * FROM `CFG_TechnicianPingUrls`; | ||||
|             """ | ||||
|         ) | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_select_by_id_string(id: int) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 SELECT * FROM `CFG_TechnicianPingUrls` | ||||
|                 WHERE `Id` = {id}; | ||||
|             """ | ||||
|         ) | ||||
|  | ||||
|     @property | ||||
|     def insert_string(self) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 INSERT INTO `CFG_TechnicianPingUrls` ( | ||||
|                     `URL` | ||||
|                 ) VALUES ( | ||||
|                     '{self._ping_url}' | ||||
|                 ); | ||||
|             """ | ||||
|         ) | ||||
|  | ||||
|     @property | ||||
|     def udpate_string(self) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 UPDATE `CFG_TechnicianPingUrls` | ||||
|                 SET `URL` = '{self._ping_url}' | ||||
|                 WHERE `Id` = {self._id}; | ||||
|             """ | ||||
|         ) | ||||
|  | ||||
|     @property | ||||
|     def delete_string(self) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 DELETE FROM `CFG_TechnicianPingUrls` | ||||
|                 WHERE `URL` = '{self._ping_url}'; | ||||
|             """ | ||||
|         ) | ||||
| @@ -0,0 +1,28 @@ | ||||
| from bot_data.abc.history_table_abc import HistoryTableABC | ||||
|  | ||||
|  | ||||
| class TechnicianPingUrlConfigHistory(HistoryTableABC): | ||||
|     def __init__( | ||||
|         self, | ||||
|         url: str, | ||||
|         deleted: bool, | ||||
|         date_from: str, | ||||
|         date_to: str, | ||||
|         id=0, | ||||
|     ): | ||||
|         HistoryTableABC.__init__(self) | ||||
|  | ||||
|         self._id = id | ||||
|         self._url = url | ||||
|  | ||||
|         self._deleted = deleted | ||||
|         self._date_from = date_from | ||||
|         self._date_to = date_to | ||||
|  | ||||
|     @property | ||||
|     def url(self) -> str: | ||||
|         return self._url | ||||
|  | ||||
|     @url.setter | ||||
|     def url(self, value: str): | ||||
|         self._url = value | ||||
| @@ -15,6 +15,8 @@ class User(TableABC): | ||||
|         self, | ||||
|         dc_id: int, | ||||
|         xp: int, | ||||
|         reaction_count: int, | ||||
|         message_count: int, | ||||
|         server: Optional[Server], | ||||
|         created_at: datetime = None, | ||||
|         modified_at: datetime = None, | ||||
| @@ -23,6 +25,8 @@ class User(TableABC): | ||||
|         self._user_id = id | ||||
|         self._discord_id = dc_id | ||||
|         self._xp = xp | ||||
|         self._reaction_count = reaction_count | ||||
|         self._message_count = message_count | ||||
|         self._server = server | ||||
|  | ||||
|         TableABC.__init__(self) | ||||
| @@ -59,6 +63,22 @@ class User(TableABC): | ||||
|     def xp(self, value: int): | ||||
|         self._xp = value | ||||
|  | ||||
|     @property | ||||
|     def message_count(self) -> int: | ||||
|         return self._message_count | ||||
|  | ||||
|     @message_count.setter | ||||
|     def message_count(self, value: int): | ||||
|         self._message_count = value | ||||
|  | ||||
|     @property | ||||
|     def reaction_count(self) -> int: | ||||
|         return self._reaction_count | ||||
|  | ||||
|     @reaction_count.setter | ||||
|     def reaction_count(self, value: int): | ||||
|         self._reaction_count = value | ||||
|  | ||||
|     @property | ||||
|     @ServiceProviderABC.inject | ||||
|     def ontime(self, services: ServiceProviderABC) -> float: | ||||
| @@ -151,10 +171,12 @@ class User(TableABC): | ||||
|         return str( | ||||
|             f""" | ||||
|             INSERT INTO `Users` ( | ||||
|                 `DiscordId`, `XP`, `ServerId` | ||||
|                 `DiscordId`, `XP`, `MessageCount`, `ReactionCount`, `ServerId` | ||||
|             ) VALUES ( | ||||
|                 {self._discord_id}, | ||||
|                 {self._xp}, | ||||
|                 {self._message_count}, | ||||
|                 {self._reaction_count}, | ||||
|                 {self._server.id} | ||||
|             ); | ||||
|         """ | ||||
| @@ -165,7 +187,9 @@ class User(TableABC): | ||||
|         return str( | ||||
|             f""" | ||||
|             UPDATE `Users` | ||||
|             SET `XP` = {self._xp} | ||||
|             SET `XP` = {self._xp}, | ||||
|             `MessageCount` = {self._message_count}, | ||||
|             `ReactionCount` = {self._reaction_count} | ||||
|             WHERE `UserId` = {self._user_id}; | ||||
|         """ | ||||
|         ) | ||||
|   | ||||
							
								
								
									
										105
									
								
								kdb-bot/src/bot_data/model/user_got_achievement.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								kdb-bot/src/bot_data/model/user_got_achievement.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,105 @@ | ||||
| from datetime import datetime | ||||
| from typing import Optional | ||||
|  | ||||
| from cpl_core.database import TableABC | ||||
|  | ||||
| from bot_data.model.achievement import Achievement | ||||
| from bot_data.model.user import User | ||||
|  | ||||
|  | ||||
| class UserGotAchievement(TableABC): | ||||
|     def __init__( | ||||
|         self, | ||||
|         user: Optional[User], | ||||
|         achievement: Optional[Achievement], | ||||
|         created_at: datetime = None, | ||||
|         modified_at: datetime = None, | ||||
|         id=0, | ||||
|     ): | ||||
|         self._id = id | ||||
|         self._user = user | ||||
|         self._achievement = achievement | ||||
|  | ||||
|         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 user(self) -> User: | ||||
|         return self._user | ||||
|  | ||||
|     @property | ||||
|     def achievement(self) -> Achievement: | ||||
|         return self._achievement | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_select_all_string() -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 SELECT * FROM `UserGotAchievements`; | ||||
|             """ | ||||
|         ) | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_select_by_id_string(id: int) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 SELECT * FROM `UserGotAchievements` | ||||
|                 WHERE `Id` = {id}; | ||||
|             """ | ||||
|         ) | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_select_by_user_id_string(id: int) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 SELECT * FROM `UserGotAchievements` | ||||
|                 WHERE `UserId` = {id}; | ||||
|             """ | ||||
|         ) | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_select_by_achievement_id_string(id: int) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 SELECT * FROM `UserGotAchievements` | ||||
|                 WHERE `AchievementId` = {id}; | ||||
|             """ | ||||
|         ) | ||||
|  | ||||
|     @property | ||||
|     def insert_string(self) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|             INSERT INTO `UserGotAchievements` ( | ||||
|                 `UserId`, `AchievementId` | ||||
|             ) VALUES ( | ||||
|                 {self._user.id}, | ||||
|                 {self._achievement.id} | ||||
|             ); | ||||
|         """ | ||||
|         ) | ||||
|  | ||||
|     @property | ||||
|     def udpate_string(self) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 UPDATE `UserGotAchievements` | ||||
|                 SET `UserId` = '{self._user.id}', | ||||
|                 `AchievementId` = '{self._achievement.id}' | ||||
|                 WHERE `Id` = {self._id}; | ||||
|             """ | ||||
|         ) | ||||
|  | ||||
|     @property | ||||
|     def delete_string(self) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 DELETE FROM `UserGotAchievements` | ||||
|                 WHERE `Id` = {self._id}; | ||||
|             """ | ||||
|         ) | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user