staging #483
| @@ -15,7 +15,7 @@ __title__ = "bot" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.8" | ||||
| __version__ = "1.2.9" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="9") | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|     "Version": { | ||||
|       "Major": "1", | ||||
|       "Minor": "2", | ||||
|       "Micro": "8" | ||||
|       "Micro": "9" | ||||
|     }, | ||||
|     "Author": "Sven Heidemann", | ||||
|     "AuthorEmail": "sven.heidemann@sh-edraft.de", | ||||
| @@ -71,6 +71,7 @@ | ||||
|       "../modules/config/config.json", | ||||
|       "../modules/database/database.json", | ||||
|       "../modules/level/level.json", | ||||
|       "../modules/realms/realms.json", | ||||
|       "../modules/short_role_name/short-role-name.json", | ||||
|       "../modules/special_offers/special-offers.json", | ||||
|       "../modules/technician/technician.json" | ||||
|   | ||||
 Submodule bot/src/bot/config updated: eeebd13f80...40df176141
									
								
							| @@ -12,6 +12,7 @@ from modules.boot_log.boot_log_module import BootLogModule | ||||
| from modules.config.config_module import ConfigModule | ||||
| from modules.database.database_module import DatabaseModule | ||||
| from modules.level.level_module import LevelModule | ||||
| from modules.realms.reams_module import RealmsModule | ||||
| from modules.short_role_name.short_role_name_module import ShortRoleNameModule | ||||
| from modules.special_offers.special_offers_module import SteamSpecialOffersModule | ||||
| from modules.technician.technician_module import TechnicianModule | ||||
| @@ -37,6 +38,7 @@ class ModuleList: | ||||
|                 AchievementsModule, | ||||
|                 ShortRoleNameModule, | ||||
|                 SteamSpecialOffersModule, | ||||
|                 RealmsModule, | ||||
|                 # has to be last! | ||||
|                 BootLogModule, | ||||
|                 CoreExtensionModule, | ||||
|   | ||||
| @@ -95,6 +95,56 @@ | ||||
|     } | ||||
|   }, | ||||
|   "modules": { | ||||
|     "realm": { | ||||
|       "list": { | ||||
|         "title": "Level:", | ||||
|         "description": "Konfigurierte Level:", | ||||
|         "realm_names": "Realm-Namen", | ||||
|         "error": { | ||||
|           "nothing_found": "Keine Einträge gefunden." | ||||
|         } | ||||
|       }, | ||||
|       "add": { | ||||
|         "error": { | ||||
|           "role_exists": "Die Rolle {} existiert bereits.", | ||||
|           "category_exists": "Die Kategorie {} existiert bereits.", | ||||
|           "realm_exists": "Das Realm {} existiert bereits.", | ||||
|           "realm_create": "Fehler beim Erstellen des Realms {}." | ||||
|         }, | ||||
|         "success": "Das Realm {} wurde erfolgreich erstellt." | ||||
|       }, | ||||
|       "edit": { | ||||
|         "error": { | ||||
|           "realm_not_found": "Das Realm {} wurde nicht gefunden." | ||||
|         }, | ||||
|         "success": "Das Realm {} wurde erfolgreich in {} umbenannt." | ||||
|       }, | ||||
|       "error": { | ||||
|         "not_moderator": "Du bist kein Moderator des Realms {}." | ||||
|       }, | ||||
|       "delete": { | ||||
|         "error": { | ||||
|           "realm_not_found": "Das Realm {} wurde nicht gefunden." | ||||
|         }, | ||||
|         "success": "Das Realm {} wurde erfolgreich gelöscht." | ||||
|       }, | ||||
|       "member": { | ||||
|         "add": { | ||||
|           "success": "{} wurde erfolgreich zum Realm {} hinzugefügt." | ||||
|         }, | ||||
|         "remove": { | ||||
|           "success": "{} wurde erfolgreich aus dem Realm {} entfernt." | ||||
|         } | ||||
|       }, | ||||
|       "moderator": { | ||||
|         "add": { | ||||
|           "success": "{} wurde erfolgreich zum Moderator des Realms {} hinzugefügt." | ||||
|         }, | ||||
|         "remove": { | ||||
|           "success": "{} wurde erfolgreich als Moderator des Realms {} entfernt." | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "special_offers": { | ||||
|       "price": "Preis", | ||||
|       "discount": "Rabatt", | ||||
|   | ||||
| @@ -17,6 +17,7 @@ class FeatureFlagsEnum(Enum): | ||||
|     moderator_module = "ModeratorModule" | ||||
|     short_role_name_module = "ShortRoleNameModule" | ||||
|     steam_special_offers_module = "SteamSpecialOffersModule" | ||||
|     realm_module = "RealmModule" | ||||
|     # features | ||||
|     api_only = "ApiOnly" | ||||
|     presence = "Presence" | ||||
|   | ||||
| @@ -19,6 +19,7 @@ class FeatureFlagsSettings(ConfigurationModelABC): | ||||
|         FeatureFlagsEnum.config_module.value: True,  # 19.07.2023 #127 | ||||
|         FeatureFlagsEnum.short_role_name_module.value: True,  # 28.09.2023 #378 | ||||
|         FeatureFlagsEnum.steam_special_offers_module.value: True,  # 11.10.2023 #188 | ||||
|         FeatureFlagsEnum.realm_module.value: True,  # 07.01.2025 #481 | ||||
|         # features | ||||
|         FeatureFlagsEnum.api_only.value: False,  # 13.10.2022 #70 | ||||
|         FeatureFlagsEnum.presence.value: True,  # 03.10.2022 #56 | ||||
|   | ||||
							
								
								
									
										69
									
								
								bot/src/bot_data/abc/realm_repository_abc.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								bot/src/bot_data/abc/realm_repository_abc.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,69 @@ | ||||
| from abc import ABC, abstractmethod | ||||
| from typing import Optional | ||||
|  | ||||
| from cpl_query.extension import List | ||||
|  | ||||
| from bot_data.model.realm import Realm | ||||
| from bot_data.model.realm_moderator import RealmModerator | ||||
|  | ||||
|  | ||||
| class RealmRepositoryABC(ABC): | ||||
|     @abstractmethod | ||||
|     def __init__(self): | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def get_all(self) -> List[Realm]: | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def get_realm_by_id(self, id: int) -> Realm: | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def find_realm_by_id(self, id: int) -> Optional[Realm]: | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def find_realm_by_name(self, name: str) -> Optional[Realm]: | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def get_realms_by_server_id(self, id: int) -> List[Realm]: | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def add_realm(self, realm: Realm): | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def update_realm(self, realm: Realm): | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def delete_realm(self, realm: Realm): | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def get_realm_moderators(self) -> List[RealmModerator]: | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def get_realm_moderator_by_id(self, id: int) -> RealmModerator: | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def get_realm_moderators_by_realm_id(self, id: int) -> List[RealmModerator]: | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def add_realm_moderator(self, realm: RealmModerator): | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def update_realm_moderator(self, realm: RealmModerator): | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def delete_realm_moderator(self, realm: RealmModerator): | ||||
|         pass | ||||
| @@ -14,6 +14,7 @@ from bot_data.abc.data_seeder_abc import DataSeederABC | ||||
| from bot_data.abc.game_server_repository_abc import GameServerRepositoryABC | ||||
| from bot_data.abc.known_user_repository_abc import KnownUserRepositoryABC | ||||
| from bot_data.abc.level_repository_abc import LevelRepositoryABC | ||||
| from bot_data.abc.realm_repository_abc import RealmRepositoryABC | ||||
| from bot_data.abc.scheduled_event_repository_abc import ScheduledEventRepositoryABC | ||||
| from bot_data.abc.server_config_repository_abc import ServerConfigRepositoryABC | ||||
| from bot_data.abc.server_repository_abc import ServerRepositoryABC | ||||
| @@ -46,6 +47,7 @@ from bot_data.service.client_repository_service import ClientRepositoryService | ||||
| from bot_data.service.game_server_repository_service import GameServerRepositoryService | ||||
| from bot_data.service.known_user_repository_service import KnownUserRepositoryService | ||||
| from bot_data.service.level_repository_service import LevelRepositoryService | ||||
| from bot_data.service.realm_repository_service import RealmRepositoryService | ||||
| from bot_data.service.scheduled_event_repository_service import ScheduledEventRepositoryService | ||||
| from bot_data.service.seeder_service import SeederService | ||||
| from bot_data.service.server_config_repository_service import ( | ||||
| @@ -118,6 +120,7 @@ class DataModule(ModuleABC): | ||||
|         services.add_transient(ShortRoleNameRepositoryABC, ShortRoleNameRepositoryService) | ||||
|         services.add_transient(SteamSpecialOfferRepositoryABC, SteamSpecialOfferRepositoryService) | ||||
|         services.add_transient(ScheduledEventRepositoryABC, ScheduledEventRepositoryService) | ||||
|         services.add_transient(RealmRepositoryABC, RealmRepositoryService) | ||||
|  | ||||
|         services.add_transient(SeederService) | ||||
|         services.add_transient(DataSeederABC, TechnicianConfigSeeder) | ||||
|   | ||||
							
								
								
									
										120
									
								
								bot/src/bot_data/model/realm.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								bot/src/bot_data/model/realm.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,120 @@ | ||||
| from datetime import datetime | ||||
| from typing import Optional | ||||
|  | ||||
| from cpl_core.database import TableABC | ||||
|  | ||||
| from bot_data.model.server import Server | ||||
|  | ||||
|  | ||||
| class Realm(TableABC): | ||||
|     def __init__( | ||||
|         self, | ||||
|         name: str, | ||||
|         role_id: int, | ||||
|         server: Optional[Server], | ||||
|         created_at: datetime = None, | ||||
|         modified_at: datetime = None, | ||||
|         id=0, | ||||
|     ): | ||||
|         self._id = id | ||||
|         self._name = name | ||||
|         self._role_id = role_id | ||||
|         self._server = server | ||||
|  | ||||
|         TableABC.__init__(self) | ||||
|         self._created_at = created_at if created_at is not None else self._created_at | ||||
|         self._modified_at = modified_at if modified_at is not None else self._modified_at | ||||
|  | ||||
|     @property | ||||
|     def id(self) -> int: | ||||
|         return self._id | ||||
|  | ||||
|     @property | ||||
|     def name(self) -> str: | ||||
|         return self._name | ||||
|  | ||||
|     @name.setter | ||||
|     def name(self, value: str): | ||||
|         self._name = value | ||||
|  | ||||
|     @property | ||||
|     def role_id(self) -> int: | ||||
|         return self._role_id | ||||
|  | ||||
|     @role_id.setter | ||||
|     def role_id(self, value: int): | ||||
|         self._role_id = value | ||||
|  | ||||
|     @property | ||||
|     def server(self) -> Server: | ||||
|         return self._server | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_select_all_string() -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|             SELECT * FROM `Realms`; | ||||
|         """ | ||||
|         ) | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_select_by_id_string(id: int) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|             SELECT * FROM `Realms` | ||||
|             WHERE `RealmId` = {id}; | ||||
|         """ | ||||
|         ) | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_select_by_server_id_string(id: int) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|             SELECT * FROM `Realms` | ||||
|             WHERE `ServerId` = {id}; | ||||
|         """ | ||||
|         ) | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_select_by_name_string(name: str) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|             SELECT * FROM `Realms` | ||||
|             WHERE `Name` = '{name}'; | ||||
|         """ | ||||
|         ) | ||||
|  | ||||
|     @property | ||||
|     def insert_string(self) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|             INSERT INTO `Realms` ( | ||||
|                 `ServerId`, `Name`, `RoleId` | ||||
|             ) VALUES ( | ||||
|                 {self._server.id}, | ||||
|                 '{self._name}', | ||||
|                 {self._role_id} | ||||
|             ); | ||||
|         """ | ||||
|         ) | ||||
|  | ||||
|     @property | ||||
|     def udpate_string(self) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|             UPDATE `Realms` | ||||
|             SET `ServerId` = {self._server.id}, | ||||
|             `Name` = '{self._name}', | ||||
|             `RoleId` = {self._role_id} | ||||
|             WHERE `RealmId` = {self._id}; | ||||
|         """ | ||||
|         ) | ||||
|  | ||||
|     @property | ||||
|     def delete_string(self) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|             DELETE FROM `Realms` | ||||
|             WHERE `RealmId` = {self._id}; | ||||
|         """ | ||||
|         ) | ||||
							
								
								
									
										43
									
								
								bot/src/bot_data/model/realm_history.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								bot/src/bot_data/model/realm_history.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| from typing import Optional | ||||
|  | ||||
| from bot_data.abc.history_table_abc import HistoryTableABC | ||||
| from bot_data.model.server import Server | ||||
|  | ||||
|  | ||||
| class Realm(HistoryTableABC): | ||||
|     def __init__( | ||||
|         self, | ||||
|         server: Optional[Server], | ||||
|         name: str, | ||||
|         role_id: int, | ||||
|         deleted: bool, | ||||
|         date_from: str, | ||||
|         date_to: str, | ||||
|         id=0, | ||||
|     ): | ||||
|         HistoryTableABC.__init__(self) | ||||
|  | ||||
|         self._id = id | ||||
|         self._server = server | ||||
|         self._name = name | ||||
|         self._role_id = role_id | ||||
|  | ||||
|         self._deleted = deleted | ||||
|         self._date_from = date_from | ||||
|         self._date_to = date_to | ||||
|  | ||||
|     @property | ||||
|     def id(self) -> int: | ||||
|         return self._id | ||||
|  | ||||
|     @property | ||||
|     def server(self) -> Server: | ||||
|         return self._server | ||||
|  | ||||
|     @property | ||||
|     def name(self) -> str: | ||||
|         return self._name | ||||
|  | ||||
|     @property | ||||
|     def role_id(self) -> int: | ||||
|         return self._role_id | ||||
							
								
								
									
										106
									
								
								bot/src/bot_data/model/realm_moderator.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								bot/src/bot_data/model/realm_moderator.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,106 @@ | ||||
| from datetime import datetime | ||||
|  | ||||
| from cpl_core.database import TableABC | ||||
|  | ||||
| from bot_data.model.realm import Realm | ||||
| from bot_data.model.user import User | ||||
|  | ||||
|  | ||||
| class RealmModerator(TableABC): | ||||
|     def __init__( | ||||
|         self, | ||||
|         realm: Realm, | ||||
|         user: User, | ||||
|         created_at: datetime = None, | ||||
|         modified_at: datetime = None, | ||||
|         id=0, | ||||
|     ): | ||||
|         self._join_id = id | ||||
|         self._realm = realm | ||||
|         self._user = user | ||||
|  | ||||
|         TableABC.__init__(self) | ||||
|         self._created_at = created_at if created_at is not None else self._created_at | ||||
|         self._modified_at = modified_at if modified_at is not None else self._modified_at | ||||
|  | ||||
|     @property | ||||
|     def id(self) -> int: | ||||
|         return self._join_id | ||||
|  | ||||
|     @property | ||||
|     def realm(self) -> Realm: | ||||
|         return self._realm | ||||
|  | ||||
|     @property | ||||
|     def user(self) -> User: | ||||
|         return self._user | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_select_all_string() -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|             SELECT * FROM `RealmModerators`; | ||||
|         """ | ||||
|         ) | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_select_by_id_string(id: int) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|             SELECT * FROM `RealmModerators` | ||||
|             WHERE `Id` = {id}; | ||||
|         """ | ||||
|         ) | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_select_by_realm_id_string(id: int) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|             SELECT * FROM `RealmModerators` | ||||
|             WHERE `RealmId` = {id}; | ||||
|         """ | ||||
|         ) | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_select_by_user_id_string(id: int) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|             SELECT * FROM `RealmModerators` | ||||
|             WHERE `UserId` = {id}; | ||||
|         """ | ||||
|         ) | ||||
|  | ||||
|     @property | ||||
|     def insert_string(self) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|             INSERT INTO `RealmModerators` ( | ||||
|                 `UserId`, `RealmId` | ||||
|             ) VALUES ( | ||||
|                 {self._user.id}, | ||||
|                 {self._realm.id} | ||||
|             ); | ||||
|         """ | ||||
|         ) | ||||
|  | ||||
|     @property | ||||
|     def udpate_string(self) -> str: | ||||
|         return str(f"""""") | ||||
|  | ||||
|     @property | ||||
|     def delete_string(self) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|             DELETE FROM `RealmModerators` | ||||
|             WHERE `Id` = {self._join_id}; | ||||
|         """ | ||||
|         ) | ||||
|  | ||||
|     @staticmethod | ||||
|     def delete_by_user_id_string(id: int) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|             DELETE FROM `RealmModerators` | ||||
|             WHERE `UserId` = {id} | ||||
|     """ | ||||
|         ) | ||||
							
								
								
									
										36
									
								
								bot/src/bot_data/model/realm_moderator_history.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								bot/src/bot_data/model/realm_moderator_history.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| from bot_data.abc.history_table_abc import HistoryTableABC | ||||
