Compare commits
	
		
			9 Commits
		
	
	
		
			02e0c72a80
			...
			46b5757fd1
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 46b5757fd1 | |||
| 1cd75cd78f | |||
| f7f3fea7a7 | |||
| 5dd2000f10 | |||
| 1b2bb85b37 | |||
| 113b188a40 | |||
| e549341196 | |||
| 8a0d939147 | |||
| 4b57d7f102 | 
 Submodule kdb-bot/src/bot/config updated: 359f9c38c3...20adf415f9
									
								
							| @@ -31,10 +31,10 @@ class Program: | |||||||
|             .use_extension(StartupDiscordExtension) |             .use_extension(StartupDiscordExtension) | ||||||
|             .use_extension(StartupModuleExtension) |             .use_extension(StartupModuleExtension) | ||||||
|             .use_extension(StartupMigrationExtension) |             .use_extension(StartupMigrationExtension) | ||||||
|  |             .use_extension(DatabaseExtension) | ||||||
|             .use_extension(ConfigExtension) |             .use_extension(ConfigExtension) | ||||||
|             .use_extension(InitBotExtension) |             .use_extension(InitBotExtension) | ||||||
|             .use_extension(BootLogExtension) |             .use_extension(BootLogExtension) | ||||||
|             .use_extension(DatabaseExtension) |  | ||||||
|             .use_extension(AppApiExtension) |             .use_extension(AppApiExtension) | ||||||
|             .use_extension(CoreExtension) |             .use_extension(CoreExtension) | ||||||
|             .use_startup(Startup) |             .use_startup(Startup) | ||||||
|   | |||||||
| @@ -9,6 +9,7 @@ from bot_data.migration.api_key_migration import ApiKeyMigration | |||||||
| from bot_data.migration.api_migration import ApiMigration | from bot_data.migration.api_migration import ApiMigration | ||||||
| from bot_data.migration.auto_role_fix1_migration import AutoRoleFix1Migration | from bot_data.migration.auto_role_fix1_migration import AutoRoleFix1Migration | ||||||
| from bot_data.migration.auto_role_migration import AutoRoleMigration | 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.config_migration import ConfigMigration | ||||||
| from bot_data.migration.db_history_migration import DBHistoryMigration | from bot_data.migration.db_history_migration import DBHistoryMigration | ||||||
| from bot_data.migration.initial_migration import InitialMigration | from bot_data.migration.initial_migration import InitialMigration | ||||||
| @@ -46,3 +47,4 @@ class StartupMigrationExtension(StartupExtensionABC): | |||||||
|         services.add_transient(MigrationABC, DBHistoryMigration)  # 06.03.2023 #246 - 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, AchievementsMigration)  # 14.06.2023 #268 - 1.1.0 | ||||||
|         services.add_transient(MigrationABC, ConfigMigration)  # 19.07.2023 #127 - 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 | ||||||
|   | |||||||
| @@ -5,18 +5,17 @@ class FeatureFlagsEnum(Enum): | |||||||
|     # modules |     # modules | ||||||
|     achievements_module = "AchievementsModule" |     achievements_module = "AchievementsModule" | ||||||
|     api_module = "ApiModule" |     api_module = "ApiModule" | ||||||
|     admin_module = "AdminModule" |  | ||||||
|     auto_role_module = "AutoRoleModule" |     auto_role_module = "AutoRoleModule" | ||||||
|     base_module = "BaseModule" |     base_module = "BaseModule" | ||||||
|     boot_log_module = "BootLogModule" |     boot_log_module = "BootLogModule" | ||||||
|     core_module = "CoreModule" |     core_module = "CoreModule" | ||||||
|     core_extension_module = "CoreExtensionModule" |     core_extension_module = "CoreExtensionModule" | ||||||
|  |     config_module = "ConfigModule" | ||||||
|     data_module = "DataModule" |     data_module = "DataModule" | ||||||
|     database_module = "DatabaseModule" |     database_module = "DatabaseModule" | ||||||
|     level_module = "LevelModule" |     level_module = "LevelModule" | ||||||
|     moderator_module = "ModeratorModule" |     moderator_module = "ModeratorModule" | ||||||
|     permission_module = "PermissionModule" |     permission_module = "PermissionModule" | ||||||
|     config_module = "ConfigModule" |  | ||||||
|     # features |     # features | ||||||
|     api_only = "ApiOnly" |     api_only = "ApiOnly" | ||||||
|     presence = "Presence" |     presence = "Presence" | ||||||
|   | |||||||
| @@ -8,8 +8,7 @@ class FeatureFlagsSettings(ConfigurationModelABC): | |||||||
|         # modules |         # modules | ||||||
|         FeatureFlagsEnum.achievements_module.value: False,  # 14.06.2023 #268 |         FeatureFlagsEnum.achievements_module.value: False,  # 14.06.2023 #268 | ||||||
|         FeatureFlagsEnum.api_module.value: False,  # 13.10.2022 #70 |         FeatureFlagsEnum.api_module.value: False,  # 13.10.2022 #70 | ||||||
|         FeatureFlagsEnum.admin_module.value: False,  # 02.10.2022 #48 |         FeatureFlagsEnum.auto_role_module.value: False,  # 03.10.2022 #54 | ||||||
|         FeatureFlagsEnum.auto_role_module.value: True,  # 03.10.2022 #54 |  | ||||||
|         FeatureFlagsEnum.base_module.value: True,  # 02.10.2022 #48 |         FeatureFlagsEnum.base_module.value: True,  # 02.10.2022 #48 | ||||||
|         FeatureFlagsEnum.boot_log_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_module.value: True,  # 03.10.2022 #56 | ||||||
| @@ -34,6 +33,17 @@ class FeatureFlagsSettings(ConfigurationModelABC): | |||||||
|         for flag in [f.value for f in FeatureFlagsEnum]: |         for flag in [f.value for f in FeatureFlagsEnum]: | ||||||
|             self._load_flag(kwargs, FeatureFlagsEnum(flag)) |             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: |     def get_flag(self, key: FeatureFlagsEnum) -> bool: | ||||||
|         if key.value not in self._flags: |         if key.value not in self._flags: | ||||||
|             return False |             return False | ||||||
|   | |||||||
| @@ -11,6 +11,7 @@ from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum | |||||||
| from bot_core.events.core_on_ready_event import CoreOnReadyEvent | from bot_core.events.core_on_ready_event import CoreOnReadyEvent | ||||||
| from bot_core.pipes.date_time_offset_pipe import DateTimeOffsetPipe | from bot_core.pipes.date_time_offset_pipe import DateTimeOffsetPipe | ||||||
| from bot_core.service.client_utils_service import ClientUtilsService | 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.data_integrity_service import DataIntegrityService | ||||||
| from bot_core.service.message_service import MessageService | from bot_core.service.message_service import MessageService | ||||||
|  |  | ||||||
| @@ -23,6 +24,7 @@ class CoreModule(ModuleABC): | |||||||
|         pass |         pass | ||||||
|  |  | ||||||
|     def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC): |     def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC): | ||||||
|  |         services.add_transient(ConfigService) | ||||||
|         services.add_transient(MessageServiceABC, MessageService) |         services.add_transient(MessageServiceABC, MessageService) | ||||||
|         services.add_transient(ClientUtilsABC, ClientUtilsService) |         services.add_transient(ClientUtilsABC, ClientUtilsService) | ||||||
|         services.add_transient(DataIntegrityService) |         services.add_transient(DataIntegrityService) | ||||||
|   | |||||||
							
								
								
									
										30
									
								
								kdb-bot/src/bot_core/service/config_service.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								kdb-bot/src/bot_core/service/config_service.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | |||||||
|  | from cpl_core.configuration import ConfigurationABC | ||||||
|  |  | ||||||
|  | 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 | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class ConfigService: | ||||||
|  |     def __init__( | ||||||
|  |         self, | ||||||
|  |         config: ConfigurationABC, | ||||||
|  |         technician_config_repo: TechnicianConfigRepositoryABC, | ||||||
|  |         server_config_repo: ServerConfigRepositoryABC, | ||||||
|  |     ): | ||||||
|  |         self._config = config | ||||||
|  |         self._technician_config_repo = technician_config_repo | ||||||
|  |         self._server_config_repo = server_config_repo | ||||||
|  |  | ||||||
|  |     def reload_technician_config(self): | ||||||
|  |         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)) | ||||||
|  |  | ||||||
|  |     def reload_server_config(self, server: Server): | ||||||
|  |         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 | ||||||
|  |         ) | ||||||
| @@ -0,0 +1,33 @@ | |||||||
|  | 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 JSON_OBJECT() AFTER CacheMaxMessages;""" | ||||||
|  |             ) | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |         self._cursor.execute( | ||||||
|  |             str( | ||||||
|  |                 """ALTER TABLE CFG_Server ADD FeatureFlags JSON NULL DEFAULT JSON_OBJECT() 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;") | ||||||
| @@ -143,6 +143,8 @@ class ConfigMigration(MigrationABC): | |||||||
|  |  | ||||||
|     def downgrade(self): |     def downgrade(self): | ||||||
|         self._logger.debug(__name__, "Running downgrade") |         self._logger.debug(__name__, "Running downgrade") | ||||||
|  |         self._server_downgrade() | ||||||
|  |         self._technician_downgrade() | ||||||
|  |  | ||||||
|     def _server_downgrade(self): |     def _server_downgrade(self): | ||||||
|         self._cursor.execute("DROP TABLE `CFG_Server`;") |         self._cursor.execute("DROP TABLE `CFG_Server`;") | ||||||
|   | |||||||
| @@ -1,9 +1,11 @@ | |||||||
|  | import json | ||||||
| from datetime import datetime | from datetime import datetime | ||||||
|  |  | ||||||
| from cpl_core.configuration import ConfigurationModelABC | from cpl_core.configuration import ConfigurationModelABC | ||||||
| from cpl_core.database import TableABC | from cpl_core.database import TableABC | ||||||
| from cpl_query.extension import List | 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 import Server | ||||||
| from bot_data.model.server_team_role_ids_config import ServerTeamRoleIdsConfig | from bot_data.model.server_team_role_ids_config import ServerTeamRoleIdsConfig | ||||||
|  |  | ||||||
| @@ -24,6 +26,7 @@ class ServerConfig(TableABC, ConfigurationModelABC): | |||||||
|         help_voice_channel_id: int, |         help_voice_channel_id: int, | ||||||
|         team_channel_id: int, |         team_channel_id: int, | ||||||
|         login_message_channel_id: int, |         login_message_channel_id: int, | ||||||
|  |         feature_flags: dict[FeatureFlagsEnum], | ||||||
|         server: Server, |         server: Server, | ||||||
|         afk_channel_ids: List[int], |         afk_channel_ids: List[int], | ||||||
|         team_role_ids: List[ServerTeamRoleIdsConfig], |         team_role_ids: List[ServerTeamRoleIdsConfig], | ||||||
| @@ -45,6 +48,7 @@ class ServerConfig(TableABC, ConfigurationModelABC): | |||||||
|         self._help_voice_channel_id = help_voice_channel_id |         self._help_voice_channel_id = help_voice_channel_id | ||||||
|         self._team_channel_id = team_channel_id |         self._team_channel_id = team_channel_id | ||||||
|         self._login_message_channel_id = login_message_channel_id |         self._login_message_channel_id = login_message_channel_id | ||||||
|  |         self._feature_flags = feature_flags | ||||||
|         self._server = server |         self._server = server | ||||||
|         self._afk_channel_ids = afk_channel_ids |         self._afk_channel_ids = afk_channel_ids | ||||||
|         self._team_role_ids = team_role_ids |         self._team_role_ids = team_role_ids | ||||||
| @@ -161,6 +165,14 @@ class ServerConfig(TableABC, ConfigurationModelABC): | |||||||
|     def login_message_channel_id(self, value: int): |     def login_message_channel_id(self, value: int): | ||||||
|         self._login_message_channel_id = value |         self._login_message_channel_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 |     @property | ||||||
|     def afk_channel_ids(self) -> List[int]: |     def afk_channel_ids(self) -> List[int]: | ||||||
|         return self._afk_channel_ids |         return self._afk_channel_ids | ||||||
| @@ -225,6 +237,7 @@ class ServerConfig(TableABC, ConfigurationModelABC): | |||||||
|                     `HelpVoiceChannelId`, |                     `HelpVoiceChannelId`, | ||||||
|                     `TeamChannelId`, |                     `TeamChannelId`, | ||||||
|                     `LoginMessageChannelId`, |                     `LoginMessageChannelId`, | ||||||
|  |                     `FeatureFlags`, | ||||||
|                     `ServerId` |                     `ServerId` | ||||||
|                 ) VALUES ( |                 ) VALUES ( | ||||||
|                     {self._message_delete_timer}, |                     {self._message_delete_timer}, | ||||||
| @@ -240,6 +253,7 @@ class ServerConfig(TableABC, ConfigurationModelABC): | |||||||
|                     {self._help_voice_channel_id}, |                     {self._help_voice_channel_id}, | ||||||
|                     {self._team_channel_id}, |                     {self._team_channel_id}, | ||||||
|                     {self._login_message_channel_id}, |                     {self._login_message_channel_id}, | ||||||
|  |                     '{json.dumps(self._feature_flags)}', | ||||||
|                     {self._server.id} |                     {self._server.id} | ||||||
|                 ); |                 ); | ||||||
|             """ |             """ | ||||||
| @@ -263,6 +277,7 @@ class ServerConfig(TableABC, ConfigurationModelABC): | |||||||
|                 `HelpVoiceChannelId` = {self._help_voice_channel_id}, |                 `HelpVoiceChannelId` = {self._help_voice_channel_id}, | ||||||
|                 `TeamChannelId` = {self._team_channel_id}, |                 `TeamChannelId` = {self._team_channel_id}, | ||||||
|                 `LoginMessageChannelId` = {self._login_message_channel_id}, |                 `LoginMessageChannelId` = {self._login_message_channel_id}, | ||||||
|  |                 `FeatureFlags` = '{json.dumps(self._feature_flags)}', | ||||||
|                 `ServerId` = {self._server.id} |                 `ServerId` = {self._server.id} | ||||||
|                 WHERE `Id` = {self._id}; |                 WHERE `Id` = {self._id}; | ||||||
|             """ |             """ | ||||||
|   | |||||||
| @@ -17,6 +17,7 @@ class ServerConfigHistory(HistoryTableABC): | |||||||
|         help_voice_channel_id: int, |         help_voice_channel_id: int, | ||||||
|         team_channel_id: int, |         team_channel_id: int, | ||||||
|         login_message_channel_id: int, |         login_message_channel_id: int, | ||||||
|  |         feature_flags: dict[str], | ||||||
|         server_id: int, |         server_id: int, | ||||||
|         deleted: bool, |         deleted: bool, | ||||||
|         date_from: str, |         date_from: str, | ||||||
| @@ -39,6 +40,7 @@ class ServerConfigHistory(HistoryTableABC): | |||||||
|         self._help_voice_channel_id = help_voice_channel_id |         self._help_voice_channel_id = help_voice_channel_id | ||||||
|         self._team_channel_id = team_channel_id |         self._team_channel_id = team_channel_id | ||||||
|         self._login_message_channel_id = login_message_channel_id |         self._login_message_channel_id = login_message_channel_id | ||||||
|  |         self._feature_flags = feature_flags | ||||||
|         self._server_id = server_id |         self._server_id = server_id | ||||||
|  |  | ||||||
|         self._deleted = deleted |         self._deleted = deleted | ||||||
| @@ -97,6 +99,10 @@ class ServerConfigHistory(HistoryTableABC): | |||||||
|     def login_message_channel_id(self) -> int: |     def login_message_channel_id(self) -> int: | ||||||
|         return self._login_message_channel_id |         return self._login_message_channel_id | ||||||
|  |  | ||||||
|  |     @property | ||||||
|  |     def feature_flags(self) -> dict[str]: | ||||||
|  |         return self._feature_flags | ||||||
|  |  | ||||||
|     @property |     @property | ||||||
|     def server_id(self) -> int: |     def server_id(self) -> int: | ||||||
|         return self._server_id |         return self._server_id | ||||||
|   | |||||||
| @@ -1,9 +1,12 @@ | |||||||
|  | import json | ||||||
| from datetime import datetime | from datetime import datetime | ||||||
|  |  | ||||||
| from cpl_core.configuration import ConfigurationModelABC | from cpl_core.configuration import ConfigurationModelABC | ||||||
| from cpl_core.database import TableABC | from cpl_core.database import TableABC | ||||||
| from cpl_query.extension import List | from cpl_query.extension import List | ||||||
|  |  | ||||||
|  | from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum | ||||||
|  |  | ||||||
|  |  | ||||||
| class TechnicianConfig(TableABC, ConfigurationModelABC): | class TechnicianConfig(TableABC, ConfigurationModelABC): | ||||||
|     def __init__( |     def __init__( | ||||||
| @@ -12,6 +15,7 @@ class TechnicianConfig(TableABC, ConfigurationModelABC): | |||||||
|         wait_for_restart: int, |         wait_for_restart: int, | ||||||
|         wait_for_shutdown: int, |         wait_for_shutdown: int, | ||||||
|         cache_max_messages: int, |         cache_max_messages: int, | ||||||
|  |         feature_flags: dict[FeatureFlagsEnum], | ||||||
|         technician_ids: List[int], |         technician_ids: List[int], | ||||||
|         ping_urls: List[str], |         ping_urls: List[str], | ||||||
|         created_at: datetime = None, |         created_at: datetime = None, | ||||||
| @@ -23,6 +27,7 @@ class TechnicianConfig(TableABC, ConfigurationModelABC): | |||||||
|         self._wait_for_restart = wait_for_restart |         self._wait_for_restart = wait_for_restart | ||||||
|         self._wait_for_shutdown = wait_for_shutdown |         self._wait_for_shutdown = wait_for_shutdown | ||||||
|         self._cache_max_messages = cache_max_messages |         self._cache_max_messages = cache_max_messages | ||||||
|  |         self._feature_flags = feature_flags | ||||||
|         self._technician_ids = technician_ids |         self._technician_ids = technician_ids | ||||||
|         self._ping_urls = ping_urls |         self._ping_urls = ping_urls | ||||||
|  |  | ||||||
| @@ -66,6 +71,14 @@ class TechnicianConfig(TableABC, ConfigurationModelABC): | |||||||
|     def cache_max_messages(self, value: int): |     def cache_max_messages(self, value: int): | ||||||
|         self._cache_max_messages = value |         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 |     @property | ||||||
|     def technician_ids(self) -> List[int]: |     def technician_ids(self) -> List[int]: | ||||||
|         return self._technician_ids |         return self._technician_ids | ||||||
| @@ -104,12 +117,13 @@ class TechnicianConfig(TableABC, ConfigurationModelABC): | |||||||
|         return str( |         return str( | ||||||
|             f""" |             f""" | ||||||
|                 INSERT INTO `CFG_Technician` ( |                 INSERT INTO `CFG_Technician` ( | ||||||
|                     `HelpCommandReferenceUrl`, `WaitForRestart`, `WaitForShutdown`, `CacheMaxMessages` |                     `HelpCommandReferenceUrl`, `WaitForRestart`, `WaitForShutdown`, `CacheMaxMessages`, `FeatureFlags` | ||||||
|                 ) VALUES ( |                 ) VALUES ( | ||||||
|                     '{self._help_command_reference_url}', |                     '{self._help_command_reference_url}', | ||||||
|                     {self._wait_for_restart}, |                     {self._wait_for_restart}, | ||||||
|                     {self._wait_for_shutdown}, |                     {self._wait_for_shutdown}, | ||||||
|                     {self._cache_max_messages} |                     {self._cache_max_messages}, | ||||||
|  |                     '{json.dumps(self._feature_flags)}' | ||||||
|                 ); |                 ); | ||||||
|             """ |             """ | ||||||
|         ) |         ) | ||||||
| @@ -122,7 +136,8 @@ class TechnicianConfig(TableABC, ConfigurationModelABC): | |||||||
|                 SET `HelpCommandReferenceUrl` = '{self._help_command_reference_url}', |                 SET `HelpCommandReferenceUrl` = '{self._help_command_reference_url}', | ||||||
|                 `WaitForRestart` = {self._wait_for_restart}, |                 `WaitForRestart` = {self._wait_for_restart}, | ||||||
|                 `WaitForShutdown` = {self._wait_for_shutdown}, |                 `WaitForShutdown` = {self._wait_for_shutdown}, | ||||||
|                 `CacheMaxMessages` = {self._cache_max_messages} |                 `CacheMaxMessages` = {self._cache_max_messages}, | ||||||
|  |                 `FeatureFlags` = '{json.dumps(self._feature_flags)}' | ||||||
|                 WHERE `Id` = {self._id}; |                 WHERE `Id` = {self._id}; | ||||||
|             """ |             """ | ||||||
|         ) |         ) | ||||||
|   | |||||||
| @@ -1,3 +1,5 @@ | |||||||
|  | import json | ||||||
|  |  | ||||||
| from cpl_core.database.context import DatabaseContextABC | from cpl_core.database.context import DatabaseContextABC | ||||||
| from cpl_query.extension import List | from cpl_query.extension import List | ||||||
|  |  | ||||||
| @@ -62,11 +64,12 @@ class ServerConfigRepositoryService(ServerConfigRepositoryABC): | |||||||
|             result[11], |             result[11], | ||||||
|             result[12], |             result[12], | ||||||
|             result[13], |             result[13], | ||||||
|             self._servers.get_server_by_id(result[14]), |             json.loads(result[14]), | ||||||
|             self._get_afk_channel_ids(result[14]), |             self._servers.get_server_by_id(result[15]), | ||||||
|             self._get_team_role_ids(result[14]), |             self._get_afk_channel_ids(result[15]), | ||||||
|             result[15], |             self._get_team_role_ids(result[15]), | ||||||
|             result[16], |             result[16], | ||||||
|  |             result[17], | ||||||
|             id=result[0], |             id=result[0], | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -48,6 +48,7 @@ class ServerConfigSeeder(DataSeederABC): | |||||||
|                     guild.system_channel.id, |                     guild.system_channel.id, | ||||||
|                     guild.system_channel.id, |                     guild.system_channel.id, | ||||||
|                     guild.system_channel.id, |                     guild.system_channel.id, | ||||||
|  |                     {}, | ||||||
|                     server, |                     server, | ||||||
|                     [], |                     [], | ||||||
|                     [], |                     [], | ||||||
|   | |||||||
| @@ -1,3 +1,5 @@ | |||||||
|  | import json | ||||||
|  |  | ||||||
| from cpl_core.database.context import DatabaseContextABC | from cpl_core.database.context import DatabaseContextABC | ||||||
| from cpl_query.extension import List | from cpl_query.extension import List | ||||||
|  |  | ||||||
| @@ -41,10 +43,11 @@ class TechnicianConfigRepositoryService(TechnicianConfigRepositoryABC): | |||||||
|             result[2], |             result[2], | ||||||
|             result[3], |             result[3], | ||||||
|             result[4], |             result[4], | ||||||
|  |             json.loads(result[5]), | ||||||
|             self._get_technician_ids(), |             self._get_technician_ids(), | ||||||
|             self._get_technician_ping_urls(), |             self._get_technician_ping_urls(), | ||||||
|             result[5], |  | ||||||
|             result[6], |             result[6], | ||||||
|  |             result[7], | ||||||
|             id=result[0], |             id=result[0], | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -32,6 +32,7 @@ class TechnicianConfigSeeder(DataSeederABC): | |||||||
|                 8, |                 8, | ||||||
|                 8, |                 8, | ||||||
|                 1000000, |                 1000000, | ||||||
|  |                 {}, | ||||||
|                 List(int, [240160344557879316]), |                 List(int, [240160344557879316]), | ||||||
|                 List(str, ["www.google.com", "www.sh-edraft.de", "www.keksdose-gaming.de"]), |                 List(str, ["www.google.com", "www.sh-edraft.de", "www.keksdose-gaming.de"]), | ||||||
|             ) |             ) | ||||||
|   | |||||||
| @@ -9,6 +9,7 @@ from cpl_query.extension import List | |||||||
| from bot_api.exception.service_error_code_enum import ServiceErrorCode | from bot_api.exception.service_error_code_enum import ServiceErrorCode | ||||||
| from bot_api.exception.service_exception import ServiceException | from bot_api.exception.service_exception import ServiceException | ||||||
| from bot_api.route.route import Route | from bot_api.route.route import Route | ||||||
|  | from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum | ||||||
| from bot_data.model.auth_role_enum import AuthRoleEnum | from bot_data.model.auth_role_enum import AuthRoleEnum | ||||||
| from bot_data.model.auth_user import AuthUser | from bot_data.model.auth_user import AuthUser | ||||||
| from bot_data.model.auto_role import AutoRole | from bot_data.model.auto_role import AutoRole | ||||||
| @@ -17,6 +18,7 @@ from bot_data.model.client import Client | |||||||
| from bot_data.model.known_user import KnownUser | from bot_data.model.known_user import KnownUser | ||||||
| from bot_data.model.level import Level | from bot_data.model.level import Level | ||||||
| from bot_data.model.server import Server | 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 import User | ||||||
| from bot_data.model.user_joined_game_server import UserJoinedGameServer | from bot_data.model.user_joined_game_server import UserJoinedGameServer | ||||||
| from bot_data.model.user_joined_server import UserJoinedServer | from bot_data.model.user_joined_server import UserJoinedServer | ||||||
| @@ -66,8 +68,12 @@ class QueryABC(ObjectType): | |||||||
|         self.set_field(f"{name}s", wrapper) |         self.set_field(f"{name}s", wrapper) | ||||||
|         self.set_field(f"{name}Count", lambda *args: wrapper(*args).count()) |         self.set_field(f"{name}Count", lambda *args: wrapper(*args).count()) | ||||||
|  |  | ||||||
|     @ServiceProviderABC.inject |     def _can_user_see_element(self, user: AuthUser, element: T) -> bool: | ||||||
|     def _can_user_see_element(self, user: AuthUser, element: T, services: ServiceProviderABC) -> bool: |         @ServiceProviderABC.inject | ||||||
|  |         def get_services(services: ServiceProviderABC) -> ServiceProviderABC: | ||||||
|  |             return services | ||||||
|  |  | ||||||
|  |         services = get_services() | ||||||
|         permissions: PermissionService = services.get_service(PermissionService) |         permissions: PermissionService = services.get_service(PermissionService) | ||||||
|         bot: DiscordBotServiceABC = services.get_service(DiscordBotServiceABC) |         bot: DiscordBotServiceABC = services.get_service(DiscordBotServiceABC) | ||||||
|  |  | ||||||
| @@ -158,6 +164,24 @@ class QueryABC(ObjectType): | |||||||
|                     access = True |                     access = True | ||||||
|                     break |                     break | ||||||
|  |  | ||||||
|  |         elif type(element) == ServerConfig: | ||||||
|  |             for u in user.users: | ||||||
|  |                 u: User = u | ||||||
|  |                 guild = bot.get_guild(u.server.discord_id) | ||||||
|  |                 member = guild.get_member(u.discord_id) | ||||||
|  |                 if permissions.is_member_technician(member): | ||||||
|  |                     access = True | ||||||
|  |                     break | ||||||
|  |  | ||||||
|  |         elif type(element) == dict and "key" in element and element["key"] in [e.value for e in FeatureFlagsEnum]: | ||||||
|  |             for u in user.users: | ||||||
|  |                 u: User = u | ||||||
|  |                 guild = bot.get_guild(u.server.discord_id) | ||||||
|  |                 member = guild.get_member(u.discord_id) | ||||||
|  |                 if permissions.is_member_technician(member): | ||||||
|  |                     access = True | ||||||
|  |                     break | ||||||
|  |  | ||||||
|         return access |         return access | ||||||
|  |  | ||||||
|     @ServiceProviderABC.inject |     @ServiceProviderABC.inject | ||||||
|   | |||||||
							
								
								
									
										9
									
								
								kdb-bot/src/bot_graphql/model/featureFlags.gql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								kdb-bot/src/bot_graphql/model/featureFlags.gql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | |||||||