| from bot_data.model.realm import Realm | ||||
| from bot_data.model.user import User | ||||
|  | ||||
|  | ||||
| class RealmModerator(HistoryTableABC): | ||||
|     def __init__( | ||||
|         self, | ||||
|         realm: Realm, | ||||
|         user: User, | ||||
|         deleted: bool, | ||||
|         date_from: str, | ||||
|         date_to: str, | ||||
|         id=0, | ||||
|     ): | ||||
|         HistoryTableABC.__init__(self) | ||||
|  | ||||
|         self._join_id = id | ||||
|         self._realm = realm | ||||
|         self._user = user | ||||
|  | ||||
|         self._deleted = deleted | ||||
|         self._date_from = date_from | ||||
|         self._date_to = date_to | ||||
|  | ||||
|     @property | ||||
|     def id(self) -> int: | ||||
|         return self._join_id | ||||
|  | ||||
|     @property | ||||
|     def realm(self) -> Realm: | ||||
|         return self._realm | ||||
|  | ||||
|     @property | ||||
|     def user(self) -> User: | ||||
|         return self._user | ||||
							
								
								
									
										4
									
								
								bot/src/bot_data/scripts/1.2.9/1_Realm_down.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								bot/src/bot_data/scripts/1.2.9/1_Realm_down.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| DROP TABLE IF EXISTS `Realms`; | ||||
| DROP TABLE IF EXISTS `RealmsHistory`; | ||||
| DROP TABLE IF EXISTS `RealmModerators`; | ||||
| DROP TABLE IF EXISTS `RealmModeratorsHistory`; | ||||
							
								
								
									
										97
									
								
								bot/src/bot_data/scripts/1.2.9/1_Realm_up.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								bot/src/bot_data/scripts/1.2.9/1_Realm_up.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,97 @@ | ||||
| CREATE TABLE IF NOT EXISTS `Realms` | ||||
| ( | ||||
|     `RealmId`        BIGINT       NOT NULL AUTO_INCREMENT, | ||||
|     `Name`           VARCHAR(255) NOT NULL, | ||||
|     `RoleId`         BIGINT       NOT NULL, | ||||
|     `ServerId`       BIGINT, | ||||
|     `CreatedAt`      DATETIME(6)  NULL DEFAULT CURRENT_TIMESTAMP(6), | ||||
|     `LastModifiedAt` DATETIME(6)  NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), | ||||
|     PRIMARY KEY (`RealmId`), | ||||
|     FOREIGN KEY (`ServerId`) REFERENCES `Servers` (`ServerId`) | ||||
| ); | ||||
|  | ||||
|  | ||||
| CREATE TABLE IF NOT EXISTS `RealmsHistory` | ||||
| ( | ||||
|     `RealmId`  BIGINT(20)   NOT NULL, | ||||
|     `Name`     VARCHAR(255) NOT NULL, | ||||
|     `RoleId`   BIGINT       NOT NULL, | ||||
|     `ServerId` BIGINT(20) DEFAULT NULL, | ||||
|     `Deleted`  BOOL       DEFAULT FALSE, | ||||
|     `DateFrom` DATETIME(6)  NOT NULL, | ||||
|     `DateTo`   DATETIME(6)  NOT NULL | ||||
| ); | ||||
|  | ||||
| DROP TRIGGER IF EXISTS `TR_RealmsUpdate`; | ||||
|  | ||||
| CREATE TRIGGER `TR_RealmsUpdate` | ||||
|     AFTER UPDATE | ||||
|     ON `Realms` | ||||
|     FOR EACH ROW | ||||
| BEGIN | ||||
|     INSERT INTO `RealmsHistory` (`RealmId`, `Name`, `RoleId`, `ServerId`, `DateFrom`, `DateTo`) | ||||
|     VALUES (OLD.RealmId, OLD.Name, OLD.RoleId, OLD.ServerId, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6)); | ||||
| END; | ||||
|  | ||||
| DROP TRIGGER IF EXISTS `TR_RealmsDelete`; | ||||
|  | ||||
| CREATE TRIGGER `TR_RealmsDelete` | ||||
|     AFTER DELETE | ||||
|     ON `Realms` | ||||
|     FOR EACH ROW | ||||
| BEGIN | ||||
|     INSERT INTO `RealmsHistory` (`RealmId`, `Name`, `RoleId`, `ServerId`, `Deleted`, `DateFrom`, `DateTo`) | ||||
|     VALUES (OLD.RealmId, OLD.Name, OLD.RoleId, OLD.ServerId, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6)); | ||||
| END; | ||||
|  | ||||
| -- Realm moderators | ||||
|  | ||||
| CREATE TABLE IF NOT EXISTS `RealmModerators` | ||||
| ( | ||||
|     `Id`             BIGINT      NOT NULL AUTO_INCREMENT, | ||||
|     `RealmId`        BIGINT      NOT NULL, | ||||
|     `UserId`         BIGINT      NOT NULL, | ||||
|     `ServerId`       BIGINT, | ||||
|     `CreatedAt`      DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6), | ||||
|     `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), | ||||
|     PRIMARY KEY (`Id`), | ||||
|     FOREIGN KEY (`RealmId`) REFERENCES `Realms` (`RealmId`), | ||||
|     FOREIGN KEY (`UserId`) REFERENCES `Users` (`UserId`), | ||||
|     FOREIGN KEY (`ServerId`) REFERENCES `Servers` (`ServerId`) | ||||
| ); | ||||
|  | ||||
|  | ||||
| CREATE TABLE IF NOT EXISTS `RealmModeratorsHistory` | ||||
| ( | ||||
|     `Id`       BIGINT(20)  NOT NULL, | ||||
|     `RealmId`  BIGINT      NOT NULL, | ||||
|     `UserId`   BIGINT      NOT NULL, | ||||
|     `ServerId` BIGINT(20) DEFAULT NULL, | ||||
|     `Deleted`  BOOL       DEFAULT FALSE, | ||||
|     `DateFrom` DATETIME(6) NOT NULL, | ||||
|     `DateTo`   DATETIME(6) NOT NULL | ||||
| ); | ||||
|  | ||||
| DROP TRIGGER IF EXISTS `TR_RealmModeratorsUpdate`; | ||||
|  | ||||
| CREATE TRIGGER `TR_RealmModeratorsUpdate` | ||||
|     AFTER UPDATE | ||||
|     ON `RealmModerators` | ||||
|     FOR EACH ROW | ||||
| BEGIN | ||||
|     INSERT INTO `RealmModeratorsHistory` (`Id`, `RealmId`, `UserId`, `ServerId`, `DateFrom`, `DateTo`) | ||||
|     VALUES (OLD.Id, OLD.RealmId, OLD.UserId, OLD.ServerId, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6)); | ||||
| END; | ||||
|  | ||||
| DROP TRIGGER IF EXISTS `TR_RealmModeratorsDelete`; | ||||
|  | ||||
| CREATE TRIGGER `TR_RealmModeratorsDelete` | ||||
|     AFTER DELETE | ||||
|     ON `RealmModerators` | ||||
|     FOR EACH ROW | ||||
| BEGIN | ||||
|     INSERT INTO `RealmModeratorsHistory` (`Id`, `RealmId`, `UserId`, `ServerId`, `Deleted`, `DateFrom`, `DateTo`) | ||||
|     VALUES (OLD.Id, OLD.RealmId, OLD.UserId, OLD.ServerId, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6)); | ||||
| END; | ||||
|  | ||||
|  | ||||
							
								
								
									
										127
									
								
								bot/src/bot_data/service/realm_repository_service.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								bot/src/bot_data/service/realm_repository_service.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,127 @@ | ||||
| from typing import Optional | ||||
|  | ||||
| from cpl_core.database.context import DatabaseContextABC | ||||
| from cpl_query.extension import List | ||||
|  | ||||
| from bot_core.logging.database_logger import DatabaseLogger | ||||
| from bot_data.abc.realm_repository_abc import RealmRepositoryABC | ||||
| from bot_data.abc.server_repository_abc import ServerRepositoryABC | ||||
| from bot_data.abc.user_repository_abc import UserRepositoryABC | ||||
| from bot_data.model.realm import Realm | ||||
| from bot_data.model.realm_moderator import RealmModerator | ||||
|  | ||||
|  | ||||
| class RealmRepositoryService(RealmRepositoryABC): | ||||
|     def __init__( | ||||
|         self, | ||||
|         logger: DatabaseLogger, | ||||
|         db_context: DatabaseContextABC, | ||||
|         servers: ServerRepositoryABC, | ||||
|         users: UserRepositoryABC, | ||||
|     ): | ||||
|         self._logger = logger | ||||
|         self._context = db_context | ||||
|         self._servers = servers | ||||
|         self._users = users | ||||
|  | ||||
|         RealmRepositoryABC.__init__(self) | ||||
|  | ||||
|     def _from_result(self, result: tuple) -> Realm: | ||||
|         return Realm( | ||||
|             result[1], | ||||
|             result[2], | ||||
|             self._servers.get_server_by_id(result[3]), | ||||
|             result[4], | ||||
|             result[5], | ||||
|             id=result[0], | ||||
|         ) | ||||
|  | ||||
|     def get_all(self) -> List[Realm]: | ||||
|         self._logger.trace(__name__, f"Send SQL command: {Realm.get_select_all_string()}") | ||||
|         return List( | ||||
|             Realm, [self._from_result(result) for result in self._context.select(Realm.get_select_all_string())] | ||||
|         ) | ||||
|  | ||||
|     def get_realm_by_id(self, id: int) -> Realm: | ||||
|         self._logger.trace(__name__, f"Send SQL command: {Realm.get_select_by_id_string(id)}") | ||||
|         return self._from_result(self._context.select(Realm.get_select_by_id_string(id))[0]) | ||||
|  | ||||
|     def find_realm_by_id(self, id: int) -> Optional[Realm]: | ||||
|         self._logger.trace(__name__, f"Send SQL command: {Realm.get_select_by_id_string(id)}") | ||||
|         result = self._context.select(Realm.get_select_by_id_string(id)) | ||||
|         if result is None or len(result) == 0: | ||||
|             return None | ||||
|  | ||||
|         return self._from_result(result[0]) | ||||
|  | ||||
|     def find_realm_by_name(self, name: str) -> Optional[Realm]: | ||||
|         self._logger.trace(__name__, f"Send SQL command: {Realm.get_select_by_name_string(name)}") | ||||
|         result = self._context.select(Realm.get_select_by_name_string(name)) | ||||
|         if result is None or len(result) == 0: | ||||
|             return None | ||||
|  | ||||
|         return self._from_result(result[0]) | ||||
|  | ||||
|     def get_realms_by_server_id(self, id: int) -> List[Realm]: | ||||
|         self._logger.trace(__name__, f"Send SQL command: {Realm.get_select_by_server_id_string(id)}") | ||||
|         return List( | ||||
|             Realm, | ||||
|             [self._from_result(result) for result in self._context.select(Realm.get_select_by_server_id_string(id))], | ||||
|         ) | ||||
|  | ||||
|     def add_realm(self, realm: Realm): | ||||
|         self._logger.trace(__name__, f"Send SQL command: {realm.insert_string}") | ||||
|         self._context.cursor.execute(realm.insert_string) | ||||
|  | ||||
|     def update_realm(self, realm: Realm): | ||||
|         self._logger.trace(__name__, f"Send SQL command: {realm.udpate_string}") | ||||
|         self._context.cursor.execute(realm.udpate_string) | ||||
|  | ||||
|     def delete_realm(self, realm: Realm): | ||||
|         self._logger.trace(__name__, f"Send SQL command: {realm.delete_string}") | ||||
|         self._context.cursor.execute(realm.delete_string) | ||||
|  | ||||
|     def _rule_from_result(self, result: tuple) -> RealmModerator: | ||||
|         return RealmModerator( | ||||
|             self.get_realm_by_id(result[1]), | ||||
|             self._users.get_user_by_id(result[2]), | ||||
|             result[4], | ||||
|             result[5], | ||||
|             id=result[0], | ||||
|         ) | ||||
|  | ||||
|     def get_realm_moderators(self) -> List[RealmModerator]: | ||||
|         self._logger.trace(__name__, f"Send SQL command: {RealmModerator.get_select_all_string()}") | ||||
|         return List( | ||||
|             RealmModerator, | ||||
|             [self._rule_from_result(result) for result in self._context.select(RealmModerator.get_select_all_string())], | ||||
|         ) | ||||
|  | ||||
|     def get_realm_moderator_by_id(self, id: int) -> RealmModerator: | ||||
|         self._logger.trace(__name__, f"Send SQL command: {RealmModerator.get_select_by_id_string(id)}") | ||||
|         return self._rule_from_result(self._context.select(RealmModerator.get_select_by_id_string(id))[0]) | ||||
|  | ||||
|     def get_realm_moderators_by_realm_id(self, id: int) -> List[RealmModerator]: | ||||
|         self._logger.trace( | ||||
|             __name__, | ||||
|             f"Send SQL command: {RealmModerator.get_select_by_realm_id_string(id)}", | ||||
|         ) | ||||
|         return List( | ||||
|             RealmModerator, | ||||
|             [ | ||||
|                 self._rule_from_result(result) | ||||
|                 for result in self._context.select(RealmModerator.get_select_by_realm_id_string(id)) | ||||
|             ], | ||||
|         ) | ||||
|  | ||||
|     def add_realm_moderator(self, realm_moderator: RealmModerator): | ||||
|         self._logger.trace(__name__, f"Send SQL command: {realm_moderator.insert_string}") | ||||
|         self._context.cursor.execute(realm_moderator.insert_string) | ||||
|  | ||||
|     def update_realm_moderator(self, realm_moderator: RealmModerator): | ||||
|         self._logger.trace(__name__, f"Send SQL command: {realm_moderator.udpate_string}") | ||||
|         self._context.cursor.execute(realm_moderator.udpate_string) | ||||
|  | ||||
|     def delete_realm_moderator(self, realm_moderator: RealmModerator): | ||||
|         self._logger.trace(__name__, f"Send SQL command: {realm_moderator.delete_string}") | ||||
|         self._context.cursor.execute(realm_moderator.delete_string) | ||||
							
								
								
									
										0
									
								
								bot/src/modules/realms/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								bot/src/modules/realms/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								bot/src/modules/realms/command/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								bot/src/modules/realms/command/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										446
									
								
								bot/src/modules/realms/command/realm_group.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										446
									
								
								bot/src/modules/realms/command/realm_group.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,446 @@ | ||||
| from typing import List as TList | ||||
| from typing import Optional | ||||
|  | ||||
| import discord | ||||
| from cpl_discord.command import DiscordCommandABC | ||||
| from cpl_discord.service import DiscordBotServiceABC | ||||
| from cpl_translation import TranslatePipe | ||||
| from discord import app_commands, Member | ||||
| from discord.ext import commands | ||||
| from discord.ext.commands import Context | ||||
|  | ||||
| from bot_core.abc.client_utils_abc import ClientUtilsABC | ||||
| from bot_core.abc.message_service_abc import MessageServiceABC | ||||
| from bot_core.abc.permission_service_abc import PermissionServiceABC | ||||
| from bot_core.helper.command_checks import CommandChecks | ||||
| from bot_core.logging.command_logger import CommandLogger | ||||
| from bot_data.abc.realm_repository_abc import RealmRepositoryABC | ||||
| from bot_data.abc.server_repository_abc import ServerRepositoryABC | ||||
| from bot_data.abc.user_repository_abc import UserRepositoryABC | ||||
| from bot_data.model.realm import Realm | ||||
| from bot_data.model.realm_moderator import RealmModerator | ||||
| from bot_data.model.technician_config import TechnicianConfig | ||||
| from modules.realms.realm_utils import RealmUtils | ||||
|  | ||||
|  | ||||
| class RealmGroup(DiscordCommandABC): | ||||
|     def __init__( | ||||
|         self, | ||||
|         logger: CommandLogger, | ||||
|         message_service: MessageServiceABC, | ||||
|         bot: DiscordBotServiceABC, | ||||
|         client_utils: ClientUtilsABC, | ||||
|         translate: TranslatePipe, | ||||
|         permissions: PermissionServiceABC, | ||||
|         servers: ServerRepositoryABC, | ||||
|         users: UserRepositoryABC, | ||||
|         realms: RealmRepositoryABC, | ||||
|         settings: TechnicianConfig, | ||||
|         realm_utils: RealmUtils, | ||||
|     ): | ||||
|         DiscordCommandABC.__init__(self) | ||||
|  | ||||
|         self._logger = logger | ||||
|         self._message_service = message_service | ||||
|         self._bot = bot | ||||
|         self._client_utils = client_utils | ||||
|         self._t = translate | ||||
|         self._permissions = permissions | ||||
|         self._servers = servers | ||||
|         self._users = users | ||||
|         self._realms = realms | ||||
|         self._settings = settings | ||||
|         self._realm_utils = realm_utils | ||||
|  | ||||
|         self._logger.trace(__name__, f"Loaded command service: {type(self).__name__}") | ||||
|  | ||||
|     async def _auto_realm_complete( | ||||
|         self, interaction: discord.Interaction, current: str | ||||
|     ) -> TList[app_commands.Choice[str]]: | ||||
|         server = self._servers.get_server_by_discord_id(interaction.guild.id) | ||||
|         realms = self._realms.get_realms_by_server_id(server.id).select(lambda x: x.name) | ||||
|         return [ | ||||
|             app_commands.Choice(name=realm, value=realm) | ||||
|             for realm in self._client_utils.get_auto_complete_list(realms, current, lambda x: x.name) | ||||
|         ] | ||||
|  | ||||
|     @commands.hybrid_group(name="realm") | ||||
|     @commands.guild_only() | ||||
|     async def realm(self, ctx: Context): | ||||
|         pass | ||||
|  | ||||
|     @realm.command() | ||||
|     @commands.guild_only() | ||||
|     @CommandChecks.check_is_ready() | ||||
|     @CommandChecks.check_is_member_moderator() | ||||
|     async def list(self, ctx: Context): | ||||
|         self._logger.debug(__name__, f"Received command realm list {ctx}") | ||||
|         realms = self._realms.get_all() | ||||
|  | ||||
|         if len(realms) == 0: | ||||
|             await self._message_service.send_ctx_msg(ctx, self._t.transform("modules.realm.list.error.nothing_found")) | ||||
|             self._logger.trace(__name__, f"Finished command realm list") | ||||
|             return | ||||
|  | ||||
|         embed = discord.Embed( | ||||
|             title=self._t.transform("modules.realm.list.title"), | ||||
|             description=self._t.transform("modules.realm.list.description"), | ||||
|             color=int("ef9d0d", 16), | ||||
|         ) | ||||
|  | ||||
|         realm_names = "" | ||||
|         for realm in realms: | ||||
|             realm_names += f"\n{realm.name}" | ||||
|  | ||||
|         embed.add_field( | ||||
|             name=self._t.transform("modules.realm.list.realm_names"), | ||||
|             value=realm_names, | ||||
|             inline=True, | ||||
|         ) | ||||
|  | ||||
|         await self._message_service.send_ctx_msg(ctx, embed) | ||||
|         self._logger.trace(__name__, f"Finished command realm list") | ||||
|  | ||||
|     @realm.command() | ||||
|     @commands.guild_only() | ||||
|     @CommandChecks.check_is_ready() | ||||
|     @CommandChecks.check_is_member_moderator() | ||||
|     async def add(self, ctx: Context, name: str, leader: Optional[discord.Member] = None): | ||||
|         self._logger.debug(__name__, f"Received command realm list {ctx}") | ||||
|  | ||||
|         if self._realm_utils.find_role_by_name(ctx.guild, name) is not None: | ||||
|             await self._message_service.send_ctx_msg( | ||||
|                 ctx, | ||||
|                 self._t.transform("modules.realm.add.error.role_exists").format(name), | ||||
|             ) | ||||
|             return | ||||
|  | ||||
|         if name in [x.name for x in ctx.guild.categories]: | ||||
|             await self._message_service.send_ctx_msg( | ||||
|                 ctx, | ||||
|                 self._t.transform("modules.realm.add.error.category_exists").format(name), | ||||
|             ) | ||||
|             return | ||||
|  | ||||
|         try: | ||||
|             role = await ctx.guild.create_role(name=name) | ||||
|             server = self._servers.get_server_by_discord_id(ctx.guild.id) | ||||
|             if self._realms.find_realm_by_name(name) is not None: | ||||
|                 await role.delete() | ||||
|                 await self._message_service.send_ctx_msg( | ||||
|                     ctx, | ||||
|                     self._t.transform("modules.realm.add.error.realm_exists").format(name), | ||||
|                 ) | ||||
|                 return | ||||
|  | ||||
|             realm = Realm(name, role.id, server) | ||||
|             self._realms.add_realm(realm) | ||||
|             realm = self._realms.find_realm_by_name(name) | ||||
|             if realm is None: | ||||
|                 raise ValueError("Realm not found after creation") | ||||
|  | ||||
|             if leader is not None: | ||||
|                 self._realms.add_realm_moderator( | ||||
|                     RealmModerator(realm, self._users.get_user_by_discord_id_and_server_id(leader.id, server.id)) | ||||
|                 ) | ||||
|  | ||||
|             await self._realm_utils.create_category(ctx.guild, name, role, leader) | ||||
|  | ||||
|             await self._message_service.send_ctx_msg( | ||||
|                 ctx, | ||||
|                 self._t.transform("modules.realm.add.success").format(name), | ||||
|             ) | ||||
|         except Exception as e: | ||||
|             role = self._realm_utils.find_role_by_name(ctx.guild, name) | ||||
|             if role is not None: | ||||
|                 await role.delete() | ||||
|  | ||||
|             self._logger.error(__name__, f"Error creating realm: {e}") | ||||
|             await self._message_service.send_ctx_msg( | ||||
|                 ctx, | ||||
|                 self._t.transform("modules.realm.add.error.realm_create").format(name), | ||||
|             ) | ||||
|             return | ||||
|  | ||||
|         self._logger.trace(__name__, f"Finished realm list command") | ||||
|  | ||||
|     @realm.command() | ||||
|     @commands.guild_only() | ||||
|     @CommandChecks.check_is_ready() | ||||
|     @CommandChecks.check_is_member_moderator() | ||||
|     async def edit(self, ctx: Context, realm_name: str, name: str): | ||||
|         self._logger.debug(__name__, f"Received command realm list {ctx}") | ||||
|         realm = self._realms.find_realm_by_name(realm_name) | ||||
|         if realm is None: | ||||
|             await self._message_service.send_ctx_msg( | ||||
|                 ctx, | ||||
|                 self._t.transform("modules.realm.edit.error.realm_not_found").format(realm_name), | ||||
|             ) | ||||
|             return | ||||
|  | ||||
|         realm.name = name | ||||
|         self._realms.update_realm(realm) | ||||
|  | ||||
|         role = self._realm_utils.find_role_by_name(ctx.guild, realm_name) | ||||
|         if role is None and self._realm_utils.find_role_by_name(ctx.guild, name) is None: | ||||
|             role = await ctx.guild.create_role(name=name) | ||||
|             realm.role_id = role.id | ||||
|             self._realms.update_realm(realm) | ||||
|  | ||||
|         elif role is not None: | ||||
|             await role.edit(name=name) | ||||
|  | ||||
|         category = self._realm_utils.find_category_by_name(ctx.guild, realm_name) | ||||
|         if category is None: | ||||
|             mods = self._realms.get_realm_moderators_by_realm_id(realm.id) | ||||
|             leader = mods[0].user.discord_id if len(mods) > 0 else None | ||||
|  | ||||
|             await self._realm_utils.create_category(ctx.guild, name, role, leader) | ||||
|  | ||||
|         await category.edit(name=name) | ||||
|         await self._message_service.send_ctx_msg( | ||||
|             ctx, | ||||
|             self._t.transform("modules.realm.edit.success").format(realm_name, name), | ||||
|         ) | ||||
|  | ||||
|         self._logger.trace(__name__, f"Finished realm list command") | ||||
|  | ||||
|     @edit.autocomplete("realm_name") | ||||
|     async def remove_autocomplete( | ||||
|         self, interaction: discord.Interaction, current: str | ||||
|     ) -> TList[app_commands.Choice[str]]: | ||||
|         return await self._auto_realm_complete(interaction, current) | ||||
|  | ||||
|     @realm.command() | ||||
|     @commands.guild_only() | ||||
|     @CommandChecks.check_is_ready() | ||||
|     @CommandChecks.check_is_member_moderator() | ||||
|     async def delete(self, ctx: Context, realm_name: str): | ||||
|         self._logger.debug(__name__, f"Received command realm list {ctx}") | ||||
|         realm = self._realms.find_realm_by_name(realm_name) | ||||
|         if realm is None: | ||||
|             await self._message_service.send_ctx_msg( | ||||
|                 ctx, | ||||
|                 self._t.transform("modules.realm.delete.error.realm_not_found").format(realm_name), | ||||
|             ) | ||||
|             return | ||||
|  | ||||
|         role = self._realm_utils.find_role_by_name(ctx.guild, realm_name) | ||||
|         if role is not None: | ||||
|             await role.delete() | ||||
|  | ||||
|         category = self._realm_utils.find_category_by_name(ctx.guild, realm_name) | ||||
|         if category is not None: | ||||
|             for c in category.channels: | ||||
|                 await c.delete() | ||||
|  | ||||
|             await category.delete() | ||||
|  | ||||
|         mods = self._realms.get_realm_moderators_by_realm_id(realm.id) | ||||
|         for mod in mods: | ||||
|             self._realms.delete_realm_moderator(mod) | ||||
|  | ||||
|         self._realms.delete_realm(realm) | ||||
|         await self._message_service.send_ctx_msg( | ||||
|             ctx, | ||||
|             self._t.transform("modules.realm.delete.success").format(realm_name), | ||||
|         ) | ||||
|  | ||||
|         self._logger.trace(__name__, f"Finished realm list command") | ||||
|  | ||||
|     @delete.autocomplete("realm_name") | ||||
|     async def remove_autocomplete( | ||||
|         self, interaction: discord.Interaction, current: str | ||||
|     ) -> TList[app_commands.Choice[str]]: | ||||
|         return await self._auto_realm_complete(interaction, current) | ||||
|  | ||||
|     @realm.group(name="member") | ||||
|     @commands.guild_only() | ||||
|     async def member(self, ctx: Context): | ||||
|         pass | ||||
|  | ||||
|     @member.command("add") | ||||
|     @commands.guild_only() | ||||
|     @CommandChecks.check_is_ready() | ||||
|     async def member_add(self, ctx: Context, realm: str, member: Member): | ||||
|         self._logger.debug(__name__, f"Received command realm member add {ctx}") | ||||
|  | ||||
|         realm = self._realms.find_realm_by_name(realm) | ||||
|         if realm is None: | ||||
|             await self._message_service.send_ctx_msg( | ||||
|                 ctx, | ||||
|                 self._t.transform("modules.realm.add.error.realm_not_found").format(realm), | ||||
|             ) | ||||
|             return | ||||
|  | ||||
|         if not self._permissions.is_member_moderator(ctx.author) and not self._realm_utils.is_realm_moderator( | ||||
|             ctx.author.id, realm.id | ||||
|         ): | ||||
|             await self._message_service.send_ctx_msg( | ||||
|                 ctx, | ||||
|                 self._t.transform("modules.realm.error.not_moderator").format(realm.name), | ||||
|             ) | ||||
|             return | ||||
|  | ||||
|         role = self._realm_utils.find_role_by_name(ctx.guild, realm.name) | ||||
|         if role is None: | ||||
|             await self._message_service.send_ctx_msg( | ||||
|                 ctx, | ||||
|                 self._t.transform("modules.realm.add.error.role_not_found").format(realm.name), | ||||
|             ) | ||||
|             return | ||||
|  | ||||
|         await member.add_roles(role) | ||||
|         await self._message_service.send_ctx_msg( | ||||
|             ctx, | ||||
|             self._t.transform("modules.realm.member.add.success").format(member.name, realm.name), | ||||
|         ) | ||||
|  | ||||
|         self._logger.trace(__name__, f"Finished realm list command") | ||||
|  | ||||
|     @member_add.autocomplete("realm") | ||||
|     async def add_autocomplete(self, interaction: discord.Interaction, current: str) -> TList[app_commands.Choice[str]]: | ||||
|         return await self._auto_realm_complete(interaction, current) | ||||
|  | ||||
|     @member.command("remove") | ||||
|     @commands.guild_only() | ||||
|     @CommandChecks.check_is_ready() | ||||
|     async def member_remove(self, ctx: Context, realm: str, member: Member): | ||||
|         self._logger.debug(__name__, f"Received command realm member remove {ctx}") | ||||
|  | ||||
|         realm = self._realms.find_realm_by_name(realm) | ||||
|         if realm is None: | ||||
|             await self._message_service.send_ctx_msg( | ||||
|                 ctx, | ||||
|                 self._t.transform("modules.realm.add.error.realm_not_found").format(realm), | ||||
|             ) | ||||
|             return | ||||
|  | ||||
|         if not self._permissions.is_member_moderator(ctx.author) and not self._realm_utils.is_realm_moderator( | ||||
|             ctx.author.id, realm.id | ||||
|         ): | ||||
|             await self._message_service.send_ctx_msg( | ||||
|                 ctx, | ||||
|                 self._t.transform("modules.realm.error.not_moderator").format(realm.name), | ||||
|             ) | ||||
|             return | ||||
|  | ||||
|         role = self._realm_utils.find_role_by_name(ctx.guild, realm.name) | ||||
|         if role is None: | ||||
|             await self._message_service.send_ctx_msg( | ||||
|                 ctx, | ||||
|                 self._t.transform("modules.realm.add.error.role_not_found").format(realm.name), | ||||
|             ) | ||||
|             return | ||||
|  | ||||
|         await member.remove_roles(role) | ||||
|         await self._message_service.send_ctx_msg( | ||||
|             ctx, | ||||
|             self._t.transform("modules.realm.member.remove.success").format(member.name, realm.name), | ||||
|         ) | ||||
|  | ||||
|         self._logger.trace(__name__, f"Finished realm remove command") | ||||
|  | ||||
|     @member_remove.autocomplete("realm") | ||||
|     async def remove_autocomplete( | ||||
|         self, interaction: discord.Interaction, current: str | ||||
|     ) -> TList[app_commands.Choice[str]]: | ||||
|         return await self._auto_realm_complete(interaction, current) | ||||
|  | ||||
|     @realm.group(name="moderator") | ||||
|     @commands.guild_only() | ||||
|     async def moderator(self, ctx: Context): | ||||
|         pass | ||||
|  | ||||
|     @moderator.command("add") | ||||
|     @commands.guild_only() | ||||
|     @CommandChecks.check_is_ready() | ||||
|     async def moderator_add(self, ctx: Context, realm: str, moderator: Member): | ||||
|         self._logger.debug(__name__, f"Received command realm moderator add {ctx}") | ||||
|  | ||||
|         realm = self._realms.find_realm_by_name(realm) | ||||
|         if realm is None: | ||||
|             await self._message_service.send_ctx_msg( | ||||
|                 ctx, | ||||
|                 self._t.transform("modules.realm.add.error.realm_not_found").format(realm), | ||||
|             ) | ||||
|             return | ||||
|  | ||||
|         if not self._permissions.is_member_moderator(ctx.author) and not self._realm_utils.is_realm_moderator(ctx.author.id, realm.id): | ||||
|             await self._message_service.send_ctx_msg( | ||||
|                 ctx, | ||||
|                 self._t.transform("modules.realm.error.not_moderator").format(realm.name), | ||||
|             ) | ||||
|             return | ||||
|  | ||||
|         role = self._realm_utils.find_role_by_name(ctx.guild, realm.name) | ||||
|         if role is None: | ||||
|             await self._message_service.send_ctx_msg( | ||||
|                 ctx, | ||||
|                 self._t.transform("modules.realm.add.error.role_not_found").format(realm.name), | ||||
|             ) | ||||
|             return | ||||
|  | ||||
|         category = self._realm_utils.find_category_by_name(ctx.guild, realm.name) | ||||
|         await self._realm_utils.assign_moderator(category, moderator) | ||||
|         await self._message_service.send_ctx_msg( | ||||
|             ctx, | ||||
|             self._t.transform("modules.realm.moderator.add.success").format(moderator.name, realm.name), | ||||
|         ) | ||||
|  | ||||
|         self._logger.trace(__name__, f"Finished realm list command") | ||||
|  | ||||
|     @moderator_add.autocomplete("realm") | ||||
|     async def add_autocomplete(self, interaction: discord.Interaction, current: str) -> TList[app_commands.Choice[str]]: | ||||
|         return await self._auto_realm_complete(interaction, current) | ||||
|  | ||||
|     @moderator.command("remove") | ||||
|     @commands.guild_only() | ||||
|     @CommandChecks.check_is_ready() | ||||
|     async def moderator_remove(self, ctx: Context, realm: str, moderator: Member): | ||||
|         self._logger.debug(__name__, f"Received command realm moderator remove {ctx}") | ||||
|  | ||||
|         realm = self._realms.find_realm_by_name(realm) | ||||
|         if realm is None: | ||||
|             await self._message_service.send_ctx_msg( | ||||
|                 ctx, | ||||
|                 self._t.transform("modules.realm.add.error.realm_not_found").format(realm), | ||||
|             ) | ||||
|             return | ||||
|  | ||||
|         if not self._permissions.is_member_moderator(ctx.author) and not self._realm_utils.is_realm_moderator(ctx.author.id, realm.id): | ||||
|             await self._message_service.send_ctx_msg( | ||||
|                 ctx, | ||||
|                 self._t.transform("modules.realm.error.not_moderator").format(realm.name), | ||||
|             ) | ||||
|             return | ||||
|  | ||||
|         role = self._realm_utils.find_role_by_name(ctx.guild, realm.name) | ||||
|         if role is None: | ||||
|             await self._message_service.send_ctx_msg( | ||||
|                 ctx, | ||||
|                 self._t.transform("modules.realm.add.error.role_not_found").format(realm.name), | ||||
|             ) | ||||
|             return | ||||
|  | ||||
|         category = self._realm_utils.find_category_by_name(ctx.guild, realm.name) | ||||
|         if category is None: | ||||
|             await self._message_service.send_ctx_msg( | ||||
|                 ctx, | ||||
|                 self._t.transform("modules.realm.add.error.category_not_found").format(realm.name), | ||||
|             ) | ||||
|             return | ||||
|  | ||||
|         await self._realm_utils.remove_moderator(category, moderator) | ||||
|         await self._message_service.send_ctx_msg( | ||||
|             ctx, | ||||
|             self._t.transform("modules.realm.moderator.remove.success").format(moderator.name, realm.name), | ||||
|         ) | ||||
|  | ||||
|         self._logger.trace(__name__, f"Finished realm remove command") | ||||
|  | ||||
|     @moderator_remove.autocomplete("realm") | ||||
|     async def remove_autocomplete( | ||||
|         self, interaction: discord.Interaction, current: str | ||||
|     ) -> TList[app_commands.Choice[str]]: | ||||
|         return await self._auto_realm_complete(interaction, current) | ||||
							
								
								
									
										79
									
								
								bot/src/modules/realms/realm_utils.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								bot/src/modules/realms/realm_utils.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,79 @@ | ||||
| from typing import Optional | ||||
|  | ||||
| import discord | ||||
| from cpl_discord.container import Role, CategoryChannel | ||||
| from discord import Guild, Member | ||||
|  | ||||
| from bot_data.abc.realm_repository_abc import RealmRepositoryABC | ||||
|  | ||||
|  | ||||
| class RealmUtils: | ||||
|     def __init__(self, realms: RealmRepositoryABC): | ||||
|         self._realms = realms | ||||
|  | ||||
|     @staticmethod | ||||
|     def find_role_by_name(guild: Guild, name: str) -> Optional[Role]: | ||||
|         for role in guild.roles: | ||||
|             if role.name == name: | ||||
|                 return Role(role) | ||||
|         return None | ||||
|  | ||||
|     @staticmethod | ||||
|     def find_category_by_name(guild: Guild, name: str) -> Optional[CategoryChannel]: | ||||
|         for category in guild.categories: | ||||
|             if category.name == name: | ||||
|                 return CategoryChannel(category) | ||||
|         return None | ||||
|  | ||||
|     @staticmethod | ||||
|     def check_realm_role(guild: Guild, role: Role) -> bool: | ||||
|         return role in guild.roles | ||||
|  | ||||
|     @staticmethod | ||||
|     async def create_category(guild: Guild, name: str, role: Role, leader: Optional[Member]) -> CategoryChannel: | ||||
|         overwrites = { | ||||
|             guild.default_role: discord.PermissionOverwrite(view_channel=False, connect=False), | ||||
|             role: discord.PermissionOverwrite(view_channel=True, connect=True), | ||||
|         } | ||||
|         if leader is not None: | ||||
|             overwrites[leader] = discord.PermissionOverwrite( | ||||
|                 view_channel=True, | ||||
|                 connect=True, | ||||
|                 manage_channels=True, | ||||
|                 manage_permissions=True, | ||||
|                 create_instant_invite=True, | ||||
|             ) | ||||
|  | ||||
|             if leader.get_role(role.id) is None: | ||||
|                 await leader.add_roles(role) | ||||
|  | ||||
|         return await guild.create_category(name, overwrites=overwrites) | ||||
|  | ||||
|     @staticmethod | ||||
|     async def assign_moderator(category: CategoryChannel, member: Member): | ||||
|         await category.set_permissions( | ||||
|             member, | ||||
|             view_channel=True, | ||||
|             connect=True, | ||||
|             manage_channels=True, | ||||
|             manage_permissions=True, | ||||
|             create_instant_invite=True, | ||||
|         ) | ||||
|  | ||||
|     @staticmethod | ||||
|     async def remove_moderator(category: CategoryChannel, member: Member): | ||||
|         await category.set_permissions( | ||||
|             member, | ||||
|             view_channel=True, | ||||
|             connect=True, | ||||
|             manage_channels=False, | ||||
|             manage_permissions=False, | ||||
|             create_instant_invite=False, | ||||
|         ) | ||||
|  | ||||
|     def is_realm_moderator(self, member_id: int, realm_id: int) -> bool: | ||||
|         return ( | ||||
|             self._realms.get_realm_moderators_by_realm_id(realm_id) | ||||
|             .select(lambda x: x.user.discord_id) | ||||
|             .contains(member_id) | ||||
|         ) | ||||
							
								
								
									
										44
									
								
								bot/src/modules/realms/reams.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								bot/src/modules/realms/reams.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| { | ||||
|   "ProjectSettings": { | ||||
|     "Name": "private-categories", | ||||
|     "Version": { | ||||
|       "Major": "1", | ||||
|       "Minor": "2", | ||||
|       "Micro": "8" | ||||
|     }, | ||||
|     "Author": "", | ||||
|     "AuthorEmail": "", | ||||
|     "Description": "", | ||||
|     "LongDescription": "", | ||||
|     "URL": "", | ||||
|     "CopyrightDate": "", | ||||
|     "CopyrightName": "", | ||||
|     "LicenseName": "", | ||||
|     "LicenseDescription": "", | ||||
|     "Dependencies": [ | ||||
|       "cpl-core==2022.12.0" | ||||
|     ], | ||||
|     "DevDependencies": [ | ||||
|       "cpl-cli==2022.12.0" | ||||
|     ], | ||||
|     "PythonVersion": ">=3.10.6", | ||||
|     "PythonPath": {}, | ||||
|     "Classifiers": [] | ||||
|   }, | ||||
|   "BuildSettings": { | ||||
|     "ProjectType": "library", | ||||
|     "SourcePath": "", | ||||
|     "OutputPath": "../../dist", | ||||
|     "Main": "private_categories.main", | ||||
|     "EntryPoint": "private_categories", | ||||
|     "IncludePackageData": false, | ||||
|     "Included": [], | ||||
|     "Excluded": [ | ||||
|       "*/__pycache__", | ||||
|       "*/logs", | ||||
|       "*/tests" | ||||
|     ], | ||||
|     "PackageData": {}, | ||||
|     "ProjectReferences": [] | ||||
|   } | ||||
| } | ||||
							
								
								
									
										21
									
								
								bot/src/modules/realms/reams_module.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								bot/src/modules/realms/reams_module.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| from cpl_core.configuration import ConfigurationABC | ||||
| from cpl_core.dependency_injection import ServiceCollectionABC | ||||
| from cpl_core.environment import ApplicationEnvironmentABC | ||||
| from cpl_discord.service.discord_collection_abc import DiscordCollectionABC | ||||
|  | ||||
| from bot_core.abc.module_abc import ModuleABC | ||||
| from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum | ||||
| from modules.realms.command.realm_group import RealmGroup | ||||
| from modules.realms.realm_utils import RealmUtils | ||||
|  | ||||
|  | ||||
| class RealmsModule(ModuleABC): | ||||
|     def __init__(self, dc: DiscordCollectionABC): | ||||
|         ModuleABC.__init__(self, dc, FeatureFlagsEnum.realm_module) | ||||
|  | ||||
|     def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC): | ||||
|         pass | ||||
|  | ||||
|     def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC): | ||||
|         services.add_transient(RealmGroup) | ||||
|         services.add_transient(RealmUtils) | ||||
		Reference in New Issue
	
	Block a user