|  | type FeatureFlag { | ||||||
|  |     key: String | ||||||
|  |     value: Boolean | ||||||
|  | } | ||||||
|  |  | ||||||
|  | input FeatureFlagInput { | ||||||
|  |     key: String | ||||||
|  |     value: Boolean | ||||||
|  | } | ||||||
| @@ -40,4 +40,5 @@ type Query { | |||||||
|     technicianConfig: TechnicianConfig |     technicianConfig: TechnicianConfig | ||||||
|  |  | ||||||
|     guilds(filter: GuildFilter): [Guild] |     guilds(filter: GuildFilter): [Guild] | ||||||
|  |     possibleFeatureFlags: [String] | ||||||
| } | } | ||||||
| @@ -13,6 +13,8 @@ type ServerConfig implements TableWithHistoryQuery { | |||||||
|     helpVoiceChannelId: String |     helpVoiceChannelId: String | ||||||
|     teamChannelId: String |     teamChannelId: String | ||||||
|     loginMessageChannelId: String |     loginMessageChannelId: String | ||||||
|  |     featureFlagCount: Int | ||||||
|  |     featureFlags: [FeatureFlag] | ||||||
|  |  | ||||||
|     afkChannelIds: [String] |     afkChannelIds: [String] | ||||||
|     moderatorRoleIds: [String] |     moderatorRoleIds: [String] | ||||||
| @@ -41,6 +43,8 @@ type ServerConfigHistory implements HistoryTableQuery { | |||||||
|     helpVoiceChannelId: String |     helpVoiceChannelId: String | ||||||
|     teamChannelId: String |     teamChannelId: String | ||||||
|     loginMessageChannelId: String |     loginMessageChannelId: String | ||||||
|  |     featureFlagCount: Int | ||||||
|  |     featureFlags: [FeatureFlag] | ||||||
|  |  | ||||||
|     serverId: ID |     serverId: ID | ||||||
|  |  | ||||||
| @@ -87,6 +91,7 @@ input ServerConfigInput { | |||||||
|     helpVoiceChannelId: String |     helpVoiceChannelId: String | ||||||
|     teamChannelId: String |     teamChannelId: String | ||||||
|     loginMessageChannelId: String |     loginMessageChannelId: String | ||||||
|  |     featureFlags: [FeatureFlagInput] | ||||||
|  |  | ||||||
|     afkChannelIds: [String] |     afkChannelIds: [String] | ||||||
|     moderatorRoleIds: [String] |     moderatorRoleIds: [String] | ||||||
|   | |||||||
| @@ -4,6 +4,8 @@ type TechnicianConfig implements TableWithHistoryQuery { | |||||||
|     waitForRestart: Int |     waitForRestart: Int | ||||||
|     waitForShutdown: Int |     waitForShutdown: Int | ||||||
|     cacheMaxMessages: Int |     cacheMaxMessages: Int | ||||||
|  |     featureFlagCount: Int | ||||||
|  |     featureFlags: [FeatureFlag] | ||||||
|     pingURLs: [String] |     pingURLs: [String] | ||||||
|     technicianIds: [String] |     technicianIds: [String] | ||||||
|  |  | ||||||
| @@ -21,6 +23,8 @@ type TechnicianConfigHistory implements HistoryTableQuery { | |||||||
|     waitForRestart: Int |     waitForRestart: Int | ||||||
|     waitForShutdown: Int |     waitForShutdown: Int | ||||||
|     cacheMaxMessages: Int |     cacheMaxMessages: Int | ||||||
|  |     featureFlagCount: Int | ||||||
|  |     featureFlags: [FeatureFlag] | ||||||
|  |  | ||||||
|     deleted: Boolean |     deleted: Boolean | ||||||
|     dateFrom: String |     dateFrom: String | ||||||
| @@ -55,6 +59,7 @@ input TechnicianConfigInput { | |||||||
|     waitForRestart: Int |     waitForRestart: Int | ||||||
|     waitForShutdown: Int |     waitForShutdown: Int | ||||||
|     cacheMaxMessages: Int |     cacheMaxMessages: Int | ||||||
|  |     featureFlags: [FeatureFlagInput] | ||||||
|     pingURLs: [String] |     pingURLs: [String] | ||||||
|     technicianIds: [String] |     technicianIds: [String] | ||||||
| } | } | ||||||
| @@ -3,6 +3,8 @@ from cpl_discord.service import DiscordBotServiceABC | |||||||
| from cpl_query.extension import List | from cpl_query.extension import List | ||||||
|  |  | ||||||
| from bot_api.logging.api_logger import ApiLogger | from bot_api.logging.api_logger import ApiLogger | ||||||
|  | from bot_api.route.route import Route | ||||||
|  | from bot_core.service.config_service import ConfigService | ||||||
| from bot_data.abc.server_config_repository_abc import ServerConfigRepositoryABC | from bot_data.abc.server_config_repository_abc import ServerConfigRepositoryABC | ||||||
| from bot_data.abc.server_repository_abc import ServerRepositoryABC | from bot_data.abc.server_repository_abc import ServerRepositoryABC | ||||||
| from bot_data.model.server_afk_channel_ids_config import ServerAFKChannelIdsConfig | from bot_data.model.server_afk_channel_ids_config import ServerAFKChannelIdsConfig | ||||||
| @@ -11,6 +13,7 @@ from bot_data.model.server_team_role_ids_config import ServerTeamRoleIdsConfig | |||||||
| from bot_data.model.team_member_type_enum import TeamMemberTypeEnum | from bot_data.model.team_member_type_enum import TeamMemberTypeEnum | ||||||
| from bot_data.model.user_role_enum import UserRoleEnum | from bot_data.model.user_role_enum import UserRoleEnum | ||||||
| from bot_graphql.abc.query_abc import QueryABC | from bot_graphql.abc.query_abc import QueryABC | ||||||
|  | from modules.permission.abc.permission_service_abc import PermissionServiceABC | ||||||
|  |  | ||||||
|  |  | ||||||
| class ServerConfigMutation(QueryABC): | class ServerConfigMutation(QueryABC): | ||||||
| @@ -21,6 +24,8 @@ class ServerConfigMutation(QueryABC): | |||||||
|         servers: ServerRepositoryABC, |         servers: ServerRepositoryABC, | ||||||
|         server_configs: ServerConfigRepositoryABC, |         server_configs: ServerConfigRepositoryABC, | ||||||
|         db: DatabaseContextABC, |         db: DatabaseContextABC, | ||||||
|  |         config_service: ConfigService, | ||||||
|  |         permissions: PermissionServiceABC, | ||||||
|     ): |     ): | ||||||
|         QueryABC.__init__(self, "ServerConfigMutation") |         QueryABC.__init__(self, "ServerConfigMutation") | ||||||
|  |  | ||||||
| @@ -29,6 +34,8 @@ class ServerConfigMutation(QueryABC): | |||||||
|         self._servers = servers |         self._servers = servers | ||||||
|         self._server_configs = server_configs |         self._server_configs = server_configs | ||||||
|         self._db = db |         self._db = db | ||||||
|  |         self._config_service = config_service | ||||||
|  |         self._permissions = permissions | ||||||
|  |  | ||||||
|         self.set_field("updateServerConfig", self.resolve_update_server_config) |         self.set_field("updateServerConfig", self.resolve_update_server_config) | ||||||
|  |  | ||||||
| @@ -37,7 +44,7 @@ class ServerConfigMutation(QueryABC): | |||||||
|             raise ValueError("Id not set") |             raise ValueError("Id not set") | ||||||
|  |  | ||||||
|         server_config = self._server_configs.get_server_config_by_server(input["id"]) |         server_config = self._server_configs.get_server_config_by_server(input["id"]) | ||||||
|         self._can_user_mutate_data(server_config, UserRoleEnum.admin) |         self._can_user_mutate_data(Route.get_user().users[0].server, UserRoleEnum.technician) | ||||||
|  |  | ||||||
|         server_config.message_delete_timer = ( |         server_config.message_delete_timer = ( | ||||||
|             input["messageDeleteTimer"] if "messageDeleteTimer" in input else server_config.message_delete_timer |             input["messageDeleteTimer"] if "messageDeleteTimer" in input else server_config.message_delete_timer | ||||||
| @@ -82,6 +89,11 @@ class ServerConfigMutation(QueryABC): | |||||||
|             if "loginMessageChannelId" in input |             if "loginMessageChannelId" in input | ||||||
|             else server_config.login_message_channel_id |             else server_config.login_message_channel_id | ||||||
|         ) |         ) | ||||||
|  |         server_config.feature_flags = ( | ||||||
|  |             dict(zip([x["key"] for x in input["featureFlags"]], [x["value"] for x in input["featureFlags"]])) | ||||||
|  |             if "featureFlags" in input | ||||||
|  |             else server_config.feature_flags | ||||||
|  |         ) | ||||||
|         server_config.afk_channel_ids = ( |         server_config.afk_channel_ids = ( | ||||||
|             List(int).extend([int(x) for x in input["afkChannelIds"]]) |             List(int).extend([int(x) for x in input["afkChannelIds"]]) | ||||||
|             if "afkChannelIds" in input |             if "afkChannelIds" in input | ||||||
| @@ -161,3 +173,6 @@ class ServerConfigMutation(QueryABC): | |||||||
|                 continue |                 continue | ||||||
|  |  | ||||||
|             self._server_configs.add_server_team_role_id_config(role_id) |             self._server_configs.add_server_team_role_id_config(role_id) | ||||||
|  |  | ||||||
|  |         self._config_service.reload_server_config(new_config.server) | ||||||
|  |         self._permissions.on_ready() | ||||||
|   | |||||||
| @@ -3,6 +3,8 @@ from cpl_discord.service import DiscordBotServiceABC | |||||||
| from cpl_query.extension import List | from cpl_query.extension import List | ||||||
|  |  | ||||||
| from bot_api.logging.api_logger import ApiLogger | from bot_api.logging.api_logger import ApiLogger | ||||||
|  | from bot_api.route.route import Route | ||||||
|  | from bot_core.service.config_service import ConfigService | ||||||
| from bot_data.abc.server_repository_abc import ServerRepositoryABC | from bot_data.abc.server_repository_abc import ServerRepositoryABC | ||||||
| from bot_data.abc.technician_config_repository_abc import TechnicianConfigRepositoryABC | from bot_data.abc.technician_config_repository_abc import TechnicianConfigRepositoryABC | ||||||
| from bot_data.model.technician_config import TechnicianConfig | from bot_data.model.technician_config import TechnicianConfig | ||||||
| @@ -10,6 +12,7 @@ from bot_data.model.technician_id_config import TechnicianIdConfig | |||||||
| from bot_data.model.technician_ping_url_config import TechnicianPingUrlConfig | from bot_data.model.technician_ping_url_config import TechnicianPingUrlConfig | ||||||
| from bot_data.model.user_role_enum import UserRoleEnum | from bot_data.model.user_role_enum import UserRoleEnum | ||||||
| from bot_graphql.abc.query_abc import QueryABC | from bot_graphql.abc.query_abc import QueryABC | ||||||
|  | from modules.permission.abc.permission_service_abc import PermissionServiceABC | ||||||
|  |  | ||||||
|  |  | ||||||
| class TechnicianConfigMutation(QueryABC): | class TechnicianConfigMutation(QueryABC): | ||||||
| @@ -20,6 +23,8 @@ class TechnicianConfigMutation(QueryABC): | |||||||
|         servers: ServerRepositoryABC, |         servers: ServerRepositoryABC, | ||||||
|         technician_configs: TechnicianConfigRepositoryABC, |         technician_configs: TechnicianConfigRepositoryABC, | ||||||
|         db: DatabaseContextABC, |         db: DatabaseContextABC, | ||||||
|  |         permissions: PermissionServiceABC, | ||||||
|  |         config_service: ConfigService, | ||||||
|     ): |     ): | ||||||
|         QueryABC.__init__(self, "TechnicianConfigMutation") |         QueryABC.__init__(self, "TechnicianConfigMutation") | ||||||
|  |  | ||||||
| @@ -28,12 +33,14 @@ class TechnicianConfigMutation(QueryABC): | |||||||
|         self._servers = servers |         self._servers = servers | ||||||
|         self._technician_configs = technician_configs |         self._technician_configs = technician_configs | ||||||
|         self._db = db |         self._db = db | ||||||
|  |         self._permissions = permissions | ||||||
|  |         self._config_service = config_service | ||||||
|  |  | ||||||
|         self.set_field("updateTechnicianConfig", self.resolve_update_technician_config) |         self.set_field("updateTechnicianConfig", self.resolve_update_technician_config) | ||||||
|  |  | ||||||
|     def resolve_update_technician_config(self, *_, input: dict): |     def resolve_update_technician_config(self, *_, input: dict): | ||||||
|         technician_config = self._technician_configs.get_technician_config() |         technician_config = self._technician_configs.get_technician_config() | ||||||
|         self._can_user_mutate_data(technician_config, UserRoleEnum.admin) |         self._can_user_mutate_data(Route.get_user().users[0].server, UserRoleEnum.technician) | ||||||
|  |  | ||||||
|         technician_config.help_command_reference_url = ( |         technician_config.help_command_reference_url = ( | ||||||
|             input["helpCommandReferenceUrl"] |             input["helpCommandReferenceUrl"] | ||||||
| @@ -49,6 +56,11 @@ class TechnicianConfigMutation(QueryABC): | |||||||
|         technician_config.cache_max_messages = ( |         technician_config.cache_max_messages = ( | ||||||
|             input["cacheMaxMessages"] if "cacheMaxMessages" in input else technician_config.cache_max_messages |             input["cacheMaxMessages"] if "cacheMaxMessages" in input else technician_config.cache_max_messages | ||||||
|         ) |         ) | ||||||
|  |         technician_config.feature_flags = ( | ||||||
|  |             dict(zip([x["key"] for x in input["featureFlags"]], [x["value"] for x in input["featureFlags"]])) | ||||||
|  |             if "featureFlags" in input | ||||||
|  |             else technician_config.feature_flags | ||||||
|  |         ) | ||||||
|         technician_config.ping_urls = ( |         technician_config.ping_urls = ( | ||||||
|             List(str, input["pingURLs"]) if "pingURLs" in input else technician_config.ping_urls |             List(str, input["pingURLs"]) if "pingURLs" in input else technician_config.ping_urls | ||||||
|         ) |         ) | ||||||
| @@ -100,3 +112,6 @@ class TechnicianConfigMutation(QueryABC): | |||||||
|                 continue |                 continue | ||||||
|  |  | ||||||
|             self._technician_configs.add_technician_id_config(TechnicianIdConfig(technician_id)) |             self._technician_configs.add_technician_id_config(TechnicianIdConfig(technician_id)) | ||||||
|  |  | ||||||
|  |         self._config_service.reload_technician_config() | ||||||
|  |         self._permissions.on_ready() | ||||||
|   | |||||||
| @@ -1,4 +1,5 @@ | |||||||
| from cpl_core.database.context import DatabaseContextABC | from cpl_core.database.context import DatabaseContextABC | ||||||
|  | from cpl_query.extension import List | ||||||
|  |  | ||||||
| from bot_data.model.server_config_history import ServerConfigHistory | from bot_data.model.server_config_history import ServerConfigHistory | ||||||
| from bot_data.model.team_member_type_enum import TeamMemberTypeEnum | from bot_data.model.team_member_type_enum import TeamMemberTypeEnum | ||||||
| @@ -23,6 +24,10 @@ class ServerConfigQuery(DataQueryWithHistoryABC): | |||||||
|         self.set_field("helpVoiceChannelId", lambda config, *_: config.help_voice_channel_id) |         self.set_field("helpVoiceChannelId", lambda config, *_: config.help_voice_channel_id) | ||||||
|         self.set_field("teamChannelId", lambda config, *_: config.team_channel_id) |         self.set_field("teamChannelId", lambda config, *_: config.team_channel_id) | ||||||
|         self.set_field("loginMessageChannelId", lambda config, *_: config.login_message_channel_id) |         self.set_field("loginMessageChannelId", lambda config, *_: config.login_message_channel_id) | ||||||
|  |         self.add_collection( | ||||||
|  |             "featureFlag", | ||||||
|  |             lambda config, *_: List(any, [{"key": x, "value": config.feature_flags[x]} for x in config.feature_flags]), | ||||||
|  |         ) | ||||||
|         self.set_field("afkChannelIds", lambda config, *_: config.afk_channel_ids) |         self.set_field("afkChannelIds", lambda config, *_: config.afk_channel_ids) | ||||||
|         self.set_field( |         self.set_field( | ||||||
|             "moderatorRoleIds", |             "moderatorRoleIds", | ||||||
|   | |||||||
| @@ -1,3 +1,5 @@ | |||||||
|  | from cpl_query.extension import List | ||||||
|  |  | ||||||
| from bot_graphql.abc.history_query_abc import HistoryQueryABC | from bot_graphql.abc.history_query_abc import HistoryQueryABC | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -9,3 +11,7 @@ class TechnicianConfigHistoryQuery(HistoryQueryABC): | |||||||
|         self.set_field("waitForRestart", lambda config, *_: config.wait_for_restart) |         self.set_field("waitForRestart", lambda config, *_: config.wait_for_restart) | ||||||
|         self.set_field("waitForShutdown", lambda config, *_: config.wait_for_shutdown) |         self.set_field("waitForShutdown", lambda config, *_: config.wait_for_shutdown) | ||||||
|         self.set_field("cacheMaxMessages", lambda config, *_: config.cache_max_messages) |         self.set_field("cacheMaxMessages", lambda config, *_: config.cache_max_messages) | ||||||
|  |         self.add_collection( | ||||||
|  |             "featureFlag", | ||||||
|  |             lambda config, *_: List(any, [{"key": x, "value": config.feature_flags[x]} for x in config.feature_flags]), | ||||||
|  |         ) | ||||||
|   | |||||||
| @@ -16,6 +16,10 @@ class TechnicianConfigQuery(DataQueryWithHistoryABC): | |||||||
|         self.set_field("waitForRestart", lambda config, *_: config.wait_for_restart) |         self.set_field("waitForRestart", lambda config, *_: config.wait_for_restart) | ||||||
|         self.set_field("waitForShutdown", lambda config, *_: config.wait_for_shutdown) |         self.set_field("waitForShutdown", lambda config, *_: config.wait_for_shutdown) | ||||||
|         self.set_field("cacheMaxMessages", lambda config, *_: config.cache_max_messages) |         self.set_field("cacheMaxMessages", lambda config, *_: config.cache_max_messages) | ||||||
|  |         self.add_collection( | ||||||
|  |             "featureFlag", | ||||||
|  |             lambda config, *_: List(any, [{"key": x, "value": config.feature_flags[x]} for x in config.feature_flags]), | ||||||
|  |         ) | ||||||
|         self.set_field("pingURLs", lambda config, *_: config.ping_urls) |         self.set_field("pingURLs", lambda config, *_: config.ping_urls) | ||||||
|         self.set_field("technicianIds", lambda config, *_: config.technician_ids) |         self.set_field("technicianIds", lambda config, *_: config.technician_ids) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| from cpl_discord.service import DiscordBotServiceABC | from cpl_discord.service import DiscordBotServiceABC | ||||||
|  |  | ||||||
|  | from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum | ||||||
| from bot_data.abc.achievement_repository_abc import AchievementRepositoryABC | from bot_data.abc.achievement_repository_abc import AchievementRepositoryABC | ||||||
| from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC | from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC | ||||||
| from bot_data.abc.client_repository_abc import ClientRepositoryABC | from bot_data.abc.client_repository_abc import ClientRepositoryABC | ||||||
| @@ -75,6 +76,7 @@ class Query(QueryABC): | |||||||
|         self.set_field("guilds", self._resolve_guilds) |         self.set_field("guilds", self._resolve_guilds) | ||||||
|         self.set_field("achievementAttributes", lambda x, *_: achievement_service.get_attributes()) |         self.set_field("achievementAttributes", lambda x, *_: achievement_service.get_attributes()) | ||||||
|         self.set_field("achievementOperators", lambda x, *_: achievement_service.get_operators()) |         self.set_field("achievementOperators", lambda x, *_: achievement_service.get_operators()) | ||||||
|  |         self.set_field("possibleFeatureFlags", lambda x, *_: [e.value for e in FeatureFlagsEnum]) | ||||||
|  |  | ||||||
|     def _resolve_guilds(self, *_, filter=None): |     def _resolve_guilds(self, *_, filter=None): | ||||||
|         if filter is None or "id" not in filter: |         if filter is None or "id" not in filter: | ||||||
|   | |||||||
| @@ -14,7 +14,7 @@ from modules.achievements.events.achievement_on_message_event import Achievement | |||||||
|  |  | ||||||
| class AchievementsModule(ModuleABC): | class AchievementsModule(ModuleABC): | ||||||
|     def __init__(self, dc: DiscordCollectionABC): |     def __init__(self, dc: DiscordCollectionABC): | ||||||
|         ModuleABC.__init__(self, dc, FeatureFlagsEnum.auto_role_module) |         ModuleABC.__init__(self, dc, FeatureFlagsEnum.achievements_module) | ||||||
|  |  | ||||||
|     def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC): |     def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC): | ||||||
|         pass |         pass | ||||||
|   | |||||||
| @@ -1,4 +1,5 @@ | |||||||
| import discord | import discord | ||||||
|  | from cpl_core.configuration import ConfigurationABC | ||||||
| from cpl_discord.command import DiscordCommandABC | from cpl_discord.command import DiscordCommandABC | ||||||
| from cpl_discord.service import DiscordBotServiceABC | from cpl_discord.service import DiscordBotServiceABC | ||||||
| from cpl_translation import TranslatePipe | from cpl_translation import TranslatePipe | ||||||
| @@ -6,16 +7,20 @@ from discord.ext import commands | |||||||
| from discord.ext.commands import Context | from discord.ext.commands import Context | ||||||
|  |  | ||||||
| from bot_core.abc.message_service_abc import MessageServiceABC | from bot_core.abc.message_service_abc import MessageServiceABC | ||||||
|  | from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum | ||||||
|  | from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings | ||||||
| from bot_core.helper.command_checks import CommandChecks | from bot_core.helper.command_checks import CommandChecks | ||||||
| from bot_core.logging.command_logger import CommandLogger | from bot_core.logging.command_logger import CommandLogger | ||||||
| from bot_data.abc.server_repository_abc import ServerRepositoryABC | from bot_data.abc.server_repository_abc import ServerRepositoryABC | ||||||
| from bot_data.abc.user_repository_abc import UserRepositoryABC | from bot_data.abc.user_repository_abc import UserRepositoryABC | ||||||
|  | from bot_data.model.server_config import ServerConfig | ||||||
| from modules.achievements.achievement_service import AchievementService | from modules.achievements.achievement_service import AchievementService | ||||||
|  |  | ||||||
|  |  | ||||||
| class AchievementGroup(DiscordCommandABC): | class AchievementGroup(DiscordCommandABC): | ||||||
|     def __init__( |     def __init__( | ||||||
|         self, |         self, | ||||||
|  |         config: ConfigurationABC, | ||||||
|         logger: CommandLogger, |         logger: CommandLogger, | ||||||
|         message_service: MessageServiceABC, |         message_service: MessageServiceABC, | ||||||
|         bot: DiscordBotServiceABC, |         bot: DiscordBotServiceABC, | ||||||
| @@ -26,6 +31,7 @@ class AchievementGroup(DiscordCommandABC): | |||||||
|     ): |     ): | ||||||
|         DiscordCommandABC.__init__(self) |         DiscordCommandABC.__init__(self) | ||||||
|  |  | ||||||
|  |         self._config = config | ||||||
|         self._logger = logger |         self._logger = logger | ||||||
|         self._message_service = message_service |         self._message_service = message_service | ||||||
|         self._bot = bot |         self._bot = bot | ||||||
| @@ -45,6 +51,14 @@ class AchievementGroup(DiscordCommandABC): | |||||||
|     @CommandChecks.check_is_member_moderator() |     @CommandChecks.check_is_member_moderator() | ||||||
|     async def check(self, ctx: Context, member: discord.Member): |     async def check(self, ctx: Context, member: discord.Member): | ||||||
|         self._logger.debug(__name__, f"Received command achievement check {ctx}") |         self._logger.debug(__name__, f"Received command achievement check {ctx}") | ||||||
|  |         if ctx.guild is None: | ||||||
|  |             return | ||||||
|  |  | ||||||
|  |         server_config: ServerConfig = self._config.get_configuration(f"ServerConfig_{ctx.guild.id}") | ||||||
|  |         if not FeatureFlagsSettings.get_flag_from_dict( | ||||||
|  |             server_config.feature_flags, FeatureFlagsEnum.achievements_module | ||||||
|  |         ): | ||||||
|  |             return | ||||||
|  |  | ||||||
|         server = self._servers.get_server_by_discord_id(member.guild.id) |         server = self._servers.get_server_by_discord_id(member.guild.id) | ||||||
|         user = self._users.get_user_by_discord_id_and_server_id(member.id, server.id) |         user = self._users.get_user_by_discord_id_and_server_id(member.id, server.id) | ||||||
|   | |||||||
| @@ -1,18 +1,23 @@ | |||||||
| import discord | import discord | ||||||
|  | from cpl_core.configuration import ConfigurationABC | ||||||
| from cpl_core.database.context import DatabaseContextABC | from cpl_core.database.context import DatabaseContextABC | ||||||
| from cpl_core.logging import LoggerABC | from cpl_core.logging import LoggerABC | ||||||
| from cpl_discord.events import OnMessageABC | from cpl_discord.events import OnMessageABC | ||||||
| from cpl_discord.service import DiscordBotServiceABC | from cpl_discord.service import DiscordBotServiceABC | ||||||
|  |  | ||||||
|  | from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum | ||||||
|  | from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings | ||||||
| from bot_core.helper.event_checks import EventChecks | from bot_core.helper.event_checks import EventChecks | ||||||
| from bot_data.abc.server_repository_abc import ServerRepositoryABC | from bot_data.abc.server_repository_abc import ServerRepositoryABC | ||||||
| from bot_data.abc.user_repository_abc import UserRepositoryABC | from bot_data.abc.user_repository_abc import UserRepositoryABC | ||||||
|  | from bot_data.model.server_config import ServerConfig | ||||||
| from modules.achievements.achievement_service import AchievementService | from modules.achievements.achievement_service import AchievementService | ||||||
|  |  | ||||||
|  |  | ||||||
| class AchievementOnMessageEvent(OnMessageABC): | class AchievementOnMessageEvent(OnMessageABC): | ||||||
|     def __init__( |     def __init__( | ||||||
|         self, |         self, | ||||||
|  |         config: ConfigurationABC, | ||||||
|         logger: LoggerABC, |         logger: LoggerABC, | ||||||
|         bot: DiscordBotServiceABC, |         bot: DiscordBotServiceABC, | ||||||
|         achievements: AchievementService, |         achievements: AchievementService, | ||||||
| @@ -22,6 +27,7 @@ class AchievementOnMessageEvent(OnMessageABC): | |||||||
|     ): |     ): | ||||||
|         OnMessageABC.__init__(self) |         OnMessageABC.__init__(self) | ||||||
|  |  | ||||||
|  |         self._config = config | ||||||
|         self._logger = logger |         self._logger = logger | ||||||
|         self._bot = bot |         self._bot = bot | ||||||
|         self._achievements = achievements |         self._achievements = achievements | ||||||
| @@ -31,9 +37,18 @@ class AchievementOnMessageEvent(OnMessageABC): | |||||||
|  |  | ||||||
|     @EventChecks.check_is_ready() |     @EventChecks.check_is_ready() | ||||||
|     async def on_message(self, message: discord.Message): |     async def on_message(self, message: discord.Message): | ||||||
|  |         if message.guild is None: | ||||||
|  |             return | ||||||
|  |  | ||||||
|         if message.author.bot: |         if message.author.bot: | ||||||
|             return |             return | ||||||
|  |  | ||||||
|  |         server_config: ServerConfig = self._config.get_configuration(f"ServerConfig_{message.guild.id}") | ||||||
|  |         if not FeatureFlagsSettings.get_flag_from_dict( | ||||||
|  |             server_config.feature_flags, FeatureFlagsEnum.achievements_module | ||||||
|  |         ): | ||||||
|  |             return | ||||||
|  |  | ||||||
|         server = self._servers.get_server_by_discord_id(message.guild.id) |         server = self._servers.get_server_by_discord_id(message.guild.id) | ||||||
|         user = self._users.get_user_by_discord_id_and_server_id(message.author.id, server.id) |         user = self._users.get_user_by_discord_id_and_server_id(message.author.id, server.id) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| from typing import List as TList | from typing import List as TList | ||||||
|  |  | ||||||
| import discord | import discord | ||||||
|  | from cpl_core.configuration import ConfigurationABC | ||||||
| from cpl_core.database.context import DatabaseContextABC | from cpl_core.database.context import DatabaseContextABC | ||||||
| from cpl_discord.command import DiscordCommandABC | from cpl_discord.command import DiscordCommandABC | ||||||
| from cpl_discord.service import DiscordBotServiceABC | from cpl_discord.service import DiscordBotServiceABC | ||||||
| @@ -12,18 +13,22 @@ from discord.ext.commands import Context | |||||||
|  |  | ||||||
| from bot_core.abc.client_utils_abc import ClientUtilsABC | from bot_core.abc.client_utils_abc import ClientUtilsABC | ||||||
| from bot_core.abc.message_service_abc import MessageServiceABC | from bot_core.abc.message_service_abc import MessageServiceABC | ||||||
|  | from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum | ||||||
|  | from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings | ||||||
| from bot_core.helper.command_checks import CommandChecks | from bot_core.helper.command_checks import CommandChecks | ||||||
| from bot_core.logging.command_logger import CommandLogger | from bot_core.logging.command_logger import CommandLogger | ||||||
| from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC | from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC | ||||||
| from bot_data.abc.server_repository_abc import ServerRepositoryABC | from bot_data.abc.server_repository_abc import ServerRepositoryABC | ||||||
| from bot_data.model.auto_role import AutoRole | from bot_data.model.auto_role import AutoRole | ||||||
| from bot_data.model.auto_role_rule import AutoRoleRule | from bot_data.model.auto_role_rule import AutoRoleRule | ||||||
|  | from bot_data.model.server_config import ServerConfig | ||||||
| from modules.permission.abc.permission_service_abc import PermissionServiceABC | from modules.permission.abc.permission_service_abc import PermissionServiceABC | ||||||
|  |  | ||||||
|  |  | ||||||
| class AutoRoleGroup(DiscordCommandABC): | class AutoRoleGroup(DiscordCommandABC): | ||||||
|     def __init__( |     def __init__( | ||||||
|         self, |         self, | ||||||
|  |         config: ConfigurationABC, | ||||||
|         logger: CommandLogger, |         logger: CommandLogger, | ||||||
|         message_service: MessageServiceABC, |         message_service: MessageServiceABC, | ||||||
|         bot: DiscordBotServiceABC, |         bot: DiscordBotServiceABC, | ||||||
| @@ -36,6 +41,7 @@ class AutoRoleGroup(DiscordCommandABC): | |||||||
|     ): |     ): | ||||||
|         DiscordCommandABC.__init__(self) |         DiscordCommandABC.__init__(self) | ||||||
|  |  | ||||||
|  |         self._config = config | ||||||
|         self._logger = logger |         self._logger = logger | ||||||
|         self._message_service = message_service |         self._message_service = message_service | ||||||
|         self._bot = bot |         self._bot = bot | ||||||
| @@ -69,10 +75,13 @@ class AutoRoleGroup(DiscordCommandABC): | |||||||
|     @CommandChecks.check_is_member_moderator() |     @CommandChecks.check_is_member_moderator() | ||||||
|     async def list(self, ctx: Context, wait: int = None): |     async def list(self, ctx: Context, wait: int = None): | ||||||
|         self._logger.debug(__name__, f"Received command auto-role list {ctx}") |         self._logger.debug(__name__, f"Received command auto-role list {ctx}") | ||||||
|  |  | ||||||
|         if ctx.guild is None: |         if ctx.guild is None: | ||||||
|             return |             return | ||||||
|  |  | ||||||
|  |         server_config: ServerConfig = self._config.get_configuration(f"ServerConfig_{ctx.guild_id}") | ||||||
|  |         if not FeatureFlagsSettings.get_flag_from_dict(server_config.feature_flags, FeatureFlagsEnum.auto_role_module): | ||||||
|  |             return | ||||||
|  |  | ||||||
|         embed = discord.Embed( |         embed = discord.Embed( | ||||||
|             title=self._t.transform("modules.auto_role.list.title"), |             title=self._t.transform("modules.auto_role.list.title"), | ||||||
|             description=self._t.transform("modules.auto_role.list.description"), |             description=self._t.transform("modules.auto_role.list.description"), | ||||||
| @@ -110,6 +119,12 @@ class AutoRoleGroup(DiscordCommandABC): | |||||||
|     @CommandChecks.check_is_member_moderator() |     @CommandChecks.check_is_member_moderator() | ||||||
|     async def add(self, ctx: Context, channel: discord.TextChannel, message_id: str): |     async def add(self, ctx: Context, channel: discord.TextChannel, message_id: str): | ||||||
|         self._logger.debug(__name__, f"Received command auto-role add {ctx} {message_id}") |         self._logger.debug(__name__, f"Received command auto-role add {ctx} {message_id}") | ||||||
|  |         if ctx.guild is None: | ||||||
|  |             return | ||||||
|  |  | ||||||
|  |         server_config: ServerConfig = self._config.get_configuration(f"ServerConfig_{ctx.guild_id}") | ||||||
|  |         if not FeatureFlagsSettings.get_flag_from_dict(server_config.feature_flags, FeatureFlagsEnum.auto_role_module): | ||||||
|  |             return | ||||||
|  |  | ||||||
|         message = ( |         message = ( | ||||||
|             List( |             List( | ||||||
| @@ -170,6 +185,12 @@ class AutoRoleGroup(DiscordCommandABC): | |||||||
|     @CommandChecks.check_is_member_moderator() |     @CommandChecks.check_is_member_moderator() | ||||||
|     async def remove(self, ctx: Context, auto_role: int): |     async def remove(self, ctx: Context, auto_role: int): | ||||||
|         self._logger.debug(__name__, f"Received command auto-role remove {ctx} {auto_role}") |         self._logger.debug(__name__, f"Received command auto-role remove {ctx} {auto_role}") | ||||||
|  |         if ctx.guild is None: | ||||||
|  |             return | ||||||
|  |  | ||||||
|  |         server_config: ServerConfig = self._config.get_configuration(f"ServerConfig_{ctx.guild_id}") | ||||||
|  |         if not FeatureFlagsSettings.get_flag_from_dict(server_config.feature_flags, FeatureFlagsEnum.auto_role_module): | ||||||
|  |             return | ||||||
|  |  | ||||||
|         auto_role_from_db = self._auto_roles.find_auto_role_by_id(auto_role) |         auto_role_from_db = self._auto_roles.find_auto_role_by_id(auto_role) | ||||||
|         if auto_role_from_db is None: |         if auto_role_from_db is None: | ||||||
| @@ -210,6 +231,12 @@ class AutoRoleGroup(DiscordCommandABC): | |||||||
|     @CommandChecks.check_is_member_moderator() |     @CommandChecks.check_is_member_moderator() | ||||||
|     async def list(self, ctx: Context, auto_role: int, wait: int = None): |     async def list(self, ctx: Context, auto_role: int, wait: int = None): | ||||||
|         self._logger.debug(__name__, f"Received command auto-role rule list {ctx}") |         self._logger.debug(__name__, f"Received command auto-role rule list {ctx}") | ||||||
|  |         if ctx.guild is None: | ||||||
|  |             return | ||||||
|  |  | ||||||
|  |         server_config: ServerConfig = self._config.get_configuration(f"ServerConfig_{ctx.guild_id}") | ||||||
|  |         if not FeatureFlagsSettings.get_flag_from_dict(server_config.feature_flags, FeatureFlagsEnum.auto_role_module): | ||||||
|  |             return | ||||||
|  |  | ||||||
|         embed = discord.Embed( |         embed = discord.Embed( | ||||||
|             title=self._t.transform("modules.auto_role.list.title"), |             title=self._t.transform("modules.auto_role.list.title"), | ||||||
| @@ -262,6 +289,12 @@ class AutoRoleGroup(DiscordCommandABC): | |||||||
|     @CommandChecks.check_is_member_moderator() |     @CommandChecks.check_is_member_moderator() | ||||||
|     async def add(self, ctx: Context, auto_role: int, emoji_name: str, role_id: str): |     async def add(self, ctx: Context, auto_role: int, emoji_name: str, role_id: str): | ||||||
|         self._logger.debug(__name__, f"Received command auto-role add {ctx} {auto_role}") |         self._logger.debug(__name__, f"Received command auto-role add {ctx} {auto_role}") | ||||||
|  |         if ctx.guild is None: | ||||||
|  |             return | ||||||
|  |  | ||||||
|  |         server_config: ServerConfig = self._config.get_configuration(f"ServerConfig_{ctx.guild_id}") | ||||||
|  |         if not FeatureFlagsSettings.get_flag_from_dict(server_config.feature_flags, FeatureFlagsEnum.auto_role_module): | ||||||
|  |             return | ||||||
|  |  | ||||||
|         emoji = discord.utils.get(self._bot.emojis, name=emoji_name) |         emoji = discord.utils.get(self._bot.emojis, name=emoji_name) | ||||||
|         if emoji is None: |         if emoji is None: | ||||||
| @@ -354,6 +387,12 @@ class AutoRoleGroup(DiscordCommandABC): | |||||||
|     @CommandChecks.check_is_member_moderator() |     @CommandChecks.check_is_member_moderator() | ||||||
|     async def remove(self, ctx: Context, auto_role_rule: int): |     async def remove(self, ctx: Context, auto_role_rule: int): | ||||||
|         self._logger.debug(__name__, f"Received command auto-role remove {ctx} {auto_role_rule}") |         self._logger.debug(__name__, f"Received command auto-role remove {ctx} {auto_role_rule}") | ||||||
|  |         if ctx.guild is None: | ||||||
|  |             return | ||||||
|  |  | ||||||
|  |         server_config: ServerConfig = self._config.get_configuration(f"ServerConfig_{ctx.guild_id}") | ||||||
|  |         if not FeatureFlagsSettings.get_flag_from_dict(server_config.feature_flags, FeatureFlagsEnum.auto_role_module): | ||||||
|  |             return | ||||||
|  |  | ||||||
|         auto_role_from_db = self._auto_roles.get_auto_role_rule_by_id(auto_role_rule) |         auto_role_from_db = self._auto_roles.get_auto_role_rule_by_id(auto_role_rule) | ||||||
|         if auto_role_from_db is None: |         if auto_role_from_db is None: | ||||||
|   | |||||||
| @@ -1,17 +1,22 @@ | |||||||
|  | from cpl_core.configuration import ConfigurationABC | ||||||
| from cpl_core.logging import LoggerABC | from cpl_core.logging import LoggerABC | ||||||
| from cpl_discord.events.on_raw_reaction_add_abc import OnRawReactionAddABC | from cpl_discord.events.on_raw_reaction_add_abc import OnRawReactionAddABC | ||||||
| from cpl_discord.service import DiscordBotServiceABC | from cpl_discord.service import DiscordBotServiceABC | ||||||
| from discord import RawReactionActionEvent | from discord import RawReactionActionEvent | ||||||
|  |  | ||||||
|  | from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum | ||||||
|  | from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings | ||||||
| from bot_core.helper.event_checks import EventChecks | from bot_core.helper.event_checks import EventChecks | ||||||
| from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC | from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC | ||||||
| from bot_data.abc.server_repository_abc import ServerRepositoryABC | from bot_data.abc.server_repository_abc import ServerRepositoryABC | ||||||
|  | from bot_data.model.server_config import ServerConfig | ||||||
| from modules.auto_role.helper.auto_role_reaction_handler import AutoRoleReactionHandler | from modules.auto_role.helper.auto_role_reaction_handler import AutoRoleReactionHandler | ||||||
|  |  | ||||||
|  |  | ||||||
| class AutoRoleOnRawReactionAddEvent(OnRawReactionAddABC): | class AutoRoleOnRawReactionAddEvent(OnRawReactionAddABC): | ||||||
|     def __init__( |     def __init__( | ||||||
|         self, |         self, | ||||||
|  |         config: ConfigurationABC, | ||||||
|         logger: LoggerABC, |         logger: LoggerABC, | ||||||
|         bot: DiscordBotServiceABC, |         bot: DiscordBotServiceABC, | ||||||
|         servers: ServerRepositoryABC, |         servers: ServerRepositoryABC, | ||||||
| @@ -20,6 +25,7 @@ class AutoRoleOnRawReactionAddEvent(OnRawReactionAddABC): | |||||||
|     ): |     ): | ||||||
|         OnRawReactionAddABC.__init__(self) |         OnRawReactionAddABC.__init__(self) | ||||||
|  |  | ||||||
|  |         self._config = config | ||||||
|         self._logger = logger |         self._logger = logger | ||||||
|         self._bot = bot |         self._bot = bot | ||||||
|         self._servers = servers |         self._servers = servers | ||||||
| @@ -29,6 +35,9 @@ class AutoRoleOnRawReactionAddEvent(OnRawReactionAddABC): | |||||||
|     @EventChecks.check_is_ready() |     @EventChecks.check_is_ready() | ||||||
|     async def on_raw_reaction_add(self, payload: RawReactionActionEvent): |     async def on_raw_reaction_add(self, payload: RawReactionActionEvent): | ||||||
|         self._logger.debug(__name__, f"Module {type(self)} started") |         self._logger.debug(__name__, f"Module {type(self)} started") | ||||||
|  |         server_config: ServerConfig = self._config.get_configuration(f"ServerConfig_{payload.guild_id}") | ||||||
|  |         if not FeatureFlagsSettings.get_flag_from_dict(server_config.feature_flags, FeatureFlagsEnum.auto_role_module): | ||||||
|  |             return | ||||||
|  |  | ||||||
|         await self._reaction_handler.handle(payload, "add") |         await self._reaction_handler.handle(payload, "add") | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,17 +1,22 @@ | |||||||
|  | from cpl_core.configuration import ConfigurationABC | ||||||
| from cpl_core.logging import LoggerABC | from cpl_core.logging import LoggerABC | ||||||
| from cpl_discord.events.on_raw_reaction_remove_abc import OnRawReactionRemoveABC | from cpl_discord.events.on_raw_reaction_remove_abc import OnRawReactionRemoveABC | ||||||
| from cpl_discord.service import DiscordBotServiceABC | from cpl_discord.service import DiscordBotServiceABC | ||||||
| from discord import RawReactionActionEvent | from discord import RawReactionActionEvent | ||||||
|  |  | ||||||
|  | from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum | ||||||
|  | from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings | ||||||
| from bot_core.helper.event_checks import EventChecks | from bot_core.helper.event_checks import EventChecks | ||||||
| from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC | from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC | ||||||
| from bot_data.abc.server_repository_abc import ServerRepositoryABC | from bot_data.abc.server_repository_abc import ServerRepositoryABC | ||||||
|  | from bot_data.model.server_config import ServerConfig | ||||||
| from modules.auto_role.helper.auto_role_reaction_handler import AutoRoleReactionHandler | from modules.auto_role.helper.auto_role_reaction_handler import AutoRoleReactionHandler | ||||||
|  |  | ||||||
|  |  | ||||||
| class AutoRoleOnRawReactionRemoveEvent(OnRawReactionRemoveABC): | class AutoRoleOnRawReactionRemoveEvent(OnRawReactionRemoveABC): | ||||||
|     def __init__( |     def __init__( | ||||||
|         self, |         self, | ||||||
|  |         config: ConfigurationABC, | ||||||
|         logger: LoggerABC, |         logger: LoggerABC, | ||||||
|         bot: DiscordBotServiceABC, |         bot: DiscordBotServiceABC, | ||||||
|         servers: ServerRepositoryABC, |         servers: ServerRepositoryABC, | ||||||
| @@ -20,6 +25,7 @@ class AutoRoleOnRawReactionRemoveEvent(OnRawReactionRemoveABC): | |||||||
|     ): |     ): | ||||||
|         OnRawReactionRemoveABC.__init__(self) |         OnRawReactionRemoveABC.__init__(self) | ||||||
|  |  | ||||||
|  |         self._config = config | ||||||
|         self._logger = logger |         self._logger = logger | ||||||
|         self._bot = bot |         self._bot = bot | ||||||
|         self._servers = servers |         self._servers = servers | ||||||
| @@ -29,6 +35,9 @@ class AutoRoleOnRawReactionRemoveEvent(OnRawReactionRemoveABC): | |||||||
|     @EventChecks.check_is_ready() |     @EventChecks.check_is_ready() | ||||||
|     async def on_raw_reaction_remove(self, payload: RawReactionActionEvent): |     async def on_raw_reaction_remove(self, payload: RawReactionActionEvent): | ||||||
|         self._logger.debug(__name__, f"Module {type(self)} started") |         self._logger.debug(__name__, f"Module {type(self)} started") | ||||||
|  |         server_config: ServerConfig = self._config.get_configuration(f"ServerConfig_{payload.guild_id}") | ||||||
|  |         if not FeatureFlagsSettings.get_flag_from_dict(server_config.feature_flags, FeatureFlagsEnum.auto_role_module): | ||||||
|  |             return | ||||||
|  |  | ||||||
|         await self._reaction_handler.handle(payload, "remove") |         await self._reaction_handler.handle(payload, "remove") | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| from typing import Optional | from typing import Optional | ||||||
|  |  | ||||||
| import discord | import discord | ||||||
|  | from cpl_core.configuration import ConfigurationABC | ||||||
| from cpl_core.database.context import DatabaseContextABC | from cpl_core.database.context import DatabaseContextABC | ||||||
| from cpl_core.time import TimeFormatSettings | from cpl_core.time import TimeFormatSettings | ||||||
| from cpl_discord.events import OnCommandABC | from cpl_discord.events import OnCommandABC | ||||||
| @@ -13,12 +14,14 @@ from bot_core.logging.command_logger import CommandLogger | |||||||
| from bot_data.abc.client_repository_abc import ClientRepositoryABC | from bot_data.abc.client_repository_abc import ClientRepositoryABC | ||||||
| from bot_data.abc.server_repository_abc import ServerRepositoryABC | from bot_data.abc.server_repository_abc import ServerRepositoryABC | ||||||
| from bot_data.abc.user_repository_abc import UserRepositoryABC | from bot_data.abc.user_repository_abc import UserRepositoryABC | ||||||
|  | from bot_data.model.server_config import ServerConfig | ||||||
| from bot_data.model.user import User | from bot_data.model.user import User | ||||||
|  |  | ||||||
|  |  | ||||||
| class BaseOnCommandEvent(OnCommandABC): | class BaseOnCommandEvent(OnCommandABC): | ||||||
|     def __init__( |     def __init__( | ||||||
|         self, |         self, | ||||||
|  |         config: ConfigurationABC, | ||||||
|         logger: CommandLogger, |         logger: CommandLogger, | ||||||
|         bot: DiscordBotServiceABC, |         bot: DiscordBotServiceABC, | ||||||
|         messenger: MessageServiceABC, |         messenger: MessageServiceABC, | ||||||
| @@ -30,6 +33,7 @@ class BaseOnCommandEvent(OnCommandABC): | |||||||
|         servers: ServerRepositoryABC, |         servers: ServerRepositoryABC, | ||||||
|     ): |     ): | ||||||
|         OnCommandABC.__init__(self) |         OnCommandABC.__init__(self) | ||||||
|  |         self._config = config | ||||||
|         self._logger = logger |         self._logger = logger | ||||||
|         self._bot = bot |         self._bot = bot | ||||||
|         self._messenger = messenger |         self._messenger = messenger | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| from typing import Optional | from typing import Optional | ||||||
|  |  | ||||||
| import discord | import discord | ||||||
|  | from cpl_core.configuration import ConfigurationABC | ||||||
| from cpl_core.database.context import DatabaseContextABC | from cpl_core.database.context import DatabaseContextABC | ||||||
| from cpl_discord.events import OnMessageDeleteABC | from cpl_discord.events import OnMessageDeleteABC | ||||||
| from cpl_discord.service import DiscordBotServiceABC | from cpl_discord.service import DiscordBotServiceABC | ||||||
| @@ -10,12 +11,14 @@ from bot_core.logging.message_logger import MessageLogger | |||||||
| from bot_data.abc.client_repository_abc import ClientRepositoryABC | from bot_data.abc.client_repository_abc import ClientRepositoryABC | ||||||
| from bot_data.abc.server_repository_abc import ServerRepositoryABC | from bot_data.abc.server_repository_abc import ServerRepositoryABC | ||||||
| from bot_data.abc.user_repository_abc import UserRepositoryABC | from bot_data.abc.user_repository_abc import UserRepositoryABC | ||||||
|  | from bot_data.model.server_config import ServerConfig | ||||||
| from bot_data.model.user import User | from bot_data.model.user import User | ||||||
|  |  | ||||||
|  |  | ||||||
| class BaseOnMessageDeleteEvent(OnMessageDeleteABC): | class BaseOnMessageDeleteEvent(OnMessageDeleteABC): | ||||||
|     def __init__( |     def __init__( | ||||||
|         self, |         self, | ||||||
|  |         config: ConfigurationABC, | ||||||
|         logger: MessageLogger, |         logger: MessageLogger, | ||||||
|         db: DatabaseContextABC, |         db: DatabaseContextABC, | ||||||
|         bot: DiscordBotServiceABC, |         bot: DiscordBotServiceABC, | ||||||
| @@ -24,6 +27,7 @@ class BaseOnMessageDeleteEvent(OnMessageDeleteABC): | |||||||
|         servers: ServerRepositoryABC, |         servers: ServerRepositoryABC, | ||||||
|     ): |     ): | ||||||
|         OnMessageDeleteABC.__init__(self) |         OnMessageDeleteABC.__init__(self) | ||||||
|  |         self._config = config | ||||||
|         self._logger = logger |         self._logger = logger | ||||||
|         self._db = db |         self._db = db | ||||||
|         self._bot = bot |         self._bot = bot | ||||||
|   | |||||||
| @@ -8,6 +8,8 @@ from cpl_translation import TranslatePipe | |||||||
| from discord import guild | from discord import guild | ||||||
|  |  | ||||||
| from bot_core.abc.message_service_abc import MessageServiceABC | from bot_core.abc.message_service_abc import MessageServiceABC | ||||||
|  | from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum | ||||||
|  | from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings | ||||||
| from bot_data.model.server_config import ServerConfig | from bot_data.model.server_config import ServerConfig | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -60,6 +62,11 @@ class BootLogOnReadyEvent(OnReadyABC): | |||||||
|                 self._logger.error(__name__, f"Config {type(self).__name__}_{g.id} not found!") |                 self._logger.error(__name__, f"Config {type(self).__name__}_{g.id} not found!") | ||||||
|                 return |                 return | ||||||
|  |  | ||||||
|  |             if not FeatureFlagsSettings.get_flag_from_dict( | ||||||
|  |                 server_config.feature_flags, FeatureFlagsEnum.boot_log_module | ||||||
|  |             ): | ||||||
|  |                 continue | ||||||
|  |  | ||||||
|             self._bot.loop.create_task( |             self._bot.loop.create_task( | ||||||
|                 self._message_service.send_channel_message( |                 self._message_service.send_channel_message( | ||||||
|                     self._bot.get_channel(server_config.login_message_channel_id), |                     self._bot.get_channel(server_config.login_message_channel_id), | ||||||
|   | |||||||
| @@ -5,8 +5,7 @@ from cpl_core.logging import LoggerABC | |||||||
|  |  | ||||||
| from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum | from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum | ||||||
| from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings | from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings | ||||||
| from bot_data.abc.technician_config_repository_abc import TechnicianConfigRepositoryABC | from bot_core.service.config_service import ConfigService | ||||||
| from bot_data.model.technician_config import TechnicianConfig |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class ConfigExtension(ApplicationExtensionABC): | class ConfigExtension(ApplicationExtensionABC): | ||||||
| @@ -19,6 +18,5 @@ class ConfigExtension(ApplicationExtensionABC): | |||||||
|             return |             return | ||||||
|         logger: LoggerABC = services.get_service(LoggerABC) |         logger: LoggerABC = services.get_service(LoggerABC) | ||||||
|         logger.debug(__name__, "Config extension started") |         logger.debug(__name__, "Config extension started") | ||||||
|         technician_config_repo: TechnicianConfigRepositoryABC = services.get_service(TechnicianConfigRepositoryABC) |         config: ConfigService = services.get_service(ConfigService) | ||||||
|         technician_config = technician_config_repo.get_technician_config() |         config.reload_technician_config() | ||||||
|         config.add_configuration(TechnicianConfig, technician_config) |  | ||||||
|   | |||||||
| @@ -1,10 +1,9 @@ | |||||||
| from cpl_core.configuration import ConfigurationABC | from cpl_core.configuration import ConfigurationABC | ||||||
| from cpl_core.logging import LoggerABC | from cpl_core.logging import LoggerABC | ||||||
| from cpl_discord.container import Guild |  | ||||||
| from cpl_discord.events import OnReadyABC | from cpl_discord.events import OnReadyABC | ||||||
| from cpl_discord.service import DiscordBotServiceABC | from cpl_discord.service import DiscordBotServiceABC | ||||||
|  |  | ||||||
| from bot_data.abc.server_config_repository_abc import ServerConfigRepositoryABC | from bot_core.service.config_service import ConfigService | ||||||
| from bot_data.abc.server_repository_abc import ServerRepositoryABC | from bot_data.abc.server_repository_abc import ServerRepositoryABC | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -15,7 +14,7 @@ class ConfigOnReadyEvent(OnReadyABC): | |||||||
|         logger: LoggerABC, |         logger: LoggerABC, | ||||||
|         bot: DiscordBotServiceABC, |         bot: DiscordBotServiceABC, | ||||||
|         servers: ServerRepositoryABC, |         servers: ServerRepositoryABC, | ||||||
|         server_config_repo: ServerConfigRepositoryABC, |         config_service: ConfigService, | ||||||
|     ): |     ): | ||||||
|         OnReadyABC.__init__(self) |         OnReadyABC.__init__(self) | ||||||
|  |  | ||||||
| @@ -23,13 +22,8 @@ class ConfigOnReadyEvent(OnReadyABC): | |||||||
|         self._logger = logger |         self._logger = logger | ||||||
|         self._bot = bot |         self._bot = bot | ||||||
|         self._servers = servers |         self._servers = servers | ||||||
|         self._server_config_repo = server_config_repo |         self._config_service = config_service | ||||||
|  |  | ||||||
|     async def on_ready(self): |     async def on_ready(self): | ||||||
|         for guild in self._bot.guilds: |         for guild in self._bot.guilds: | ||||||
|             guild: Guild = guild |             self._config_service.reload_server_config(self._servers.get_server_by_discord_id(guild.id)) | ||||||
|             server = self._servers.get_server_by_discord_id(guild.id) |  | ||||||
|             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 |  | ||||||
|             ) |  | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| from typing import List as TList | from typing import List as TList | ||||||
|  |  | ||||||
| import discord | import discord | ||||||
|  | from cpl_core.configuration import ConfigurationABC | ||||||
| from cpl_core.database.context import DatabaseContextABC | from cpl_core.database.context import DatabaseContextABC | ||||||
| from cpl_discord.command import DiscordCommandABC | from cpl_discord.command import DiscordCommandABC | ||||||
| from cpl_discord.container import Guild, Role | from cpl_discord.container import Guild, Role | ||||||
| @@ -12,12 +13,15 @@ from discord.ext.commands import Context | |||||||
|  |  | ||||||
| from bot_core.abc.client_utils_abc import ClientUtilsABC | from bot_core.abc.client_utils_abc import ClientUtilsABC | ||||||
| from bot_core.abc.message_service_abc import MessageServiceABC | from bot_core.abc.message_service_abc import MessageServiceABC | ||||||
|  | from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum | ||||||
|  | from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings | ||||||
| from bot_core.helper.command_checks import CommandChecks | from bot_core.helper.command_checks import CommandChecks | ||||||
| from bot_core.logging.command_logger import CommandLogger | from bot_core.logging.command_logger import CommandLogger | ||||||
| from bot_data.abc.level_repository_abc import LevelRepositoryABC | from bot_data.abc.level_repository_abc import LevelRepositoryABC | ||||||
| from bot_data.abc.server_repository_abc import ServerRepositoryABC | from bot_data.abc.server_repository_abc import ServerRepositoryABC | ||||||
| from bot_data.abc.user_repository_abc import UserRepositoryABC | from bot_data.abc.user_repository_abc import UserRepositoryABC | ||||||
| from bot_data.model.level import Level | from bot_data.model.level import Level | ||||||
|  | from bot_data.model.server_config import ServerConfig | ||||||
| from modules.level.level_seeder import LevelSeeder | from modules.level.level_seeder import LevelSeeder | ||||||
| from modules.level.service.level_service import LevelService | from modules.level.service.level_service import LevelService | ||||||
| from modules.permission.abc.permission_service_abc import PermissionServiceABC | from modules.permission.abc.permission_service_abc import PermissionServiceABC | ||||||
| @@ -26,6 +30,7 @@ from modules.permission.abc.permission_service_abc import PermissionServiceABC | |||||||
| class LevelGroup(DiscordCommandABC): | class LevelGroup(DiscordCommandABC): | ||||||
|     def __init__( |     def __init__( | ||||||
|         self, |         self, | ||||||
|  |         config: ConfigurationABC, | ||||||
|         logger: CommandLogger, |         logger: CommandLogger, | ||||||
|         message_service: MessageServiceABC, |         message_service: MessageServiceABC, | ||||||
|         bot: DiscordBotServiceABC, |         bot: DiscordBotServiceABC, | ||||||
| @@ -41,6 +46,7 @@ class LevelGroup(DiscordCommandABC): | |||||||
|     ): |     ): | ||||||
|         DiscordCommandABC.__init__(self) |         DiscordCommandABC.__init__(self) | ||||||
|  |  | ||||||
|  |         self._config = config | ||||||
|         self._logger = logger |         self._logger = logger | ||||||
|         self._message_service = message_service |         self._message_service = message_service | ||||||
|         self._bot = bot |         self._bot = bot | ||||||
| @@ -125,10 +131,13 @@ class LevelGroup(DiscordCommandABC): | |||||||
|     @CommandChecks.check_is_member_moderator() |     @CommandChecks.check_is_member_moderator() | ||||||
|     async def list(self, ctx: Context, wait: int = None): |     async def list(self, ctx: Context, wait: int = None): | ||||||
|         self._logger.debug(__name__, f"Received command level list {ctx}") |         self._logger.debug(__name__, f"Received command level list {ctx}") | ||||||
|  |  | ||||||
|         if ctx.guild is None: |         if ctx.guild is None: | ||||||
|             return |             return | ||||||
|  |  | ||||||
|  |         server_config: ServerConfig = self._config.get_configuration(f"ServerConfig_{ctx.guild.id}") | ||||||
|  |         if not FeatureFlagsSettings.get_flag_from_dict(server_config.feature_flags, FeatureFlagsEnum.level_module): | ||||||
|  |             return | ||||||
|  |  | ||||||
|         server = self._servers.get_server_by_discord_id(ctx.guild.id) |         server = self._servers.get_server_by_discord_id(ctx.guild.id) | ||||||
|         levels = self._levels.get_levels_by_server_id(server.id) |         levels = self._levels.get_levels_by_server_id(server.id) | ||||||
|         if levels.count() < 1: |         if levels.count() < 1: | ||||||
| @@ -169,6 +178,12 @@ class LevelGroup(DiscordCommandABC): | |||||||
|     @CommandChecks.check_is_member_admin() |     @CommandChecks.check_is_member_admin() | ||||||
|     async def create(self, ctx: Context, name: str, color: str, min_xp: int, permissions: int): |     async def create(self, ctx: Context, name: str, color: str, min_xp: int, permissions: int): | ||||||
|         self._logger.debug(__name__, f"Received command level create {ctx}") |         self._logger.debug(__name__, f"Received command level create {ctx}") | ||||||
|  |         if ctx.guild is None: | ||||||
|  |             return | ||||||
|  |  | ||||||
|  |         server_config: ServerConfig = self._config.get_configuration(f"ServerConfig_{ctx.guild.id}") | ||||||
|  |         if not FeatureFlagsSettings.get_flag_from_dict(server_config.feature_flags, FeatureFlagsEnum.level_module): | ||||||
|  |             return | ||||||
|  |  | ||||||
|         try: |         try: | ||||||
|             color = hex(discord.Colour.from_str(color).value) |             color = hex(discord.Colour.from_str(color).value) | ||||||
| @@ -258,6 +273,12 @@ class LevelGroup(DiscordCommandABC): | |||||||
|         permissions: int = None, |         permissions: int = None, | ||||||
|     ): |     ): | ||||||
|         self._logger.debug(__name__, f"Received command level edit {ctx}") |         self._logger.debug(__name__, f"Received command level edit {ctx}") | ||||||
|  |         if ctx.guild is None: | ||||||
|  |             return | ||||||
|  |  | ||||||
|  |         server_config: ServerConfig = self._config.get_configuration(f"ServerConfig_{ctx.guild.id}") | ||||||
|  |         if not FeatureFlagsSettings.get_flag_from_dict(server_config.feature_flags, FeatureFlagsEnum.level_module): | ||||||
|  |             return | ||||||
|  |  | ||||||
|         server = self._servers.get_server_by_discord_id(ctx.guild.id) |         server = self._servers.get_server_by_discord_id(ctx.guild.id) | ||||||
|         level_from_db = ( |         level_from_db = ( | ||||||
| @@ -350,6 +371,12 @@ class LevelGroup(DiscordCommandABC): | |||||||
|     @CommandChecks.check_is_member_admin() |     @CommandChecks.check_is_member_admin() | ||||||
|     async def remove(self, ctx: Context, level: str): |     async def remove(self, ctx: Context, level: str): | ||||||
|         self._logger.debug(__name__, f"Received command level remove {ctx}") |         self._logger.debug(__name__, f"Received command level remove {ctx}") | ||||||
|  |         if ctx.guild is None: | ||||||
|  |             return | ||||||
|  |  | ||||||
|  |         server_config: ServerConfig = self._config.get_configuration(f"ServerConfig_{ctx.guild.id}") | ||||||
|  |         if not FeatureFlagsSettings.get_flag_from_dict(server_config.feature_flags, FeatureFlagsEnum.level_module): | ||||||
|  |             return | ||||||
|  |  | ||||||
|         server = self._servers.get_server_by_discord_id(ctx.guild.id) |         server = self._servers.get_server_by_discord_id(ctx.guild.id) | ||||||
|         level_from_db = ( |         level_from_db = ( | ||||||
| @@ -394,6 +421,12 @@ class LevelGroup(DiscordCommandABC): | |||||||
|     @CommandChecks.check_is_member_moderator() |     @CommandChecks.check_is_member_moderator() | ||||||
|     async def down(self, ctx: Context, member: discord.Member): |     async def down(self, ctx: Context, member: discord.Member): | ||||||
|         self._logger.debug(__name__, f"Received command level down {ctx} {member}") |         self._logger.debug(__name__, f"Received command level down {ctx} {member}") | ||||||
|  |         if ctx.guild is None: | ||||||
|  |             return | ||||||
|  |  | ||||||
|  |         server_config: ServerConfig = self._config.get_configuration(f"ServerConfig_{ctx.guild.id}") | ||||||
|  |         if not FeatureFlagsSettings.get_flag_from_dict(server_config.feature_flags, FeatureFlagsEnum.level_module): | ||||||
|  |             return | ||||||
|  |  | ||||||
|         if member.bot: |         if member.bot: | ||||||
|             return |             return | ||||||
| @@ -436,6 +469,12 @@ class LevelGroup(DiscordCommandABC): | |||||||
|     @CommandChecks.check_is_member_moderator() |     @CommandChecks.check_is_member_moderator() | ||||||
|     async def up(self, ctx: Context, member: discord.Member): |     async def up(self, ctx: Context, member: discord.Member): | ||||||
|         self._logger.debug(__name__, f"Received command level up {ctx} {member}") |         self._logger.debug(__name__, f"Received command level up {ctx} {member}") | ||||||
|  |         if ctx.guild is None: | ||||||
|  |             return | ||||||
|  |  | ||||||
|  |         server_config: ServerConfig = self._config.get_configuration(f"ServerConfig_{ctx.guild.id}") | ||||||
|  |         if not FeatureFlagsSettings.get_flag_from_dict(server_config.feature_flags, FeatureFlagsEnum.level_module): | ||||||
|  |             return | ||||||
|  |  | ||||||
|         if member.bot: |         if member.bot: | ||||||
|             return |             return | ||||||
| @@ -477,6 +516,12 @@ class LevelGroup(DiscordCommandABC): | |||||||
|     @CommandChecks.check_is_member_moderator() |     @CommandChecks.check_is_member_moderator() | ||||||
|     async def set(self, ctx: Context, member: discord.Member, level: str): |     async def set(self, ctx: Context, member: discord.Member, level: str): | ||||||
|         self._logger.debug(__name__, f"Received command level up {ctx} {member}") |         self._logger.debug(__name__, f"Received command level up {ctx} {member}") | ||||||
|  |         if ctx.guild is None: | ||||||
|  |             return | ||||||
|  |  | ||||||
|  |         server_config: ServerConfig = self._config.get_configuration(f"ServerConfig_{ctx.guild.id}") | ||||||
|  |         if not FeatureFlagsSettings.get_flag_from_dict(server_config.feature_flags, FeatureFlagsEnum.level_module): | ||||||
|  |             return | ||||||
|  |  | ||||||
|         if member.bot: |         if member.bot: | ||||||
|             return |             return | ||||||
| @@ -529,5 +574,12 @@ class LevelGroup(DiscordCommandABC): | |||||||
|     @CommandChecks.check_is_member_moderator() |     @CommandChecks.check_is_member_moderator() | ||||||
|     async def reload(self, ctx: Context): |     async def reload(self, ctx: Context): | ||||||
|         self._logger.debug(__name__, f"Received command level reload {ctx}") |         self._logger.debug(__name__, f"Received command level reload {ctx}") | ||||||
|  |         if ctx.guild is None: | ||||||
|  |             return | ||||||
|  |  | ||||||
|  |         server_config: ServerConfig = self._config.get_configuration(f"ServerConfig_{ctx.guild.id}") | ||||||
|  |         if not FeatureFlagsSettings.get_flag_from_dict(server_config.feature_flags, FeatureFlagsEnum.level_module): | ||||||
|  |             return | ||||||
|  |  | ||||||
|         await self._seed_levels(ctx) |         await self._seed_levels(ctx) | ||||||
|         self._logger.trace(__name__, f"Finished command level reload") |         self._logger.trace(__name__, f"Finished command level reload") | ||||||
|   | |||||||
| @@ -1,18 +1,27 @@ | |||||||
| import discord | import discord | ||||||
|  | from cpl_core.configuration import ConfigurationABC | ||||||
| from cpl_discord.events import OnMemberJoinABC | from cpl_discord.events import OnMemberJoinABC | ||||||
|  |  | ||||||
|  | from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum | ||||||
|  | from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings | ||||||
| from bot_core.helper.event_checks import EventChecks | from bot_core.helper.event_checks import EventChecks | ||||||
| from bot_core.logging.message_logger import MessageLogger | from bot_core.logging.message_logger import MessageLogger | ||||||
|  | from bot_data.model.server_config import ServerConfig | ||||||
| from modules.level.service.level_service import LevelService | from modules.level.service.level_service import LevelService | ||||||
|  |  | ||||||
|  |  | ||||||
| class LevelOnMemberJoinEvent(OnMemberJoinABC): | class LevelOnMemberJoinEvent(OnMemberJoinABC): | ||||||
|     def __init__(self, logger: MessageLogger, level: LevelService): |     def __init__(self, config: ConfigurationABC, logger: MessageLogger, level: LevelService): | ||||||
|         OnMemberJoinABC.__init__(self) |         OnMemberJoinABC.__init__(self) | ||||||
|  |         self._config = config | ||||||
|         self._logger = logger |         self._logger = logger | ||||||
|         self._level = level |         self._level = level | ||||||
|  |  | ||||||
|     @EventChecks.check_is_ready() |     @EventChecks.check_is_ready() | ||||||
|     async def on_member_join(self, member: discord.Member): |     async def on_member_join(self, member: discord.Member): | ||||||
|         self._logger.debug(__name__, f"Module {type(self)} started") |         self._logger.debug(__name__, f"Module {type(self)} started") | ||||||
|  |         server_config: ServerConfig = self._config.get_configuration(f"ServerConfig_{member.guild.id}") | ||||||
|  |         if not FeatureFlagsSettings.get_flag_from_dict(server_config.feature_flags, FeatureFlagsEnum.level_module): | ||||||
|  |             return | ||||||
|  |  | ||||||
|         await self._level.check_level(member) |         await self._level.check_level(member) | ||||||
|   | |||||||
| @@ -1,20 +1,35 @@ | |||||||
| import discord | import discord | ||||||
|  | from cpl_core.configuration import ConfigurationABC | ||||||
| from cpl_discord.events import OnMessageABC | from cpl_discord.events import OnMessageABC | ||||||
|  |  | ||||||
|  | from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum | ||||||
|  | from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings | ||||||
| from bot_core.helper.event_checks import EventChecks | from bot_core.helper.event_checks import EventChecks | ||||||
| from bot_core.logging.message_logger import MessageLogger | from bot_core.logging.message_logger import MessageLogger | ||||||
|  | from bot_data.model.server_config import ServerConfig | ||||||
| from modules.level.service.level_service import LevelService | from modules.level.service.level_service import LevelService | ||||||
|  |  | ||||||
|  |  | ||||||
| class LevelOnMessageEvent(OnMessageABC): | class LevelOnMessageEvent(OnMessageABC): | ||||||
|     def __init__(self, logger: MessageLogger, level: LevelService): |     def __init__(self, config: ConfigurationABC, logger: MessageLogger, level: LevelService): | ||||||
|         OnMessageABC.__init__(self) |         OnMessageABC.__init__(self) | ||||||
|  |         self._config = config | ||||||
|         self._logger = logger |         self._logger = logger | ||||||
|         self._level = level |         self._level = level | ||||||
|  |  | ||||||
|     @EventChecks.check_is_ready() |     @EventChecks.check_is_ready() | ||||||
|     async def on_message(self, message: discord.Message): |     async def on_message(self, message: discord.Message): | ||||||
|         self._logger.debug(__name__, f"Module {type(self)} started") |         self._logger.debug(__name__, f"Module {type(self)} started") | ||||||
|  |         if message.guild is None: | ||||||
|  |             return | ||||||
|  |  | ||||||
|  |         if message.author.bot: | ||||||
|  |             return | ||||||
|  |  | ||||||
|  |         server_config: ServerConfig = self._config.get_configuration(f"ServerConfig_{message.guild.id}") | ||||||
|  |         if not FeatureFlagsSettings.get_flag_from_dict(server_config.feature_flags, FeatureFlagsEnum.level_module): | ||||||
|  |             return | ||||||
|  |  | ||||||
|         try: |         try: | ||||||
|             await self._level.check_level(message.author) |             await self._level.check_level(message.author) | ||||||
|         except Exception as e: |         except Exception as e: | ||||||
|   | |||||||
| @@ -1,21 +1,27 @@ | |||||||
|  | from cpl_core.configuration import ConfigurationABC | ||||||
| from cpl_core.logging import LoggerABC | from cpl_core.logging import LoggerABC | ||||||
| from cpl_discord.events.on_raw_reaction_add_abc import OnRawReactionAddABC | from cpl_discord.events.on_raw_reaction_add_abc import OnRawReactionAddABC | ||||||
| from cpl_discord.service import DiscordBotServiceABC | from cpl_discord.service import DiscordBotServiceABC | ||||||
| from discord import RawReactionActionEvent | from discord import RawReactionActionEvent | ||||||
|  |  | ||||||
|  | from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum | ||||||
|  | from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings | ||||||
| from bot_core.helper.event_checks import EventChecks | from bot_core.helper.event_checks import EventChecks | ||||||
|  | from bot_data.model.server_config import ServerConfig | ||||||
| from modules.level.service.level_service import LevelService | from modules.level.service.level_service import LevelService | ||||||
|  |  | ||||||
|  |  | ||||||
| class LevelOnRawReactionAddEvent(OnRawReactionAddABC): | class LevelOnRawReactionAddEvent(OnRawReactionAddABC): | ||||||
|     def __init__( |     def __init__( | ||||||
|         self, |         self, | ||||||
|  |         config: ConfigurationABC, | ||||||
|         logger: LoggerABC, |         logger: LoggerABC, | ||||||
|         bot: DiscordBotServiceABC, |         bot: DiscordBotServiceABC, | ||||||
|         level: LevelService, |         level: LevelService, | ||||||
|     ): |     ): | ||||||
|         OnRawReactionAddABC.__init__(self) |         OnRawReactionAddABC.__init__(self) | ||||||
|  |  | ||||||
|  |         self._config = config | ||||||
|         self._logger = logger |         self._logger = logger | ||||||
|         self._bot = bot |         self._bot = bot | ||||||
|         self._level = level |         self._level = level | ||||||
| @@ -23,6 +29,10 @@ class LevelOnRawReactionAddEvent(OnRawReactionAddABC): | |||||||
|     @EventChecks.check_is_ready() |     @EventChecks.check_is_ready() | ||||||
|     async def on_raw_reaction_add(self, payload: RawReactionActionEvent): |     async def on_raw_reaction_add(self, payload: RawReactionActionEvent): | ||||||
|         self._logger.debug(__name__, f"Module {type(self)} started") |         self._logger.debug(__name__, f"Module {type(self)} started") | ||||||
|  |         server_config: ServerConfig = self._config.get_configuration(f"ServerConfig_{payload.guild_id}") | ||||||
|  |         if not FeatureFlagsSettings.get_flag_from_dict(server_config.feature_flags, FeatureFlagsEnum.level_module): | ||||||
|  |             return | ||||||
|  |  | ||||||
|         try: |         try: | ||||||
|             self._logger.trace(__name__, f"Handle reaction {payload} for level") |             self._logger.trace(__name__, f"Handle reaction {payload} for level") | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,21 +1,27 @@ | |||||||
|  | from cpl_core.configuration import ConfigurationABC | ||||||
| from cpl_core.logging import LoggerABC | from cpl_core.logging import LoggerABC | ||||||
| from cpl_discord.events.on_raw_reaction_remove_abc import OnRawReactionRemoveABC | from cpl_discord.events.on_raw_reaction_remove_abc import OnRawReactionRemoveABC | ||||||
| from cpl_discord.service import DiscordBotServiceABC | from cpl_discord.service import DiscordBotServiceABC | ||||||
| from discord import RawReactionActionEvent | from discord import RawReactionActionEvent | ||||||
|  |  | ||||||
|  | from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum | ||||||
|  | from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings | ||||||
| from bot_core.helper.event_checks import EventChecks | from bot_core.helper.event_checks import EventChecks | ||||||
|  | from bot_data.model.server_config import ServerConfig | ||||||
| from modules.level.service.level_service import LevelService | from modules.level.service.level_service import LevelService | ||||||
|  |  | ||||||
|  |  | ||||||
| class LevelOnRawReactionRemoveEvent(OnRawReactionRemoveABC): | class LevelOnRawReactionRemoveEvent(OnRawReactionRemoveABC): | ||||||
|     def __init__( |     def __init__( | ||||||
|         self, |         self, | ||||||
|  |         config: ConfigurationABC, | ||||||
|         logger: LoggerABC, |         logger: LoggerABC, | ||||||
|         bot: DiscordBotServiceABC, |         bot: DiscordBotServiceABC, | ||||||
|         level: LevelService, |         level: LevelService, | ||||||
|     ): |     ): | ||||||
|         OnRawReactionRemoveABC.__init__(self) |         OnRawReactionRemoveABC.__init__(self) | ||||||
|  |  | ||||||
|  |         self._config = config | ||||||
|         self._logger = logger |         self._logger = logger | ||||||
|         self._bot = bot |         self._bot = bot | ||||||
|         self._level = level |         self._level = level | ||||||
| @@ -23,6 +29,10 @@ class LevelOnRawReactionRemoveEvent(OnRawReactionRemoveABC): | |||||||
|     @EventChecks.check_is_ready() |     @EventChecks.check_is_ready() | ||||||
|     async def on_raw_reaction_remove(self, payload: RawReactionActionEvent): |     async def on_raw_reaction_remove(self, payload: RawReactionActionEvent): | ||||||
|         self._logger.debug(__name__, f"Module {type(self)} started") |         self._logger.debug(__name__, f"Module {type(self)} started") | ||||||
|  |         server_config: ServerConfig = self._config.get_configuration(f"ServerConfig_{payload.guild_id}") | ||||||
|  |         if not FeatureFlagsSettings.get_flag_from_dict(server_config.feature_flags, FeatureFlagsEnum.level_module): | ||||||
|  |             return | ||||||
|  |  | ||||||
|         try: |         try: | ||||||
|             self._logger.trace(__name__, f"Handle reaction {payload} for level") |             self._logger.trace(__name__, f"Handle reaction {payload} for level") | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,14 +1,19 @@ | |||||||
| import discord | import discord | ||||||
|  | from cpl_core.configuration import ConfigurationABC | ||||||
| from cpl_core.logging import LoggerABC | from cpl_core.logging import LoggerABC | ||||||
| from cpl_discord.events import OnVoiceStateUpdateABC | from cpl_discord.events import OnVoiceStateUpdateABC | ||||||
|  |  | ||||||
|  | from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum | ||||||
|  | from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings | ||||||
| from bot_core.helper.event_checks import EventChecks | from bot_core.helper.event_checks import EventChecks | ||||||
|  | from bot_data.model.server_config import ServerConfig | ||||||
| from modules.level.service.level_service import LevelService | from modules.level.service.level_service import LevelService | ||||||
|  |  | ||||||
|  |  | ||||||
| class LevelOnVoiceStateUpdateEvent(OnVoiceStateUpdateABC): | class LevelOnVoiceStateUpdateEvent(OnVoiceStateUpdateABC): | ||||||
|     def __init__(self, logger: LoggerABC, level: LevelService): |     def __init__(self, config: ConfigurationABC, logger: LoggerABC, level: LevelService): | ||||||
|         OnVoiceStateUpdateABC.__init__(self) |         OnVoiceStateUpdateABC.__init__(self) | ||||||
|  |         self._config = config | ||||||
|         self._logger = logger |         self._logger = logger | ||||||
|         self._level = level |         self._level = level | ||||||
|  |  | ||||||
| @@ -22,4 +27,8 @@ class LevelOnVoiceStateUpdateEvent(OnVoiceStateUpdateABC): | |||||||
|         after: discord.VoiceState, |         after: discord.VoiceState, | ||||||
|     ): |     ): | ||||||
|         self._logger.debug(__name__, f"Module {type(self)} started") |         self._logger.debug(__name__, f"Module {type(self)} started") | ||||||
|  |         server_config: ServerConfig = self._config.get_configuration(f"ServerConfig_{member.guild.id}") | ||||||
|  |         if not FeatureFlagsSettings.get_flag_from_dict(server_config.feature_flags, FeatureFlagsEnum.level_module): | ||||||
|  |             return | ||||||
|  |  | ||||||
|         await self._level.check_level(member) |         await self._level.check_level(member) | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
|     "name": "kdb-web", |     "name": "kdb-web", | ||||||
|     "version": "1.1.dev79_hide_table_columns", |     "version": "1.1.dev334_feature_flags_in_wi", | ||||||
|     "scripts": { |     "scripts": { | ||||||
|         "ng": "ng", |         "ng": "ng", | ||||||
|         "update-version": "ts-node-esm update-version.ts", |         "update-version": "ts-node-esm update-version.ts", | ||||||
|   | |||||||
| @@ -26,7 +26,12 @@ export class ComponentWithTable { | |||||||
|     this.columns = columns.map(column => { |     this.columns = columns.map(column => { | ||||||
|       return { key: this.getKey(column), name: column }; |       return { key: this.getKey(column), name: column }; | ||||||
|     }); |     }); | ||||||
|     this._hiddenColumns = JSON.parse(localStorage.getItem("hiddenColumns") ?? ""); |     let hiddenColumns = localStorage.getItem("hiddenColumns"); | ||||||
|  |     if (!hiddenColumns) { | ||||||
|  |       localStorage.setItem("hiddenColumns", JSON.stringify([{}])); | ||||||
|  |       hiddenColumns = localStorage.getItem("hiddenColumns") ?? JSON.stringify([{}]); | ||||||
|  |     } | ||||||
|  |     this._hiddenColumns = JSON.parse(hiddenColumns); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private getKey(column: string): string { |   private getKey(column: string): string { | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								kdb-web/src/app/models/config/feature-flags.model.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								kdb-web/src/app/models/config/feature-flags.model.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | |||||||
|  | export interface FeatureFlag { | ||||||
|  |   key: string; | ||||||
|  |   value: boolean; | ||||||
|  | } | ||||||
| @@ -1,4 +1,5 @@ | |||||||
| import { DataWithHistory } from "../data/data.model"; | import { DataWithHistory } from "../data/data.model"; | ||||||
|  | import { FeatureFlag } from "./feature-flags.model"; | ||||||
|  |  | ||||||
| export interface ServerConfig extends DataWithHistory { | export interface ServerConfig extends DataWithHistory { | ||||||
|   id?: number; |   id?: number; | ||||||
| @@ -15,6 +16,7 @@ export interface ServerConfig extends DataWithHistory { | |||||||
|   helpVoiceChannelId?: string; |   helpVoiceChannelId?: string; | ||||||
|   teamChannelId?: string; |   teamChannelId?: string; | ||||||
|   loginMessageChannelId?: string; |   loginMessageChannelId?: string; | ||||||
|  |   featureFlags: FeatureFlag[]; | ||||||
|   afkChannelIds: string[]; |   afkChannelIds: string[]; | ||||||
|   moderatorRoleIds: string[]; |   moderatorRoleIds: string[]; | ||||||
|   adminRoleIds: string[]; |   adminRoleIds: string[]; | ||||||
|   | |||||||
| @@ -1,4 +1,5 @@ | |||||||
| import { DataWithHistory } from "../data/data.model"; | import { DataWithHistory } from "../data/data.model"; | ||||||
|  | import { FeatureFlag } from "./feature-flags.model"; | ||||||
|  |  | ||||||
| export interface TechnicianConfig extends DataWithHistory { | export interface TechnicianConfig extends DataWithHistory { | ||||||
|   id?: number; |   id?: number; | ||||||
| @@ -6,6 +7,7 @@ export interface TechnicianConfig extends DataWithHistory { | |||||||
|   waitForRestart?: number; |   waitForRestart?: number; | ||||||
|   waitForShutdown?: number; |   waitForShutdown?: number; | ||||||
|   cacheMaxMessages?: number; |   cacheMaxMessages?: number; | ||||||
|  |   featureFlags: FeatureFlag[]; | ||||||
|   pingURLs: string[]; |   pingURLs: string[]; | ||||||
|   technicianIds: string[]; |   technicianIds: string[]; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -167,7 +167,7 @@ export class Mutations { | |||||||
|   `; |   `; | ||||||
|  |  | ||||||
|   static updateTechnicianConfig = ` |   static updateTechnicianConfig = ` | ||||||
|     mutation updateTechnicianConfig($id: ID, $helpCommandReferenceUrl: String, $waitForRestart: Int, $waitForShutdown: Int, $cacheMaxMessages: Int, $pingURLs: [String], $technicianIds: [String]) { |     mutation updateTechnicianConfig($id: ID, $helpCommandReferenceUrl: String, $waitForRestart: Int, $waitForShutdown: Int, $cacheMaxMessages: Int, $featureFlags: [FeatureFlagInput], $pingURLs: [String], $technicianIds: [String]) { | ||||||
|       technicianConfig { |       technicianConfig { | ||||||
|         updateTechnicianConfig(input: { |         updateTechnicianConfig(input: { | ||||||
|             id: $id, |             id: $id, | ||||||
| @@ -175,6 +175,7 @@ export class Mutations { | |||||||
|             waitForRestart: $waitForRestart, |             waitForRestart: $waitForRestart, | ||||||
|             waitForShutdown: $waitForShutdown, |             waitForShutdown: $waitForShutdown, | ||||||
|             cacheMaxMessages: $cacheMaxMessages, |             cacheMaxMessages: $cacheMaxMessages, | ||||||
|  |             featureFlags: $featureFlags, | ||||||
|             pingURLs: $pingURLs, |             pingURLs: $pingURLs, | ||||||
|             technicianIds: $technicianIds |             technicianIds: $technicianIds | ||||||
|           }) { |           }) { | ||||||
| @@ -183,6 +184,10 @@ export class Mutations { | |||||||
|           waitForRestart |           waitForRestart | ||||||
|           waitForShutdown |           waitForShutdown | ||||||
|           cacheMaxMessages |           cacheMaxMessages | ||||||
|  |           featureFlags { | ||||||
|  |             key | ||||||
|  |             value | ||||||
|  |           } | ||||||
|           pingURLs |           pingURLs | ||||||
|           technicianIds |           technicianIds | ||||||
|         } |         } | ||||||
| @@ -206,6 +211,7 @@ export class Mutations { | |||||||
|       $helpVoiceChannelId: String, |       $helpVoiceChannelId: String, | ||||||
|       $teamChannelId: String, |       $teamChannelId: String, | ||||||
|       $loginMessageChannelId: String, |       $loginMessageChannelId: String, | ||||||
|  |       $featureFlags: [FeatureFlagInput], | ||||||
|       $afkChannelIds: [String], |       $afkChannelIds: [String], | ||||||
|       $moderatorRoleIds: [String], |       $moderatorRoleIds: [String], | ||||||
|       $adminRoleIds: [String] |       $adminRoleIds: [String] | ||||||
| @@ -213,21 +219,22 @@ export class Mutations { | |||||||
|       serverConfig { |       serverConfig { | ||||||
|         updateServerConfig(input: { |         updateServerConfig(input: { | ||||||
|             id: $id, |             id: $id, | ||||||
|             messageDeleteTimer: $messageDeleteTimer |             messageDeleteTimer: $messageDeleteTimer, | ||||||
|             notificationChatId: $notificationChatId |             notificationChatId: $notificationChatId, | ||||||
|             maxVoiceStateHours: $maxVoiceStateHours |             maxVoiceStateHours: $maxVoiceStateHours, | ||||||
|             xpPerMessage: $xpPerMessage |             xpPerMessage: $xpPerMessage, | ||||||
|             xpPerReaction: $xpPerReaction |             xpPerReaction: $xpPerReaction, | ||||||
|             maxMessageXpPerHour: $maxMessageXpPerHour |             maxMessageXpPerHour: $maxMessageXpPerHour, | ||||||
|             xpPerOntimeHour: $xpPerOntimeHour |             xpPerOntimeHour: $xpPerOntimeHour, | ||||||
|             xpPerEventParticipation: $xpPerEventParticipation |             xpPerEventParticipation: $xpPerEventParticipation, | ||||||
|             xpPerAchievement: $xpPerAchievement |             xpPerAchievement: $xpPerAchievement, | ||||||
|             afkCommandChannelId: $afkCommandChannelId |             afkCommandChannelId: $afkCommandChannelId, | ||||||
|             helpVoiceChannelId: $helpVoiceChannelId |             helpVoiceChannelId: $helpVoiceChannelId, | ||||||
|             teamChannelId: $teamChannelId |             teamChannelId: $teamChannelId, | ||||||
|             loginMessageChannelId: $loginMessageChannelId |             loginMessageChannelId: $loginMessageChannelId, | ||||||
|             afkChannelIds: $afkChannelIds |             featureFlags: $featureFlags, | ||||||
|             moderatorRoleIds: $moderatorRoleIds |             afkChannelIds: $afkChannelIds, | ||||||
|  |             moderatorRoleIds: $moderatorRoleIds, | ||||||
|             adminRoleIds: $adminRoleIds |             adminRoleIds: $adminRoleIds | ||||||
|           }) { |           }) { | ||||||
|           id |           id | ||||||
| @@ -244,6 +251,10 @@ export class Mutations { | |||||||
|           helpVoiceChannelId |           helpVoiceChannelId | ||||||
|           teamChannelId |           teamChannelId | ||||||
|           loginMessageChannelId |           loginMessageChannelId | ||||||
|  |           featureFlags { | ||||||
|  |             key | ||||||
|  |             value | ||||||
|  |           } | ||||||
|           afkChannelIds |           afkChannelIds | ||||||
|           moderatorRoleIds |           moderatorRoleIds | ||||||
|           adminRoleIds |           adminRoleIds | ||||||
|   | |||||||
| @@ -353,6 +353,10 @@ export class Queries { | |||||||
|         waitForRestart |         waitForRestart | ||||||
|         waitForShutdown |         waitForShutdown | ||||||
|         cacheMaxMessages |         cacheMaxMessages | ||||||
|  |         featureFlags { | ||||||
|  |           key | ||||||
|  |           value | ||||||
|  |         } | ||||||
|         pingURLs |         pingURLs | ||||||
|         technicianIds |         technicianIds | ||||||
|  |  | ||||||
| @@ -381,6 +385,10 @@ export class Queries { | |||||||
|           helpVoiceChannelId |           helpVoiceChannelId | ||||||
|           teamChannelId |           teamChannelId | ||||||
|           loginMessageChannelId |           loginMessageChannelId | ||||||
|  |           featureFlags { | ||||||
|  |             key | ||||||
|  |             value | ||||||
|  |           } | ||||||
|           afkChannelIds |           afkChannelIds | ||||||
|           moderatorRoleIds |           moderatorRoleIds | ||||||
|           adminRoleIds |           adminRoleIds | ||||||
|   | |||||||
| @@ -59,3 +59,8 @@ export interface AutoRoleRuleQuery { | |||||||
|   autoRoleRules: AutoRoleRule[]; |   autoRoleRules: AutoRoleRule[]; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | export interface PossibleFeatureFlagsQuery { | ||||||
|  |   possibleFeatureFlags: string[]; | ||||||
|  | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -163,6 +163,7 @@ | |||||||
|     <div class="content-divider"></div> |     <div class="content-divider"></div> | ||||||
|     <app-config-list translationKey="admin.settings.bot.ping_urls" [(data)]="config.pingURLs"></app-config-list> |     <app-config-list translationKey="admin.settings.bot.ping_urls" [(data)]="config.pingURLs"></app-config-list> | ||||||
|     <app-config-list translationKey="admin.settings.bot.technician_ids" [(data)]="config.technicianIds"></app-config-list> |     <app-config-list translationKey="admin.settings.bot.technician_ids" [(data)]="config.technicianIds"></app-config-list> | ||||||
|  |     <app-feature-flag-list [(data)]="config.featureFlags"></app-feature-flag-list> | ||||||
|  |  | ||||||
|     <div class="content-row"> |     <div class="content-row"> | ||||||
|       <button pButton icon="pi pi-save" label="{{'common.save' | translate}}" class="btn login-form-submit-btn" |       <button pButton icon="pi pi-save" label="{{'common.save' | translate}}" class="btn login-form-submit-btn" | ||||||
|   | |||||||
| @@ -49,6 +49,7 @@ export class SettingsComponent implements OnInit { | |||||||
|     waitForRestart: 0, |     waitForRestart: 0, | ||||||
|     waitForShutdown: 0, |     waitForShutdown: 0, | ||||||
|     cacheMaxMessages: 0, |     cacheMaxMessages: 0, | ||||||
|  |     featureFlags: [], | ||||||
|     pingURLs: [], |     pingURLs: [], | ||||||
|     technicianIds: [] |     technicianIds: [] | ||||||
|   }; |   }; | ||||||
| @@ -150,6 +151,7 @@ export class SettingsComponent implements OnInit { | |||||||
|         waitForRestart: this.config.waitForRestart, |         waitForRestart: this.config.waitForRestart, | ||||||
|         waitForShutdown: this.config.waitForShutdown, |         waitForShutdown: this.config.waitForShutdown, | ||||||
|         cacheMaxMessages: this.config.cacheMaxMessages, |         cacheMaxMessages: this.config.cacheMaxMessages, | ||||||
|  |         featureFlags: this.config.featureFlags, | ||||||
|         pingURLs: this.config.pingURLs, |         pingURLs: this.config.pingURLs, | ||||||
|         technicianIds: this.config.technicianIds |         technicianIds: this.config.technicianIds | ||||||
|       } |       } | ||||||
|   | |||||||
| @@ -2,9 +2,10 @@ | |||||||
|   <p-multiSelect display="chip" [options]="columns" [(ngModel)]="hiddenColumns" optionLabel="name" placeholder="{{'common.hidden_columns' | translate}}" [filter]=false> |   <p-multiSelect display="chip" [options]="columns" [(ngModel)]="hiddenColumns" optionLabel="name" placeholder="{{'common.hidden_columns' | translate}}" [filter]=false> | ||||||
|     <ng-template let-value pTemplate="selectedItems"> |     <ng-template let-value pTemplate="selectedItems"> | ||||||
|       <div *ngFor="let item of hiddenColumns; let i = index;"> |       <div *ngFor="let item of hiddenColumns; let i = index;"> | ||||||
|         <div> |         <div *ngIf="item.name"> | ||||||
|           {{'common.' + item.name | translate}}<span *ngIf="i < columns.length-1">,</span> |           {{'common.' + item.name | translate}}<span *ngIf="i < columns.length-1">,</span> | ||||||
|         </div> |         </div> | ||||||
|  |         <div *ngIf="!item.name">{{'common.hidden_columns' | translate}}</div> | ||||||
|       </div> |       </div> | ||||||
|       <div *ngIf="!hiddenColumns || hiddenColumns.length === 0">{{'common.hidden_columns' | translate}}</div> |       <div *ngIf="!hiddenColumns || hiddenColumns.length === 0">{{'common.hidden_columns' | translate}}</div> | ||||||
|     </ng-template> |     </ng-template> | ||||||
|   | |||||||
| @@ -15,8 +15,8 @@ | |||||||
|           </div> |           </div> | ||||||
|         </ng-template> |         </ng-template> | ||||||
|         <ng-template pTemplate="body" let-value let-editing="editing" let-ri="rowIndex"> |         <ng-template pTemplate="body" let-value let-editing="editing" let-ri="rowIndex"> | ||||||
|           <tr [pEditableRow]="value"> |           <tr [pEditableRow]="value" style="display: flex;"> | ||||||
|             <td> |             <td style="flex: 1;"> | ||||||
|               <p-cellEditor> |               <p-cellEditor> | ||||||
|                 <ng-template pTemplate="input"> |                 <ng-template pTemplate="input"> | ||||||
|                   <input class="table-edit-input" pInputText type="text" [(ngModel)]="value.value"> |                   <input class="table-edit-input" pInputText type="text" [(ngModel)]="value.value"> | ||||||
|   | |||||||
| @@ -0,0 +1,55 @@ | |||||||
|  | <div class="content-row"> | ||||||
|  |   <div class="content-column"> | ||||||
|  |     <div class="content-data-name"> | ||||||
|  |       {{'common.feature_flags' | translate}}: | ||||||
|  |     </div> | ||||||
|  |     <div class="content-data-value-row"> | ||||||
|  |       <p-table #dt [value]="internal_data" dataKey="id" editMode="row"> | ||||||
|  |         <ng-template pTemplate="caption"> | ||||||
|  |           <div class="table-caption"> | ||||||
|  |             <div class="table-caption-btn-wrapper btn-wrapper"> | ||||||
|  |               <button pButton class="icon-btn btn" | ||||||
|  |                       icon="pi pi-plus" (click)="addNew(dt)"> | ||||||
|  |               </button> | ||||||
|  |             </div> | ||||||
|  |           </div> | ||||||
|  |         </ng-template> | ||||||
|  |         <ng-template pTemplate="body" let-value let-editing="editing" let-ri="rowIndex"> | ||||||
|  |           <tr [pEditableRow]="value" style="display: flex;"> | ||||||
|  |             <td style="flex: 3;"> | ||||||
|  |               <p-cellEditor> | ||||||
|  |                 <ng-template pTemplate="input"> | ||||||
|  |                   <p-dropdown class="table-edit-input" [options]="featureFlags" [(ngModel)]="value.value.key"></p-dropdown> | ||||||
|  |                 </ng-template> | ||||||
|  |                 <ng-template pTemplate="output"> | ||||||
|  |                   {{value.value.key}} | ||||||
|  |                 </ng-template> | ||||||
|  |               </p-cellEditor> | ||||||
|  |             </td> | ||||||
|  |             <td style="flex: 1;"> | ||||||
|  |               <p-cellEditor> | ||||||
|  |                 <ng-template pTemplate="input"> | ||||||
|  |                   <p-inputSwitch class="table-edit-input" [(ngModel)]="value.value.value"></p-inputSwitch> | ||||||
|  |                 </ng-template> | ||||||
|  |                 <ng-template pTemplate="output"> | ||||||
|  |                   <p-inputSwitch class="table-edit-input" [(ngModel)]="value.value.value" [disabled]="true"></p-inputSwitch> | ||||||
|  |                 </ng-template> | ||||||
|  |               </p-cellEditor> | ||||||
|  |             </td> | ||||||
|  |             <td> | ||||||
|  |               <div class="btn-wrapper"> | ||||||
|  |                 <button *ngIf="!editing" pButton type="button" pInitEditableRow class="btn icon-btn" icon="pi pi-pencil" (click)="editInit(value, ri)"></button> | ||||||
|  |                 <button *ngIf="!editing" pButton type="button" class="btn danger-icon-btn" icon="pi pi-trash" (click)="delete(ri)"></button> | ||||||
|  |  | ||||||
|  |                 <button *ngIf="editing" pButton type="button" pSaveEditableRow class="btn icon-btn" icon="pi pi-check" (click)="editSave(value, ri)"></button> | ||||||
|  |                 <button *ngIf="editing" pButton type="button" pCancelEditableRow class="btn danger-icon-btn" icon="pi pi-times" | ||||||
|  |                         (click)="editCancel(ri)"></button> | ||||||
|  |               </div> | ||||||
|  |             </td> | ||||||
|  |           </tr> | ||||||
|  |         </ng-template> | ||||||
|  |       </p-table> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  | </div> | ||||||
|  | <div class="content-divider"></div> | ||||||
| @@ -0,0 +1,23 @@ | |||||||
|  | import { ComponentFixture, TestBed } from '@angular/core/testing'; | ||||||
|  |  | ||||||
|  | import { FeatureFlagListComponent } from './feature-flag-list.component'; | ||||||
|  |  | ||||||
|  | describe('FeatureFlagListComponent', () => { | ||||||
|  |   let component: FeatureFlagListComponent; | ||||||
|  |   let fixture: ComponentFixture<FeatureFlagListComponent>; | ||||||
|  |  | ||||||
|  |   beforeEach(async () => { | ||||||
|  |     await TestBed.configureTestingModule({ | ||||||
|  |       declarations: [ FeatureFlagListComponent ] | ||||||
|  |     }) | ||||||
|  |     .compileComponents(); | ||||||
|  |  | ||||||
|  |     fixture = TestBed.createComponent(FeatureFlagListComponent); | ||||||
|  |     component = fixture.componentInstance; | ||||||
|  |     fixture.detectChanges(); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   it('should create', () => { | ||||||
|  |     expect(component).toBeTruthy(); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
| @@ -0,0 +1,40 @@ | |||||||
|  | import { Component, OnInit } from "@angular/core"; | ||||||
|  | import { ConfigListComponent } from "../config-list/config-list.component"; | ||||||
|  | import { Table } from "primeng/table"; | ||||||
|  | import { PossibleFeatureFlagsQuery } from "../../../../models/graphql/query.model"; | ||||||
|  | import { DataService } from "../../../../services/data/data.service"; | ||||||
|  |  | ||||||
|  | @Component({ | ||||||
|  |   selector: "app-feature-flag-list", | ||||||
|  |   templateUrl: "./feature-flag-list.component.html", | ||||||
|  |   styleUrls: ["./feature-flag-list.component.scss"] | ||||||
|  | }) | ||||||
|  | export class FeatureFlagListComponent extends ConfigListComponent implements OnInit { | ||||||
|  |   featureFlags: string[] = []; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   constructor( | ||||||
|  |     private dataService: DataService | ||||||
|  |   ) { | ||||||
|  |     super(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   ngOnInit() { | ||||||
|  |     this.dataService.query<PossibleFeatureFlagsQuery>("{possibleFeatureFlags}" | ||||||
|  |     ).subscribe(data => { | ||||||
|  |       this.featureFlags = data.possibleFeatureFlags; | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   override addNew(table: Table) { | ||||||
|  |     const id = Math.max.apply(Math, this.internal_data.map(value => { | ||||||
|  |       return value.id ?? 0; | ||||||
|  |     })) + 1; | ||||||
|  |     const newItem = { id: id, value: { key: "", value: false } }; | ||||||
|  |     this.internal_data.push(newItem); | ||||||
|  |  | ||||||
|  |     table.initRowEdit(newItem); | ||||||
|  |     const index = this.internal_data.findIndex(l => l.id == newItem.id); | ||||||
|  |     this.editInit(newItem, index); | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -28,8 +28,11 @@ export class AuthGuard implements CanActivate { | |||||||
|  |  | ||||||
|     const role = route.data['role']; |     const role = route.data['role']; | ||||||
|     if (role) { |     if (role) { | ||||||
|       this.authService.hasUserPermission(role).then(hasPermission => { |       this.authService.hasUserPermission(role).then(async hasPermission => { | ||||||
|         if (!hasPermission) { |         let authUser = await this.authService.getLoggedInUser(); | ||||||
|  |         let isTechnician = authUser?.users?.map(u => u.isTechnician).filter(u => u) ?? []; | ||||||
|  |  | ||||||
|  |         if (!hasPermission && !isTechnician) { | ||||||
|           this.router.navigate(['/dashboard']); |           this.router.navigate(['/dashboard']); | ||||||
|           return false; |           return false; | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -30,6 +30,8 @@ import { MultiSelectModule } from "primeng/multiselect"; | |||||||
| import { HideableColumnComponent } from './components/hideable-column/hideable-column.component'; | import { HideableColumnComponent } from './components/hideable-column/hideable-column.component'; | ||||||
| import { HideableHeaderComponent } from './components/hideable-header/hideable-header.component'; | import { HideableHeaderComponent } from './components/hideable-header/hideable-header.component'; | ||||||
| import { MultiSelectColumnsComponent } from './base/multi-select-columns/multi-select-columns.component'; | import { MultiSelectColumnsComponent } from './base/multi-select-columns/multi-select-columns.component'; | ||||||
|  | import { FeatureFlagListComponent } from './components/feature-flag-list/feature-flag-list.component'; | ||||||
|  | import { InputSwitchModule } from "primeng/inputswitch"; | ||||||
|  |  | ||||||
|  |  | ||||||
| @NgModule({ | @NgModule({ | ||||||
| @@ -42,6 +44,7 @@ import { MultiSelectColumnsComponent } from './base/multi-select-columns/multi-s | |||||||
|     HideableColumnComponent, |     HideableColumnComponent, | ||||||
|     HideableHeaderComponent, |     HideableHeaderComponent, | ||||||
|     MultiSelectColumnsComponent, |     MultiSelectColumnsComponent, | ||||||
|  |     FeatureFlagListComponent, | ||||||
|   ], |   ], | ||||||
|   imports: [ |   imports: [ | ||||||
|     CommonModule, |     CommonModule, | ||||||
| @@ -68,6 +71,7 @@ import { MultiSelectColumnsComponent } from './base/multi-select-columns/multi-s | |||||||
|     SidebarModule, |     SidebarModule, | ||||||
|     DataViewModule, |     DataViewModule, | ||||||
|     MultiSelectModule, |     MultiSelectModule, | ||||||
|  |     InputSwitchModule, | ||||||
|   ], |   ], | ||||||
|   exports: [ |   exports: [ | ||||||
|     ButtonModule, |     ButtonModule, | ||||||
| @@ -102,6 +106,8 @@ import { MultiSelectColumnsComponent } from './base/multi-select-columns/multi-s | |||||||
|     HideableColumnComponent, |     HideableColumnComponent, | ||||||
|     HideableHeaderComponent, |     HideableHeaderComponent, | ||||||
|     MultiSelectColumnsComponent, |     MultiSelectColumnsComponent, | ||||||
|  |     FeatureFlagListComponent, | ||||||
|  |     InputSwitchModule, | ||||||
|   ] |   ] | ||||||
| }) | }) | ||||||
| export class SharedModule { | export class SharedModule { | ||||||
|   | |||||||
| @@ -113,6 +113,7 @@ | |||||||
|     <app-config-list translationKey="view.server.config.bot.afk_channels" [(data)]="config.afkChannelIds"></app-config-list> |     <app-config-list translationKey="view.server.config.bot.afk_channels" [(data)]="config.afkChannelIds"></app-config-list> | ||||||
|     <app-config-list translationKey="view.server.config.bot.moderator_roles" [(data)]="config.moderatorRoleIds"></app-config-list> |     <app-config-list translationKey="view.server.config.bot.moderator_roles" [(data)]="config.moderatorRoleIds"></app-config-list> | ||||||
|     <app-config-list translationKey="view.server.config.bot.admin_roles" [(data)]="config.adminRoleIds"></app-config-list> |     <app-config-list translationKey="view.server.config.bot.admin_roles" [(data)]="config.adminRoleIds"></app-config-list> | ||||||
|  |     <app-feature-flag-list *ngIf="isTechnician" [(data)]="config.featureFlags"></app-feature-flag-list> | ||||||
|  |  | ||||||
|     <div class="content-row"> |     <div class="content-row"> | ||||||
|       <button pButton icon="pi pi-save" label="{{'common.save' | translate}}" class="btn login-form-submit-btn" |       <button pButton icon="pi pi-save" label="{{'common.save' | translate}}" class="btn login-form-submit-btn" | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ import { AuthService } from "../../../../../../services/auth/auth.service"; | |||||||
| import { ServerConfig } from "../../../../../../models/config/server-config.model"; | import { ServerConfig } from "../../../../../../models/config/server-config.model"; | ||||||
| import { Server } from "../../../../../../models/data/server.model"; | import { Server } from "../../../../../../models/data/server.model"; | ||||||
| import { ActivatedRoute } from "@angular/router"; | import { ActivatedRoute } from "@angular/router"; | ||||||
| import { Table } from "primeng/table"; | import { UserDTO } from "../../../../../../models/auth/auth-user.dto"; | ||||||
|  |  | ||||||
| type AFKChannelId = { | type AFKChannelId = { | ||||||
|   id: number; |   id: number; | ||||||
| @@ -31,6 +31,7 @@ type AFKChannelId = { | |||||||
| export class ConfigComponent implements OnInit { | export class ConfigComponent implements OnInit { | ||||||
|   config: ServerConfig = { |   config: ServerConfig = { | ||||||
|     messageDeleteTimer: 0, |     messageDeleteTimer: 0, | ||||||
|  |     featureFlags: [], | ||||||
|     afkChannelIds: [], |     afkChannelIds: [], | ||||||
|     moderatorRoleIds: [], |     moderatorRoleIds: [], | ||||||
|     adminRoleIds: [] |     adminRoleIds: [] | ||||||
| @@ -41,6 +42,7 @@ export class ConfigComponent implements OnInit { | |||||||
|   clonedAfkChannelIds: { [s: number]: AFKChannelId } = {}; |   clonedAfkChannelIds: { [s: number]: AFKChannelId } = {}; | ||||||
|  |  | ||||||
|   private server: Server = {}; |   private server: Server = {}; | ||||||
|  |   isTechnician: boolean = false; | ||||||
|  |  | ||||||
|   constructor( |   constructor( | ||||||
|     private data: DataService, |     private data: DataService, | ||||||
| @@ -62,6 +64,9 @@ export class ConfigComponent implements OnInit { | |||||||
|     this.data.getServerFromRoute(this.route).then(async server => { |     this.data.getServerFromRoute(this.route).then(async server => { | ||||||
|       this.server = server; |       this.server = server; | ||||||
|       this.loadConfig(); |       this.loadConfig(); | ||||||
|  |       let authUser = await this.authService.getLoggedInUser(); | ||||||
|  |       let isUserTechnicianList = authUser?.users?.map(u => u.isTechnician).filter(u => u) ?? []; | ||||||
|  |       this.isTechnician = isUserTechnicianList.length > 0; | ||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -101,6 +106,7 @@ export class ConfigComponent implements OnInit { | |||||||
|         helpVoiceChannelId: this.config.helpVoiceChannelId, |         helpVoiceChannelId: this.config.helpVoiceChannelId, | ||||||
|         teamChannelId: this.config.teamChannelId, |         teamChannelId: this.config.teamChannelId, | ||||||
|         loginMessageChannelId: this.config.loginMessageChannelId, |         loginMessageChannelId: this.config.loginMessageChannelId, | ||||||
|  |         featureFlags: this.config.featureFlags, | ||||||
|         afkChannelIds: this.config.afkChannelIds, |         afkChannelIds: this.config.afkChannelIds, | ||||||
|         moderatorRoleIds: this.config.moderatorRoleIds, |         moderatorRoleIds: this.config.moderatorRoleIds, | ||||||
|         adminRoleIds: this.config.adminRoleIds |         adminRoleIds: this.config.adminRoleIds | ||||||
| @@ -110,7 +116,7 @@ export class ConfigComponent implements OnInit { | |||||||
|       return throwError(err); |       return throwError(err); | ||||||
|     })).subscribe(result => { |     })).subscribe(result => { | ||||||
|       this.spinner.hideSpinner(); |       this.spinner.hideSpinner(); | ||||||
|       this.toastService.success(this.translate.instant("view.server.config.message.server#_config_create"), this.translate.instant("view.server.config.message.server_config_create_d")); |       this.toastService.success(this.translate.instant("view.server.config.message.server_config_create"), this.translate.instant("view.server.config.message.server_config_create_d")); | ||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -67,7 +67,7 @@ export class SidebarService { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async buildMenu(user: UserDTO | null, hasPermission: boolean) { |   async buildMenu(user: UserDTO | null, hasPermission: boolean, isTechnician: boolean = false) { | ||||||
|     this.dashboard = { |     this.dashboard = { | ||||||
|       label: this.isSidebarOpen ? this.translateService.instant("sidebar.dashboard") : "", |       label: this.isSidebarOpen ? this.translateService.instant("sidebar.dashboard") : "", | ||||||
|       icon: "pi pi-th-large", |       icon: "pi pi-th-large", | ||||||
| @@ -127,18 +127,20 @@ export class SidebarService { | |||||||
|     }; |     }; | ||||||
|     this.adminConfig = { |     this.adminConfig = { | ||||||
|       label: this.isSidebarOpen ? this.translateService.instant("sidebar.config") : "", |       label: this.isSidebarOpen ? this.translateService.instant("sidebar.config") : "", | ||||||
|  |       visible: hasPermission || isTechnician, | ||||||
|       icon: "pi pi-cog", |       icon: "pi pi-cog", | ||||||
|       routerLink: "/admin/settings" |       routerLink: "/admin/settings" | ||||||
|     }; |     }; | ||||||
|     this.adminUsers = { |     this.adminUsers = { | ||||||
|       label: this.isSidebarOpen ? this.translateService.instant("sidebar.auth_user_list") : "", |       label: this.isSidebarOpen ? this.translateService.instant("sidebar.auth_user_list") : "", | ||||||
|  |       visible: hasPermission, | ||||||
|       icon: "pi pi-user-edit", |       icon: "pi pi-user-edit", | ||||||
|       routerLink: "/admin/users" |       routerLink: "/admin/users" | ||||||
|     }; |     }; | ||||||
|     this.adminMenu = { |     this.adminMenu = { | ||||||
|       label: this.isSidebarOpen ? this.translateService.instant("sidebar.administration") : "", |       label: this.isSidebarOpen ? this.translateService.instant("sidebar.administration") : "", | ||||||
|       icon: "pi pi-cog", |       icon: "pi pi-cog", | ||||||
|       visible: hasPermission, |       visible: hasPermission || isTechnician, | ||||||
|       expanded: true, |       expanded: true, | ||||||
|       items: [this.adminConfig, this.adminUsers] |       items: [this.adminConfig, this.adminUsers] | ||||||
|     }; |     }; | ||||||
| @@ -148,9 +150,10 @@ export class SidebarService { | |||||||
|     this.authService.hasUserPermission(AuthRoles.Admin).then(async hasPermission => { |     this.authService.hasUserPermission(AuthRoles.Admin).then(async hasPermission => { | ||||||
|       let authUser = await this.authService.getLoggedInUser(); |       let authUser = await this.authService.getLoggedInUser(); | ||||||
|       let user: UserDTO | null = authUser?.users?.find(u => u.server == this.server$.value?.id) ?? null; |       let user: UserDTO | null = authUser?.users?.find(u => u.server == this.server$.value?.id) ?? null; | ||||||
|  |       let isTechnician = authUser?.users?.map(u => u.isTechnician).filter(u => u) ?? []; | ||||||
|  |  | ||||||
|       if (build || this.menuItems$.value.length == 0) { |       if (build || this.menuItems$.value.length == 0) { | ||||||
|         await this.buildMenu(user, hasPermission); |         await this.buildMenu(user, hasPermission, isTechnician.length > 0); | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       if (this.server$.value) { |       if (this.server$.value) { | ||||||
| @@ -159,7 +162,7 @@ export class SidebarService { | |||||||
|         this.serverAutoRoles.visible = !!user?.isModerator; |         this.serverAutoRoles.visible = !!user?.isModerator; | ||||||
|         this.serverLevels.visible = !!user?.isModerator; |         this.serverLevels.visible = !!user?.isModerator; | ||||||
|         this.serverAchievements.visible = !!user?.isModerator; |         this.serverAchievements.visible = !!user?.isModerator; | ||||||
|         this.serverConfig.visible = !!user?.isAdmin; |         this.serverConfig.visible = !!user?.isAdmin || isTechnician.length > 0; | ||||||
|       } else { |       } else { | ||||||
|         this.serverMenu.visible = false; |         this.serverMenu.visible = false; | ||||||
|       } |       } | ||||||
|   | |||||||
| @@ -122,6 +122,7 @@ | |||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   "common": { |   "common": { | ||||||
|  |     "feature_flags": "Funktionen", | ||||||
|     "404": "404 - Der Eintrag konnte nicht gefunden werden", |     "404": "404 - Der Eintrag konnte nicht gefunden werden", | ||||||
|     "actions": "Aktionen", |     "actions": "Aktionen", | ||||||
|     "active": "Aktiv", |     "active": "Aktiv", | ||||||
|   | |||||||
| @@ -2,6 +2,6 @@ | |||||||
|     "WebVersion": { |     "WebVersion": { | ||||||
|         "Major": "1", |         "Major": "1", | ||||||
|         "Minor": "1", |         "Minor": "1", | ||||||
|         "Micro": "dev79_hide_table_columns" |         "Micro": "dev334_feature_flags_in_wi" | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -587,7 +587,7 @@ | |||||||
|  |  | ||||||
|   .p-datatable .p-sortable-column.p-highlight, |   .p-datatable .p-sortable-column.p-highlight, | ||||||
|   .p-datatable .p-sortable-column.p-highlight .p-sortable-column-icon, |   .p-datatable .p-sortable-column.p-highlight .p-sortable-column-icon, | ||||||
|   .p-datatable .p-sortable-column:not(.p-highlight):hover{ |   .p-datatable .p-sortable-column:not(.p-highlight):hover { | ||||||
|     color: $primaryHeaderColor !important; |     color: $primaryHeaderColor !important; | ||||||
|     background-color: transparent !important; |     background-color: transparent !important; | ||||||
|   } |   } | ||||||
| @@ -672,4 +672,13 @@ | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   .p-inputswitch.p-inputswitch-checked .p-inputswitch-slider { | ||||||
|  |     background: $primaryHeaderColor !important; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .p-inputswitch.p-focus .p-inputswitch-slider { | ||||||
|  |     box-shadow: none !important; | ||||||
|  |   } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user