1.0.0 #253
 Submodule kdb-bot/src/bot/config updated: ac7046820f...84d05a9c78
									
								
							| @@ -1,7 +1,10 @@ | ||||
| from datetime import datetime | ||||
| from typing import Optional | ||||
|  | ||||
| from cpl_query.extension import List | ||||
|  | ||||
| from bot_api.abc.dto_abc import DtoABC | ||||
| from bot_api.model.user_dto import UserDTO | ||||
| from bot_data.model.auth_role_enum import AuthRoleEnum | ||||
|  | ||||
|  | ||||
| @@ -15,6 +18,7 @@ class AuthUserDTO(DtoABC): | ||||
|         password: str = None, | ||||
|         confirmation_id: Optional[str] = None, | ||||
|         auth_role: AuthRoleEnum = None, | ||||
|         users: List[UserDTO] = None, | ||||
|         created_at: datetime = None, | ||||
|         modified_at: datetime = None, | ||||
|     ): | ||||
| @@ -30,6 +34,11 @@ class AuthUserDTO(DtoABC): | ||||
|         self._created_at = created_at | ||||
|         self._modified_at = modified_at | ||||
|  | ||||
|         if users is None: | ||||
|             self._users = List(UserDTO) | ||||
|         else: | ||||
|             self._users = users | ||||
|  | ||||
|     @property | ||||
|     def id(self) -> int: | ||||
|         return self._id | ||||
| @@ -82,6 +91,10 @@ class AuthUserDTO(DtoABC): | ||||
|     def auth_role(self, value: AuthRoleEnum): | ||||
|         self._auth_role = value | ||||
|  | ||||
|     @property | ||||
|     def users(self) -> List[UserDTO]: | ||||
|         return self._users | ||||
|  | ||||
|     @property | ||||
|     def created_at(self) -> datetime: | ||||
|         return self._created_at | ||||
| @@ -98,6 +111,12 @@ class AuthUserDTO(DtoABC): | ||||
|         self._password = values["password"] | ||||
|         self._is_confirmed = values["isConfirmed"] | ||||
|         self._auth_role = AuthRoleEnum(values["authRole"]) | ||||
|         if "users" in values: | ||||
|             self._users = List(UserDTO) | ||||
|             for u in values["users"]: | ||||
|                 user = UserDTO() | ||||
|                 user.from_dict(u) | ||||
|                 self._users.add(user) | ||||
|  | ||||
|         self._created_at = values["createdAt"] | ||||
|         self._modified_at = values["modifiedAt"] | ||||
| @@ -111,6 +130,7 @@ class AuthUserDTO(DtoABC): | ||||
|             "password": self._password, | ||||
|             "isConfirmed": self._is_confirmed, | ||||
|             "authRole": self._auth_role.value, | ||||
|             "users": self._users.select(lambda u: u.to_dict()).to_list(), | ||||
|             "createdAt": self._created_at, | ||||
|             "modifiedAt": self._modified_at, | ||||
|         } | ||||
|   | ||||
							
								
								
									
										88
									
								
								kdb-bot/src/bot_api/model/user_dto.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								kdb-bot/src/bot_api/model/user_dto.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,88 @@ | ||||
| from typing import Optional | ||||
|  | ||||
| from bot_api.abc.dto_abc import DtoABC | ||||
| from bot_data.model.server import Server | ||||
|  | ||||
|  | ||||
| class UserDTO(DtoABC): | ||||
|     def __init__( | ||||
|         self, | ||||
|         id: int = None, | ||||
|         dc_id: int = None, | ||||
|         xp: int = None, | ||||
|         minecraft_id: Optional[str] = None, | ||||
|         server: Optional[Server] = None, | ||||
|         is_technician: Optional[bool] = None, | ||||
|         is_admin: Optional[bool] = None, | ||||
|         is_moderator: Optional[bool] = None, | ||||
|     ): | ||||
|         DtoABC.__init__(self) | ||||
|  | ||||
|         self._user_id = id | ||||
|         self._discord_id = dc_id | ||||
|         self._xp = xp | ||||
|         self._minecraft_id = minecraft_id | ||||
|         self._server = server | ||||
|  | ||||
|         self._is_technician = is_technician | ||||
|         self._is_admin = is_admin | ||||
|         self._is_moderator = is_moderator | ||||
|  | ||||
|     @property | ||||
|     def user_id(self) -> int: | ||||
|         return self._user_id | ||||
|  | ||||
|     @property | ||||
|     def discord_id(self) -> int: | ||||
|         return self._discord_id | ||||
|  | ||||
|     @property | ||||
|     def xp(self) -> int: | ||||
|         return self._xp | ||||
|  | ||||
|     @xp.setter | ||||
|     def xp(self, value: int): | ||||
|         self._xp = value | ||||
|  | ||||
|     @property | ||||
|     def minecraft_id(self) -> Optional[str]: | ||||
|         return self._minecraft_id | ||||
|  | ||||
|     @minecraft_id.setter | ||||
|     def minecraft_id(self, value: str): | ||||
|         self._minecraft_id = value | ||||
|  | ||||
|     @property | ||||
|     def server(self) -> Optional[Server]: | ||||
|         return self._server | ||||
|  | ||||
|     @property | ||||
|     def is_technician(self) -> bool: | ||||
|         return self._is_technician if self._is_technician is not None else False | ||||
|  | ||||
|     @property | ||||
|     def is_admin(self) -> bool: | ||||
|         return self._is_admin if self._is_admin is not None else False | ||||
|  | ||||
|     @property | ||||
|     def is_moderator(self) -> bool: | ||||
|         return self._is_moderator if self._is_moderator is not None else False | ||||
|  | ||||
|     def from_dict(self, values: dict): | ||||
|         self._user_id = values["id"] | ||||
|         self._discord_id = values["dcId"] | ||||
|         self._xp = values["xp"] | ||||
|         self._minecraft_id = values["minecraftId"] | ||||
|         self._server = values["server"] | ||||
|  | ||||
|     def to_dict(self) -> dict: | ||||
|         return { | ||||
|             "id": self._user_id, | ||||
|             "dcId": self._discord_id, | ||||
|             "xp": self._xp, | ||||
|             "minecraftId": self._minecraft_id, | ||||
|             "server": self._server.id, | ||||
|             "isTechnician": self.is_technician, | ||||
|             "isAdmin": self.is_admin, | ||||
|             "isModerator": self.is_moderator, | ||||
|         } | ||||
| @@ -2,7 +2,6 @@ from typing import Optional | ||||
|  | ||||
| from cpl_discord.service import DiscordBotServiceABC | ||||
| from cpl_query.extension import List | ||||
| from flask import jsonify | ||||
|  | ||||
| from bot_api.abc.auth_service_abc import AuthServiceABC | ||||
| from bot_api.exception.service_error_code_enum import ServiceErrorCode | ||||
| @@ -10,7 +9,6 @@ from bot_api.exception.service_exception import ServiceException | ||||
| from bot_api.filter.discord.server_select_criteria import ServerSelectCriteria | ||||
| from bot_api.model.discord.server_dto import ServerDTO | ||||
| from bot_api.model.discord.server_filtered_result_dto import ServerFilteredResultDTO | ||||
| from bot_api.model.error_dto import ErrorDTO | ||||
| from bot_api.transformer.server_transformer import ServerTransformer | ||||
| from bot_data.abc.auth_user_repository_abc import AuthUserRepositoryABC | ||||
| from bot_data.abc.server_repository_abc import ServerRepositoryABC | ||||
| @@ -35,7 +33,7 @@ class DiscordService: | ||||
|         self._users = users | ||||
|  | ||||
|     def _to_dto(self, x: Server) -> Optional[ServerDTO]: | ||||
|         guild = self._bot.get_guild(x.discord_server_id) | ||||
|         guild = self._bot.get_guild(x.discord_id) | ||||
|         if guild is None: | ||||
|             return ServerTransformer.to_dto(x, "", 0, None) | ||||
|  | ||||
| @@ -55,8 +53,8 @@ class DiscordService: | ||||
|         if role != AuthRoleEnum.admin: | ||||
|             auth_user = self._auth_users.find_auth_user_by_email(token["email"]) | ||||
|             if auth_user is not None: | ||||
|                 user_ids = auth_user.users.select(lambda x: x.server is not None and x.server.server_id) | ||||
|                 servers = servers.where(lambda x: x.server_id in user_ids) | ||||
|                 user_ids = auth_user.users.select(lambda x: x.server is not None and x.server.id) | ||||
|                 servers = servers.where(lambda x: x.id in user_ids) | ||||
|  | ||||
|         servers = List(ServerDTO, servers) | ||||
|         return servers.select(self._to_dto).where(lambda x: x.name != "") | ||||
| @@ -72,8 +70,8 @@ class DiscordService: | ||||
|         if role != AuthRoleEnum.admin: | ||||
|             auth_user = self._auth_users.find_auth_user_by_email(token["email"]) | ||||
|             if auth_user is not None: | ||||
|                 user_ids = auth_user.users.select(lambda x: x.server is not None and x.server.server_id) | ||||
|                 filtered_result.result = filtered_result.result.where(lambda x: x.server_id in user_ids) | ||||
|                 user_ids = auth_user.users.select(lambda x: x.server is not None and x.server.id) | ||||
|                 filtered_result.result = filtered_result.result.where(lambda x: x.id in user_ids) | ||||
|  | ||||
|         servers: List = filtered_result.result.select(self._to_dto).where(lambda x: x.name != "") | ||||
|         result = List(ServerDTO, servers) | ||||
| @@ -87,7 +85,7 @@ class DiscordService: | ||||
|  | ||||
|     async def get_server_by_id_async(self, id: int) -> ServerDTO: | ||||
|         server = self._servers.get_server_by_id(id) | ||||
|         guild = self._bot.get_guild(server.discord_server_id) | ||||
|         guild = self._bot.get_guild(server.discord_id) | ||||
|  | ||||
|         server_dto = ServerTransformer.to_dto(server, guild.name, guild.member_count, guild.icon) | ||||
|         return server_dto | ||||
|   | ||||
| @@ -1,9 +1,16 @@ | ||||
| from datetime import datetime | ||||
|  | ||||
| from cpl_core.dependency_injection import ServiceProviderABC | ||||
| from cpl_discord.service import DiscordBotServiceABC | ||||
| from cpl_query.extension import List | ||||
|  | ||||
| from bot_api.abc.transformer_abc import TransformerABC | ||||
| from bot_api.model.auth_user_dto import AuthUserDTO | ||||
| from bot_api.model.user_dto import UserDTO | ||||
| from bot_data.model.auth_role_enum import AuthRoleEnum | ||||
| from bot_data.model.auth_user import AuthUser | ||||
| from bot_data.model.user import User | ||||
| from modules.permission.abc.permission_service_abc import PermissionServiceABC | ||||
|  | ||||
|  | ||||
| class AuthUserTransformer(TransformerABC): | ||||
| @@ -25,7 +32,28 @@ class AuthUserTransformer(TransformerABC): | ||||
|         ) | ||||
|  | ||||
|     @staticmethod | ||||
|     def to_dto(db: AuthUser, password: str = None) -> AuthUserDTO: | ||||
|     @ServiceProviderABC.inject | ||||
|     def _is_technician(user: User, bot: DiscordBotServiceABC, permissions: PermissionServiceABC): | ||||
|         guild = bot.get_guild(user.server.discord_id) | ||||
|         member = guild.get_member(user.discord_id) | ||||
|         return permissions.is_member_technician(member) | ||||
|  | ||||
|     @staticmethod | ||||
|     @ServiceProviderABC.inject | ||||
|     def _is_admin(user: User, bot: DiscordBotServiceABC, permissions: PermissionServiceABC): | ||||
|         guild = bot.get_guild(user.server.discord_id) | ||||
|         member = guild.get_member(user.discord_id) | ||||
|         return permissions.is_member_technician(member) | ||||
|  | ||||
|     @staticmethod | ||||
|     @ServiceProviderABC.inject | ||||
|     def _is_moderator(user: User, bot: DiscordBotServiceABC, permissions: PermissionServiceABC): | ||||
|         guild = bot.get_guild(user.server.discord_id) | ||||
|         member = guild.get_member(user.discord_id) | ||||
|         return permissions.is_member_technician(member) | ||||
|  | ||||
|     @classmethod | ||||
|     def to_dto(cls, db: AuthUser, password: str = None) -> AuthUserDTO: | ||||
|         return AuthUserDTO( | ||||
|             db.id, | ||||
|             db.first_name, | ||||
| @@ -34,6 +62,21 @@ class AuthUserTransformer(TransformerABC): | ||||
|             "" if password is None else password, | ||||
|             db.confirmation_id, | ||||
|             db.auth_role, | ||||
|             List( | ||||
|                 UserDTO, | ||||
|                 db.users.select( | ||||
|                     lambda u: UserDTO( | ||||
|                         u.id, | ||||
|                         u.discord_id, | ||||
|                         u.xp, | ||||
|                         u.minecraft_id, | ||||
|                         u.server, | ||||
|                         cls._is_technician(u), | ||||
|                         cls._is_admin(u), | ||||
|                         cls._is_moderator(u), | ||||
|                     ) | ||||
|                 ), | ||||
|             ), | ||||
|             db.created_at, | ||||
|             db.modified_at, | ||||
|         ) | ||||
|   | ||||
| @@ -15,8 +15,8 @@ class ServerTransformer(TransformerABC): | ||||
|     @staticmethod | ||||
|     def to_dto(db: Server, name: str, member_count: int, icon_url: Optional[discord.Asset]) -> ServerDTO: | ||||
|         return ServerDTO( | ||||
|             db.server_id, | ||||
|             db.discord_server_id, | ||||
|             db.id, | ||||
|             db.discord_id, | ||||
|             name, | ||||
|             member_count, | ||||
|             icon_url.url if icon_url is not None else None, | ||||
|   | ||||
| @@ -60,28 +60,28 @@ class ClientUtilsService(ClientUtilsABC): | ||||
|  | ||||
|     def received_command(self, guild_id: int): | ||||
|         server = self._servers.get_server_by_discord_id(guild_id) | ||||
|         client = self._clients.find_client_by_discord_id_and_server_id(self._bot.user.id, server.server_id) | ||||
|         client = self._clients.find_client_by_discord_id_and_server_id(self._bot.user.id, server.id) | ||||
|         client.received_command_count += 1 | ||||
|         self._clients.update_client(client) | ||||
|         self._db.save_changes() | ||||
|  | ||||
|     def moved_user(self, guild_id: int): | ||||
|         server = self._servers.get_server_by_discord_id(guild_id) | ||||
|         client = self._clients.find_client_by_discord_id_and_server_id(self._bot.user.id, server.server_id) | ||||
|         client = self._clients.find_client_by_discord_id_and_server_id(self._bot.user.id, server.id) | ||||
|         client.moved_users_count += 1 | ||||
|         self._clients.update_client(client) | ||||
|         self._db.save_changes() | ||||
|  | ||||
|     def moved_users(self, guild_id: int, count: int): | ||||
|         server = self._servers.get_server_by_discord_id(guild_id) | ||||
|         client = self._clients.find_client_by_discord_id_and_server_id(self._bot.user.id, server.server_id) | ||||
|         client = self._clients.find_client_by_discord_id_and_server_id(self._bot.user.id, server.id) | ||||
|         client.moved_users_count += count | ||||
|         self._clients.update_client(client) | ||||
|         self._db.save_changes() | ||||
|  | ||||
|     def get_client(self, dc_ic: int, guild_id: int): | ||||
|         server = self._servers.get_server_by_discord_id(guild_id) | ||||
|         client = self._clients.find_client_by_discord_id_and_server_id(self._bot.user.id, server.server_id) | ||||
|         client = self._clients.find_client_by_discord_id_and_server_id(self._bot.user.id, server.id) | ||||
|         return client | ||||
|  | ||||
|     async def check_if_bot_is_ready_yet(self) -> bool: | ||||
| @@ -138,7 +138,7 @@ class ClientUtilsService(ClientUtilsABC): | ||||
|     ) -> bool: | ||||
|         umcph = None | ||||
|         try: | ||||
|             umcph = self._umcphs.find_user_message_count_per_hour_by_user_id_and_date(user.user_id, created_at) | ||||
|             umcph = self._umcphs.find_user_message_count_per_hour_by_user_id_and_date(user.id, created_at) | ||||
|             if umcph is None: | ||||
|                 self._umcphs.add_user_message_count_per_hour( | ||||
|                     UserMessageCountPerHour( | ||||
| @@ -151,7 +151,7 @@ class ClientUtilsService(ClientUtilsABC): | ||||
|  | ||||
|                 self._db.save_changes() | ||||
|  | ||||
|                 umcph = self._umcphs.get_user_message_count_per_hour_by_user_id_and_date(user.user_id, created_at) | ||||
|                 umcph = self._umcphs.get_user_message_count_per_hour_by_user_id_and_date(user.id, created_at) | ||||
|         except Exception as e: | ||||
|             self._logger.error( | ||||
|                 __name__, | ||||
| @@ -183,7 +183,7 @@ class ClientUtilsService(ClientUtilsABC): | ||||
|  | ||||
|     def get_ontime_for_user(self, user: User) -> float: | ||||
|         return round( | ||||
|             self._user_joined_voice_channel.get_user_joined_voice_channels_by_user_id(user.user_id) | ||||
|             self._user_joined_voice_channel.get_user_joined_voice_channels_by_user_id(user.id) | ||||
|             .where(lambda x: x.leaved_on is not None and x.joined_on is not None) | ||||
|             .sum(lambda join: (join.leaved_on - join.joined_on).total_seconds() / 3600), | ||||
|             2, | ||||
|   | ||||
| @@ -73,7 +73,7 @@ class ApiKey(TableABC): | ||||
|             ) VALUES ( | ||||
|                 '{self._identifier}', | ||||
|                 '{self._key}', | ||||
|                 {"NULL" if self._creator is None else self._creator.user_id}, | ||||
|                 {"NULL" if self._creator is None else self._creator.id}, | ||||
|                 '{self._created_at}', | ||||
|                 '{self._modified_at}' | ||||
|             ); | ||||
|   | ||||
| @@ -42,6 +42,8 @@ class AuthUser(TableABC): | ||||
|  | ||||
|         if users is None: | ||||
|             self._users = List(User) | ||||
|         else: | ||||
|             self._users = users | ||||
|  | ||||
|         self._auth_role_id = auth_role | ||||
|  | ||||
| @@ -250,10 +252,10 @@ class AuthUser(TableABC): | ||||
|             `EMail` = '{self._email}',  | ||||
|             `Password` = '{self._password}',  | ||||
|             `PasswordSalt` = '{self._password_salt}',  | ||||
|             `RefreshToken` = '{"NULL" if self._refresh_token is None else self._refresh_token}',  | ||||
|             `ConfirmationId` = '{"NULL" if self._confirmation_id is None else self._confirmation_id}',  | ||||
|             `ForgotPasswordId` = '{"NULL" if self._forgot_password_id is None else self._forgot_password_id}', | ||||
|             `OAuthId` = '{"NULL" if self._oauth_id is None else self._oauth_id}', | ||||
|             `RefreshToken` = '{'null' if self._refresh_token is None else f'{self._refresh_token}'}',  | ||||
|             `ConfirmationId` = '{'null' if self._confirmation_id is None else f'{self._confirmation_id}'}',  | ||||
|             `ForgotPasswordId` = '{'null' if self._forgot_password_id is None else f'{self._forgot_password_id}'}', | ||||
|             `OAuthId` = '{'null' if self._oauth_id is None else f'{self._oauth_id}'}', | ||||
|             `RefreshTokenExpiryTime` = '{self._refresh_token_expire_time.isoformat()}', | ||||
|             `AuthRole` = {self._auth_role_id.value}, | ||||
|             `LastModifiedAt` = '{self._modified_at}' | ||||
|   | ||||
| @@ -71,7 +71,7 @@ class AuthUserUsersRelation(TableABC): | ||||
|                 `AuthUserId`, `UserId`, `CreatedAt`, `LastModifiedAt` | ||||
|             ) VALUES ( | ||||
|                 {self._auth_user.id}, | ||||
|                 {self._user.user_id}, | ||||
|                 {self._user.id}, | ||||
|                 '{self._created_at}', | ||||
|                 '{self._modified_at}' | ||||
|             ); | ||||
| @@ -84,10 +84,10 @@ class AuthUserUsersRelation(TableABC): | ||||
|             f""" | ||||
|             UPDATE `AuthUserUsersRelations` | ||||
|             SET `AuthUserId` = '{self._auth_user.id}',, | ||||
|             `UserId` = '{self._user.user_id}' | ||||
|             `UserId` = '{self._user.id}' | ||||
|             `LastModifiedAt` = '{self._modified_at}' | ||||
|             WHERE `AuthUserId` = {self._auth_user.id} | ||||
|             AND `UserId` = {self._user.user_id}; | ||||
|             AND `UserId` = {self._user.id}; | ||||
|         """ | ||||
|         ) | ||||
|  | ||||
| @@ -97,6 +97,6 @@ class AuthUserUsersRelation(TableABC): | ||||
|             f""" | ||||
|             DELETE FROM `AuthUserUsersRelations` | ||||
|             WHERE `AuthUserId` = {self._auth_user.id} | ||||
|             AND `UserId` = {self._user.user_id}; | ||||
|             AND `UserId` = {self._user.id}; | ||||
|         """ | ||||
|         ) | ||||
|   | ||||
| @@ -2,6 +2,8 @@ from datetime import datetime | ||||
| from typing import Optional | ||||
|  | ||||
| from cpl_core.database import TableABC | ||||
| from cpl_core.dependency_injection import ServiceProviderABC | ||||
| from cpl_discord.service import DiscordBotServiceABC | ||||
|  | ||||
| from bot_data.model.server import Server | ||||
|  | ||||
| @@ -10,7 +12,7 @@ class AutoRole(TableABC): | ||||
|     def __init__( | ||||
|         self, | ||||
|         server: Optional[Server], | ||||
|         dc_channel_id: int, | ||||
|         channel_id: int, | ||||
|         dc_message_id: int, | ||||
|         created_at: datetime = None, | ||||
|         modified_at: datetime = None, | ||||
| @@ -18,7 +20,7 @@ class AutoRole(TableABC): | ||||
|     ): | ||||
|         self._auto_role_id = id | ||||
|         self._server = server | ||||
|         self._discord_channel_id = dc_channel_id | ||||
|         self._discord_channel_id = channel_id | ||||
|         self._discord_message_id = dc_message_id | ||||
|  | ||||
|         TableABC.__init__(self) | ||||
| @@ -26,7 +28,7 @@ class AutoRole(TableABC): | ||||
|         self._modified_at = modified_at if modified_at is not None else self._modified_at | ||||
|  | ||||
|     @property | ||||
|     def auto_role_id(self) -> int: | ||||
|     def id(self) -> int: | ||||
|         return self._auto_role_id | ||||
|  | ||||
|     @property | ||||
| @@ -41,6 +43,12 @@ class AutoRole(TableABC): | ||||
|     def discord_channel_id(self, value: int): | ||||
|         self._discord_channel_id = value | ||||
|  | ||||
|     @property | ||||
|     @ServiceProviderABC.inject | ||||
|     def discord_channel_name(self, bot: DiscordBotServiceABC) -> str: | ||||
|         channel = bot.get_channel(self.discord_channel_id) | ||||
|         return None if channel is None else channel.name | ||||
|  | ||||
|     @property | ||||
|     def discord_message_id(self) -> int: | ||||
|         return self._discord_message_id | ||||
| @@ -91,7 +99,7 @@ class AutoRole(TableABC): | ||||
|             INSERT INTO `AutoRoles` ( | ||||
|                 `ServerId`, `DiscordChannelId`, `DiscordMessageId`, `CreatedAt`, `LastModifiedAt` | ||||
|             ) VALUES ( | ||||
|                 {self._server.server_id}, | ||||
|                 {self._server.id}, | ||||
|                 {self._discord_channel_id}, | ||||
|                 {self._discord_message_id}, | ||||
|                 '{self._created_at}', | ||||
| @@ -105,7 +113,7 @@ class AutoRole(TableABC): | ||||
|         return str( | ||||
|             f""" | ||||
|             UPDATE `AutoRoles` | ||||
|             SET `ServerId` = {self._server.server_id}, | ||||
|             SET `ServerId` = {self._server.id}, | ||||
|             `DiscordChannelId` = {self._discord_channel_id}, | ||||
|             `DiscordMessageId` = {self._discord_message_id}, | ||||
|             `LastModifiedAt` = '{self._modified_at}' | ||||
|   | ||||
| @@ -1,6 +1,8 @@ | ||||
| from datetime import datetime | ||||
|  | ||||
| from cpl_core.database import TableABC | ||||
| from cpl_core.dependency_injection import ServiceProviderABC | ||||
| from cpl_discord.service import DiscordBotServiceABC | ||||
|  | ||||
| from bot_data.model.auto_role import AutoRole | ||||
|  | ||||
| @@ -25,7 +27,7 @@ class AutoRoleRule(TableABC): | ||||
|         self._modified_at = modified_at if modified_at is not None else self._modified_at | ||||
|  | ||||
|     @property | ||||
|     def auto_role_rule_id(self) -> int: | ||||
|     def id(self) -> int: | ||||
|         return self._auto_role_rule_id | ||||
|  | ||||
|     @property | ||||
| @@ -44,6 +46,12 @@ class AutoRoleRule(TableABC): | ||||
|     def role_id(self) -> int: | ||||
|         return self._discord_role_id | ||||
|  | ||||
|     @property | ||||
|     @ServiceProviderABC.inject | ||||
|     def role_name(self, bot: DiscordBotServiceABC) -> str: | ||||
|         guild = bot.get_guild(self.auto_role.server.discord_id) | ||||
|         return guild.get_role(self.role_id).name | ||||
|  | ||||
|     @role_id.setter | ||||
|     def role_id(self, value: int): | ||||
|         self._discord_role_id = value | ||||
|   | ||||
| @@ -1,5 +1,8 @@ | ||||
| from datetime import datetime | ||||
|  | ||||
| from cpl_core.database import TableABC | ||||
| from cpl_core.dependency_injection import ServiceProviderABC | ||||
| from cpl_discord.service import DiscordBotServiceABC | ||||
|  | ||||
| from bot_data.model.server import Server | ||||
|  | ||||
| @@ -32,13 +35,18 @@ class Client(TableABC): | ||||
|         self._modified_at = modified_at if modified_at is not None else self._modified_at | ||||
|  | ||||
|     @property | ||||
|     def client_id(self) -> int: | ||||
|     def id(self) -> int: | ||||
|         return self._client_id | ||||
|  | ||||
|     @property | ||||
|     def discord_id(self) -> int: | ||||
|         return self._discord_client_id | ||||
|  | ||||
|     @property | ||||
|     @ServiceProviderABC.inject | ||||
|     def name(self, bot: DiscordBotServiceABC) -> str: | ||||
|         return bot.user.name | ||||
|  | ||||
|     @property | ||||
|     def sent_message_count(self) -> int: | ||||
|         return self._sent_message_count | ||||
| @@ -154,7 +162,7 @@ class Client(TableABC): | ||||
|                 {self._deleted_message_count}, | ||||
|                 {self._received_message_count}, | ||||
|                 {self._moved_users_count}, | ||||
|                 {self._server.server_id}, | ||||
|                 {self._server.id}, | ||||
|                 '{self._created_at}', | ||||
|                 '{self._modified_at}' | ||||
|             ); | ||||
|   | ||||
| @@ -19,7 +19,7 @@ class KnownUser(TableABC): | ||||
|         self._modified_at = modified_at if modified_at is not None else self._modified_at | ||||
|  | ||||
|     @property | ||||
|     def known_user_id(self) -> int: | ||||
|     def id(self) -> int: | ||||
|         return self._known_user_id | ||||
|  | ||||
|     @property | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| from datetime import datetime | ||||
| from typing import Optional | ||||
|  | ||||
| from cpl_core.database import TableABC | ||||
|  | ||||
| from bot_data.model.server import Server | ||||
| @@ -114,7 +115,7 @@ class Level(TableABC): | ||||
|                 '{self._color}', | ||||
|                 {self._min_xp}, | ||||
|                 {self._permissions}, | ||||
|                 {self._server.server_id}, | ||||
|                 {self._server.id}, | ||||
|                 '{self._created_at}', | ||||
|                 '{self._modified_at}' | ||||
|             ); | ||||
|   | ||||
| @@ -1,7 +1,8 @@ | ||||
| from datetime import datetime | ||||
| from typing import Optional | ||||
|  | ||||
| from cpl_core.database import TableABC | ||||
| from cpl_core.dependency_injection import ServiceProviderABC | ||||
| from cpl_discord.service import DiscordBotServiceABC | ||||
|  | ||||
|  | ||||
| class Server(TableABC): | ||||
| @@ -20,13 +21,25 @@ class Server(TableABC): | ||||
|         self._modified_at = modified_at if modified_at is not None else self._modified_at | ||||
|  | ||||
|     @property | ||||
|     def server_id(self) -> int: | ||||
|     def id(self) -> int: | ||||
|         return self._server_id | ||||
|  | ||||
|     @property | ||||
|     def discord_server_id(self) -> int: | ||||
|     def discord_id(self) -> int: | ||||
|         return self._discord_server_id | ||||
|  | ||||
|     @property | ||||
|     @ServiceProviderABC.inject | ||||
|     def name(self, bot: DiscordBotServiceABC) -> str: | ||||
|         guild = bot.get_guild(self.discord_id) | ||||
|         return None if guild is None else guild.name | ||||
|  | ||||
|     @property | ||||
|     @ServiceProviderABC.inject | ||||
|     def icon_url(self, bot: DiscordBotServiceABC) -> str: | ||||
|         guild = bot.get_guild(self.discord_id) | ||||
|         return None if guild is None else guild.icon.url | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_select_all_string() -> str: | ||||
|         return str( | ||||
|   | ||||
| @@ -101,7 +101,7 @@ class Statistic(TableABC): | ||||
|                 '{self._name}', | ||||
|                 '{self._description}', | ||||
|                 '{self._code}', | ||||
|                 {self._server.server_id}, | ||||
|                 {self._server.id}, | ||||
|                 '{self._created_at}', | ||||
|                 '{self._modified_at}' | ||||
|             ); | ||||
|   | ||||
| @@ -2,7 +2,10 @@ from datetime import datetime | ||||
| from typing import Optional | ||||
|  | ||||
| from cpl_core.database import TableABC | ||||
| from cpl_core.dependency_injection import ServiceProviderABC | ||||
| from cpl_discord.service import DiscordBotServiceABC | ||||
|  | ||||
| from bot_data.model.level import Level | ||||
| from bot_data.model.server import Server | ||||
|  | ||||
|  | ||||
| @@ -28,13 +31,27 @@ class User(TableABC): | ||||
|         self._modified_at = modified_at if modified_at is not None else self._modified_at | ||||
|  | ||||
|     @property | ||||
|     def user_id(self) -> int: | ||||
|     def id(self) -> int: | ||||
|         return self._user_id | ||||
|  | ||||
|     @property | ||||
|     def discord_id(self) -> int: | ||||
|         return self._discord_id | ||||
|  | ||||
|     @property | ||||
|     @ServiceProviderABC.inject | ||||
|     def name(self, bot: DiscordBotServiceABC) -> str: | ||||
|         guild = bot.get_guild(self.server.discord_id) | ||||
|         user = guild.get_member(self.discord_id) | ||||
|         return None if user is None else user.name | ||||
|  | ||||
|     @property | ||||
|     @ServiceProviderABC.inject | ||||
|     def icon_url(self, bot: DiscordBotServiceABC) -> str: | ||||
|         guild = bot.get_guild(self.server.discord_id) | ||||
|         user = guild.get_member(self.discord_id) | ||||
|         return None if user is None else user.display_icon | ||||
|  | ||||
|     @property | ||||
|     def xp(self) -> int: | ||||
|         return self._xp | ||||
| @@ -44,6 +61,22 @@ class User(TableABC): | ||||
|         self._modified_at = datetime.now().isoformat() | ||||
|         self._xp = value | ||||
|  | ||||
|     @property | ||||
|     @ServiceProviderABC.inject | ||||
|     def ontime(self, services: ServiceProviderABC) -> float: | ||||
|         from bot_core.abc.client_utils_abc import ClientUtilsABC | ||||
|  | ||||
|         client_utils: ClientUtilsABC = services.get_service(ClientUtilsABC) | ||||
|         return client_utils.get_ontime_for_user(self) | ||||
|  | ||||
|     @property | ||||
|     @ServiceProviderABC.inject | ||||
|     def level(self, services: ServiceProviderABC) -> Level: | ||||
|         from modules.level.service.level_service import LevelService | ||||
|  | ||||
|         levels: LevelService = services.get_service(LevelService) | ||||
|         return levels.get_level(self) | ||||
|  | ||||
|     @property | ||||
|     def minecraft_id(self) -> Optional[str]: | ||||
|         return self._minecraft_id | ||||
| @@ -56,6 +89,17 @@ class User(TableABC): | ||||
|     def server(self) -> Optional[Server]: | ||||
|         return self._server | ||||
|  | ||||
|     @property | ||||
|     @ServiceProviderABC.inject | ||||
|     def left_server( | ||||
|         self, | ||||
|         services: ServiceProviderABC, | ||||
|     ) -> bool: | ||||
|         from bot_data.abc.user_joined_server_repository_abc import UserJoinedServerRepositoryABC | ||||
|  | ||||
|         ujs: UserJoinedServerRepositoryABC = services.get_service(UserJoinedServerRepositoryABC) | ||||
|         return ujs.find_active_user_joined_server_by_user_id(self.id) is None | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_select_all_string() -> str: | ||||
|         return str( | ||||
| @@ -110,8 +154,8 @@ class User(TableABC): | ||||
|             ) VALUES ( | ||||
|                 {self._discord_id}, | ||||
|                 {self._xp}, | ||||
|                 '{"NULL" if self._minecraft_id is None else self._minecraft_id}', | ||||
|                 {self._server.server_id}, | ||||
|                 '{self._minecraft_id}', | ||||
|                 {self._server.id}, | ||||
|                 '{self._created_at}', | ||||
|                 '{self._modified_at}' | ||||
|             ); | ||||
| @@ -124,7 +168,7 @@ class User(TableABC): | ||||
|             f""" | ||||
|             UPDATE `Users` | ||||
|             SET `XP` = {self._xp}, | ||||
|             `MinecraftId` = '{"NULL" if self._minecraft_id is None else self._minecraft_id}', | ||||
|             `MinecraftId` = {'null' if self.minecraft_id is None else f'{self._minecraft_id}'}, | ||||
|             `LastModifiedAt` = '{self._modified_at}' | ||||
|             WHERE `UserId` = {self._user_id}; | ||||
|         """ | ||||
|   | ||||
| @@ -38,6 +38,10 @@ class UserJoinedGameServer(TableABC): | ||||
|     def game_server(self) -> str: | ||||
|         return self._game_server | ||||
|  | ||||
|     @property | ||||
|     def time(self) -> float: | ||||
|         return round((self.leaved_on - self.joined_on).total_seconds() / 3600, 2) | ||||
|  | ||||
|     @property | ||||
|     def joined_on(self) -> datetime: | ||||
|         return self._joined_on | ||||
| @@ -100,7 +104,7 @@ class UserJoinedGameServer(TableABC): | ||||
|                 INSERT INTO `UserJoinedGameServer` ( | ||||
|                     `UserId`, `GameServer`, `JoinedOn`, `LeavedOn`, `CreatedAt`, `LastModifiedAt` | ||||
|                 ) VALUES ( | ||||
|                     {self._user.user_id}, | ||||
|                     {self._user.id}, | ||||
|                     '{self._game_server}', | ||||
|                     '{self._joined_on}', | ||||
|                     '{self._leaved_on}', | ||||
| @@ -115,7 +119,7 @@ class UserJoinedGameServer(TableABC): | ||||
|                 INSERT INTO `UserJoinedGameServer` ( | ||||
|                     `UserId`, `GameServer`, `JoinedOn`, `CreatedAt`, `LastModifiedAt` | ||||
|                 ) VALUES ( | ||||
|                     {self._user.user_id}, | ||||
|                     {self._user.id}, | ||||
|                     '{self._game_server}', | ||||
|                     '{self._joined_on}', | ||||
|                     '{self._created_at}', | ||||
|   | ||||
| @@ -25,7 +25,7 @@ class UserJoinedServer(TableABC): | ||||
|         self._modified_at = modified_at if modified_at is not None else self._modified_at | ||||
|  | ||||
|     @property | ||||
|     def join_id(self) -> int: | ||||
|     def id(self) -> int: | ||||
|         return self._join_id | ||||
|  | ||||
|     @property | ||||
| @@ -103,7 +103,7 @@ class UserJoinedServer(TableABC): | ||||
|                 INSERT INTO `UserJoinedServers` ( | ||||
|                     `UserId`, `JoinedOn`, `LeavedOn`, `CreatedAt`, `LastModifiedAt` | ||||
|                 ) VALUES ( | ||||
|                     {self._user.user_id}, | ||||
|                     {self._user.id}, | ||||
|                     '{self._joined_on}', | ||||
|                     '{self._leaved_on}', | ||||
|                     '{self._created_at}', | ||||
| @@ -117,7 +117,7 @@ class UserJoinedServer(TableABC): | ||||
|                 INSERT INTO `UserJoinedServers` ( | ||||
|                     `UserId`, `JoinedOn`, `CreatedAt`, `LastModifiedAt` | ||||
|                 ) VALUES ( | ||||
|                     {self._user.user_id}, | ||||
|                     {self._user.id}, | ||||
|                     '{self._joined_on}', | ||||
|                     '{self._created_at}', | ||||
|                     '{self._modified_at}' | ||||
| @@ -132,7 +132,7 @@ class UserJoinedServer(TableABC): | ||||
|             UPDATE `UserJoinedServers` | ||||
|             SET `LeavedOn` = '{self._leaved_on}', | ||||
|             `LastModifiedAt` = '{self._modified_at}' | ||||
|             WHERE `UserId` = {self._user.user_id}; | ||||
|             WHERE `UserId` = {self._user.id}; | ||||
|         """ | ||||
|         ) | ||||
|  | ||||
|   | ||||
| @@ -1,6 +1,8 @@ | ||||
| from datetime import datetime | ||||
|  | ||||
| from cpl_core.database import TableABC | ||||
| from cpl_core.dependency_injection import ServiceProviderABC | ||||
| from cpl_discord.service import DiscordBotServiceABC | ||||
|  | ||||
| from bot_data.model.user import User | ||||
|  | ||||
| @@ -9,7 +11,7 @@ class UserJoinedVoiceChannel(TableABC): | ||||
|     def __init__( | ||||
|         self, | ||||
|         user: User, | ||||
|         dc_channel_id: int, | ||||
|         channel_id: int, | ||||
|         joined_on: datetime, | ||||
|         leaved_on: datetime = None, | ||||
|         created_at: datetime = None, | ||||
| @@ -17,7 +19,7 @@ class UserJoinedVoiceChannel(TableABC): | ||||
|         id=0, | ||||
|     ): | ||||
|         self._join_id = id | ||||
|         self._dc_channel_id = dc_channel_id | ||||
|         self._channel_id = channel_id | ||||
|         self._user = user | ||||
|         self._joined_on = joined_on | ||||
|         self._leaved_on = leaved_on | ||||
| @@ -27,17 +29,26 @@ class UserJoinedVoiceChannel(TableABC): | ||||
|         self._modified_at = modified_at if modified_at is not None else self._modified_at | ||||
|  | ||||
|     @property | ||||
|     def join_id(self) -> int: | ||||
|     def id(self) -> int: | ||||
|         return self._join_id | ||||
|  | ||||
|     @property | ||||
|     def dc_channel_id(self) -> int: | ||||
|         return self._dc_channel_id | ||||
|     def channel_id(self) -> int: | ||||
|         return self._channel_id | ||||
|  | ||||
|     @property | ||||
|     @ServiceProviderABC.inject | ||||
|     def channel_name(self, bot: DiscordBotServiceABC) -> str: | ||||
|         return bot.get_channel(self.channel_id).name | ||||
|  | ||||
|     @property | ||||
|     def user(self) -> User: | ||||
|         return self._user | ||||
|  | ||||
|     @property | ||||
|     def time(self) -> float: | ||||
|         return round((self.leaved_on - self.joined_on).total_seconds() / 3600, 2) | ||||
|  | ||||
|     @property | ||||
|     def joined_on(self) -> datetime: | ||||
|         return self._joined_on | ||||
| @@ -100,8 +111,8 @@ class UserJoinedVoiceChannel(TableABC): | ||||
|                 INSERT INTO `UserJoinedVoiceChannel` ( | ||||
|                     `UserId`, `DiscordChannelId`, `JoinedOn`, `LeavedOn`, `CreatedAt`, `LastModifiedAt` | ||||
|                 ) VALUES ( | ||||
|                     {self._user.user_id}, | ||||
|                     {self._dc_channel_id}, | ||||
|                     {self._user.id}, | ||||
|                     {self._channel_id}, | ||||
|                     '{self._joined_on}', | ||||
|                     '{self._leaved_on}', | ||||
|                     '{self._created_at}', | ||||
| @@ -115,8 +126,8 @@ class UserJoinedVoiceChannel(TableABC): | ||||
|                 INSERT INTO `UserJoinedVoiceChannel` ( | ||||
|                     `UserId`, `DiscordChannelId`, `JoinedOn`, `CreatedAt`, `LastModifiedAt` | ||||
|                 ) VALUES ( | ||||
|                     {self._user.user_id}, | ||||
|                     {self._dc_channel_id}, | ||||
|                     {self._user.id}, | ||||
|                     {self._channel_id}, | ||||
|                     '{self._joined_on}', | ||||
|                     '{self._created_at}', | ||||
|                     '{self._modified_at}' | ||||
|   | ||||
| @@ -97,7 +97,7 @@ class UserMessageCountPerHour(TableABC): | ||||
|             INSERT INTO `UserMessageCountPerHour` ( | ||||
|                 `UserId`, `Date`, `Hour`, `XPCount`, `CreatedAt`, `LastModifiedAt` | ||||
|             ) VALUES ( | ||||
|                 {self._user.user_id}, | ||||
|                 {self._user.id}, | ||||
|                 '{self._date}', | ||||
|                 {self._hour}, | ||||
|                 {self._xp_count}, | ||||
|   | ||||
| @@ -28,7 +28,7 @@ class AuthUserRepositoryService(AuthUserRepositoryABC): | ||||
|  | ||||
|     @staticmethod | ||||
|     def _get_value_from_result(value: any) -> Optional[any]: | ||||
|         if isinstance(value, str) and "NULL" in value: | ||||
|         if isinstance(value, str) and "null" in value: | ||||
|             return None | ||||
|  | ||||
|         return value | ||||
|   | ||||
| @@ -193,9 +193,9 @@ class ClientRepositoryService(ClientRepositoryABC): | ||||
|             self._logger.warn(__name__, f"Cannot find server by id {server_id}") | ||||
|             raise Exception("Value not found") | ||||
|  | ||||
|         client = self.find_client_by_discord_id_and_server_id(id, server.server_id) | ||||
|         client = self.find_client_by_discord_id_and_server_id(id, server.id) | ||||
|         if client is None: | ||||
|             self._logger.warn(__name__, f"Cannot find client by ids {id}@{server.server_id}") | ||||
|             self._logger.warn(__name__, f"Cannot find client by ids {id}@{server.id}") | ||||
|             raise Exception("Value not found") | ||||
|  | ||||
|         return client | ||||
|   | ||||
| @@ -75,9 +75,9 @@ class QueryABC(ObjectType): | ||||
|             element: AutoRole = element | ||||
|             for u in user.users: | ||||
|                 u: User = u | ||||
|                 guild = bot.get_guild(u.server.discord_server_id) | ||||
|                 guild = bot.get_guild(u.server.discord_id) | ||||
|                 member = guild.get_member(u.discord_id) | ||||
|                 if permissions.is_member_moderator(member) and u.server.server_id == element.server.server_id: | ||||
|                 if permissions.is_member_moderator(member) and u.server.id == element.server.id: | ||||
|                     access = True | ||||
|                     break | ||||
|  | ||||
| @@ -85,23 +85,23 @@ class QueryABC(ObjectType): | ||||
|             element: AutoRole = element.auto_role | ||||
|             for u in user.users: | ||||
|                 u: User = u | ||||
|                 guild = bot.get_guild(u.server.discord_server_id) | ||||
|                 guild = bot.get_guild(u.server.discord_id) | ||||
|                 member = guild.get_member(u.discord_id) | ||||
|                 if permissions.is_member_moderator(member) and u.server.server_id == element.server.server_id: | ||||
|                 if permissions.is_member_moderator(member) and u.server.id == element.server.id: | ||||
|                     access = True | ||||
|                     break | ||||
|  | ||||
|         elif type(element) == Client: | ||||
|             for u in user.users: | ||||
|                 u: User = u | ||||
|                 if u.server.server_id == element.server.server_id: | ||||
|                 if u.server.id == element.server.id: | ||||
|                     access = True | ||||
|                     break | ||||
|  | ||||
|         elif type(element) == KnownUser: | ||||
|             for u in user.users: | ||||
|                 u: User = u | ||||
|                 guild = bot.get_guild(u.server.discord_server_id) | ||||
|                 guild = bot.get_guild(u.server.discord_id) | ||||
|                 member = guild.get_member(u.discord_id) | ||||
|                 if permissions.is_member_moderator(member): | ||||
|                     access = True | ||||
| @@ -110,42 +110,42 @@ class QueryABC(ObjectType): | ||||
|         elif type(element) == Level: | ||||
|             for u in user.users: | ||||
|                 u: User = u | ||||
|                 if u.server.server_id == element.server.server_id: | ||||
|                 if u.server.id == element.server.id: | ||||
|                     access = True | ||||
|                     break | ||||
|  | ||||
|         elif type(element) == Server: | ||||
|             for u in user.users: | ||||
|                 u: User = u | ||||
|                 if u.server.server_id == element.server_id: | ||||
|                 if u.server.id == element.id: | ||||
|                     access = True | ||||
|                     break | ||||
|  | ||||
|         elif type(element) == User: | ||||
|             for u in user.users: | ||||
|                 u: User = u | ||||
|                 if u.user_id == element.user_id: | ||||
|                 if u.id == element.id: | ||||
|                     access = True | ||||
|                     break | ||||
|  | ||||
|         elif type(element) == UserJoinedServer: | ||||
|             for u in user.users: | ||||
|                 u: User = u | ||||
|                 if u.user_id == element.user.user_id: | ||||
|                 if u.id == element.user.id: | ||||
|                     access = True | ||||
|                     break | ||||
|  | ||||
|         elif type(element) == UserJoinedVoiceChannel: | ||||
|             for u in user.users: | ||||
|                 u: User = u | ||||
|                 if u.user_id == element.user.user_id: | ||||
|                 if u.id == element.user.id: | ||||
|                     access = True | ||||
|                     break | ||||
|  | ||||
|         elif type(element) == UserJoinedGameServer: | ||||
|             for u in user.users: | ||||
|                 u: User = u | ||||
|                 if u.user_id == element.user.user_id: | ||||
|                 if u.id == element.user.id: | ||||
|                     access = True | ||||
|                     break | ||||
|  | ||||
| @@ -160,8 +160,8 @@ class QueryABC(ObjectType): | ||||
|         if auth_user == "system" or auth_user.auth_role == AuthRoleEnum.admin: | ||||
|             return | ||||
|  | ||||
|         member = bot.get_guild(server.discord_server_id).get_member( | ||||
|             auth_user.users.where(lambda x: x.server.server_id == server.server_id).single().discord_id | ||||
|         member = bot.get_guild(server.discord_id).get_member( | ||||
|             auth_user.users.where(lambda x: x.server.id == server.id).single().discord_id | ||||
|         ) | ||||
|  | ||||
|         check_perm = lambda x: True | ||||
| @@ -180,12 +180,12 @@ class QueryABC(ObjectType): | ||||
|     # @FilterABC.resolve_filter_annotation | ||||
|     def _resolve_collection(self, collection: List, *_, filter: FilterABC = None, page: Page = None, sort: Sort = None): | ||||
|         if filter is not None: | ||||
|             return filter.filter(collection) | ||||
|             collection = filter.filter(collection) | ||||
|  | ||||
|         if page is not None: | ||||
|             return page.filter(collection) | ||||
|             collection = page.filter(collection) | ||||
|  | ||||
|         if sort is not None: | ||||
|             return sort.filter(collection) | ||||
|             collection = sort.filter(collection) | ||||
|  | ||||
|         return collection | ||||
|   | ||||
| @@ -42,7 +42,7 @@ class AutoRoleFilter(FilterABC): | ||||
|  | ||||
|     def filter(self, query: List[AutoRole]) -> List[AutoRole]: | ||||
|         if self._id is not None: | ||||
|             query = query.where(lambda x: x.auto_role_id == self._id) | ||||
|             query = query.where(lambda x: x.id == self._id) | ||||
|  | ||||
|         if self._channel_id is not None: | ||||
|             query = query.where(lambda x: x.discord_channel_id == self._channel_id) | ||||
| @@ -57,7 +57,7 @@ class AutoRoleFilter(FilterABC): | ||||
|             query = query.where(lambda x: x.discord_message_id == self._message_id) | ||||
|  | ||||
|         if self._server is not None: | ||||
|             servers = self._server.filter(query.select(lambda x: x.server)).select(lambda x: x.server_id) | ||||
|             query = query.where(lambda x: x.server.server_id in servers) | ||||
|             servers = self._server.filter(query.select(lambda x: x.server)).select(lambda x: x.id) | ||||
|             query = query.where(lambda x: x.server.id in servers) | ||||
|  | ||||
|         return query | ||||
|   | ||||
| @@ -39,7 +39,7 @@ class AutoRoleRuleFilter(FilterABC): | ||||
|  | ||||
|     def filter(self, query: List[AutoRoleRule]) -> List[AutoRoleRule]: | ||||
|         if self._id is not None: | ||||
|             query = query.where(lambda x: x.auto_role_rule_id == self._id) | ||||
|             query = query.where(lambda x: x.id == self._id) | ||||
|  | ||||
|         if self._emoji_name is not None: | ||||
|             query = query.where(lambda x: x.emoji_name == self._emoji_name) | ||||
| @@ -50,14 +50,14 @@ class AutoRoleRuleFilter(FilterABC): | ||||
|         if self._role_name is not None and self._role_id is not None: | ||||
|  | ||||
|             def get_role_name(x: AutoRoleRule): | ||||
|                 guild = self._bot.get_guild(x.auto_role.server.discord_server_id) | ||||
|                 guild = self._bot.get_guild(x.auto_role.server.discord_id) | ||||
|                 name = guild.get_role(x.role_id).name | ||||
|                 return name == self._role_name or self._role_name in name | ||||
|  | ||||
|             query = query.where(get_role_name) | ||||
|  | ||||
|         if self._auto_role is not None: | ||||
|             auto_roles = self._auto_role.filter(query.select(lambda x: x.auto_role)).select(lambda x: x.auto_role_id) | ||||
|             query = query.where(lambda x: x.auto_role.auto_role_id in auto_roles) | ||||
|             auto_roles = self._auto_role.filter(query.select(lambda x: x.auto_role)).select(lambda x: x.id) | ||||
|             query = query.where(lambda x: x.auto_role.id in auto_roles) | ||||
|  | ||||
|         return query | ||||
|   | ||||
| @@ -32,16 +32,16 @@ class ClientFilter(FilterABC): | ||||
|  | ||||
|     def filter(self, query: List[Client]) -> List[Client]: | ||||
|         if self._id is not None: | ||||
|             query = query.where(lambda x: x.client_id == self._id) | ||||
|             query = query.where(lambda x: x.id == self._id) | ||||
|  | ||||
|         if self._discord_id is not None: | ||||
|             query = query.where(lambda x: x.client_id == self._discord_id) | ||||
|             query = query.where(lambda x: x.id == self._discord_id) | ||||
|  | ||||
|         if self._name is not None: | ||||
|             query = query.where(lambda x: self._name.lower() == x.name.lower() or self._name.lower() in x.name.lower()) | ||||
|  | ||||
|         if self._server is not None: | ||||
|             servers = self._server.filter(query.select(lambda x: x.server)).select(lambda x: x.server_id) | ||||
|             query = query.where(lambda x: x.server.server_id in servers) | ||||
|             servers = self._server.filter(query.select(lambda x: x.server)).select(lambda x: x.id) | ||||
|             query = query.where(lambda x: x.server.id in servers) | ||||
|  | ||||
|         return query | ||||
|   | ||||
| @@ -25,7 +25,7 @@ class LevelFilter(FilterABC): | ||||
|         if "server" in values: | ||||
|             from bot_graphql.filter.server_filter import ServerFilter | ||||
|  | ||||
|             self._server: ServerFilter = self._services.get_service(LevelFilter) | ||||
|             self._server: ServerFilter = self._services.get_service(ServerFilter) | ||||
|             self._server.from_dict(values["server"]) | ||||
|  | ||||
|     def filter(self, query: List[Level]) -> List[Level]: | ||||
| @@ -36,7 +36,7 @@ class LevelFilter(FilterABC): | ||||
|             query = query.where(lambda x: self._name.lower() == x.name.lower() or self._name.lower() in x.name.lower()) | ||||
|  | ||||
|         if self._server is not None: | ||||
|             servers = self._server.filter(query.select(lambda x: x.server)).select(lambda x: x.server_id) | ||||
|             query = query.where(lambda x: x.server.server_id in servers) | ||||
|             servers = self._server.filter(query.select(lambda x: x.server)).select(lambda x: x.id) | ||||
|             query = query.where(lambda x: x.server.id in servers) | ||||
|  | ||||
|         return query | ||||
|   | ||||
| @@ -28,15 +28,17 @@ class ServerFilter(FilterABC): | ||||
|     @ServiceProviderABC.inject | ||||
|     def filter(self, query: List[Server], bot: DiscordBotServiceABC) -> List[Server]: | ||||
|         if self._id is not None: | ||||
|             query = query.where(lambda x: x.server_id == self._id) | ||||
|             query = query.where(lambda x: x.id == self._id) | ||||
|  | ||||
|         if self._discord_id is not None: | ||||
|             query = query.where(lambda x: x.discord_server_id == self._discord_id) | ||||
|             query = query.where( | ||||
|                 lambda x: x.discord_id == self._discord_id or str(self._discord_id) in str(x.discord_id) | ||||
|             ) | ||||
|  | ||||
|         if self._name is not None: | ||||
|  | ||||
|             def where_guild(x: Guild): | ||||
|                 guild = bot.get_guild(x.discord_server_id) | ||||
|                 guild = bot.get_guild(x.discord_id) | ||||
|                 return guild is not None and ( | ||||
|                     self._name.lower() == guild.name.lower() or self._name.lower() in guild.name.lower() | ||||
|                 ) | ||||
|   | ||||
| @@ -1,3 +1,6 @@ | ||||
| import functools | ||||
|  | ||||
| from cpl_core.utils import String | ||||
| from cpl_query.extension import List | ||||
|  | ||||
| from bot_graphql.abc.filter_abc import FilterABC | ||||
| @@ -6,6 +9,7 @@ from bot_graphql.abc.filter_abc import FilterABC | ||||
| class Sort(FilterABC): | ||||
|     def __init__(self): | ||||
|         FilterABC.__init__(self) | ||||
|  | ||||
|         self._sort_direction = None | ||||
|         self._sort_column = None | ||||
|  | ||||
| @@ -16,5 +20,27 @@ class Sort(FilterABC): | ||||
|         if "sortColumn" in values: | ||||
|             self._sort_column = values["sortColumn"] | ||||
|  | ||||
|     @staticmethod | ||||
|     def _rgetattr(obj, attr, *args): | ||||
|         def _getattr(obj, attr): | ||||
|             return getattr(obj, attr, *args) | ||||
|  | ||||
|         return functools.reduce(_getattr, [obj] + attr.split(".")) | ||||
|  | ||||
|     def _by_column(self, x): | ||||
|         atr = self._rgetattr(x, String.convert_to_snake_case(self._sort_column), None) | ||||
|         if atr is None: | ||||
|             return "" | ||||
|         return atr | ||||
|  | ||||
|     def filter(self, query: List, *args) -> List: | ||||
|         if self._sort_column is None: | ||||
|             return query | ||||
|  | ||||
|         match self._sort_direction.lower() if self._sort_direction is not None else "ASC": | ||||
|             case "asc": | ||||
|                 query = query.order_by(self._by_column) | ||||
|             case "desc": | ||||
|                 query = query.order_by_descending(self._by_column) | ||||
|  | ||||
|         return query | ||||
|   | ||||
| @@ -5,6 +5,7 @@ from cpl_discord.service import DiscordBotServiceABC | ||||
| from cpl_query.extension import List | ||||
|  | ||||
| from bot_core.abc.client_utils_abc import ClientUtilsABC | ||||
| from bot_data.abc.user_joined_server_repository_abc import UserJoinedServerRepositoryABC | ||||
| from bot_data.model.user import User | ||||
| from bot_graphql.abc.filter_abc import FilterABC | ||||
| from bot_graphql.filter.level_filter import LevelFilter | ||||
| @@ -18,6 +19,7 @@ class UserFilter(FilterABC): | ||||
|         bot: DiscordBotServiceABC, | ||||
|         client_utils: ClientUtilsABC, | ||||
|         levels: LevelService, | ||||
|         user_joined_servers: UserJoinedServerRepositoryABC, | ||||
|     ): | ||||
|         FilterABC.__init__(self) | ||||
|  | ||||
| @@ -25,6 +27,7 @@ class UserFilter(FilterABC): | ||||
|         self._bot = bot | ||||
|         self._client_utils = client_utils | ||||
|         self._levels = levels | ||||
|         self._user_joined_servers = user_joined_servers | ||||
|  | ||||
|         self._id = None | ||||
|         self._discord_id = None | ||||
| @@ -34,6 +37,7 @@ class UserFilter(FilterABC): | ||||
|         self._ontime = None | ||||
|         self._level: Optional[LevelFilter] = None | ||||
|         self._server = None | ||||
|         self._left_server = None | ||||
|  | ||||
|     def from_dict(self, values: dict): | ||||
|         if "id" in values: | ||||
| @@ -64,18 +68,26 @@ class UserFilter(FilterABC): | ||||
|             self._server: ServerFilter = self._services.get_service(ServerFilter) | ||||
|             self._server.from_dict(values["server"]) | ||||
|  | ||||
|         if "leftServer" in values: | ||||
|             self._left_server = values["leftServer"] | ||||
|  | ||||
|     def filter(self, query: List[User]) -> List[User]: | ||||
|         if self._id is not None: | ||||
|             query = query.where(lambda x: x.user_id == self._id) | ||||
|             query = query.where(lambda x: x.id == self._id) | ||||
|  | ||||
|         if self._discord_id is not None: | ||||
|             query = query.where(lambda x: x.discord_id == self._discord_id) | ||||
|             query = query.where( | ||||
|                 lambda x: x.discord_id == self._discord_id or str(self._discord_id) in str(x.discord_id) | ||||
|             ) | ||||
|  | ||||
|         if self._name is not None: | ||||
|             query = query.where( | ||||
|                 lambda x: self._bot.get_user(x.discord_id).name == self._name | ||||
|                 or self._name in self._bot.get_user(x.discord_id).name | ||||
|             ) | ||||
|  | ||||
|             def _get_member(user: User): | ||||
|                 guild = self._bot.get_guild(user.server.discord_id) | ||||
|                 member = guild.get_member(user.discord_id) | ||||
|                 return member is not None and (member.name == self._name or self._name in member.name) | ||||
|  | ||||
|             query = query.where(_get_member) | ||||
|  | ||||
|         if self._xp is not None: | ||||
|             query = query.where(lambda x: x.xp == self._xp) | ||||
| @@ -91,7 +103,15 @@ class UserFilter(FilterABC): | ||||
|             query = query.where(lambda x: self._levels.get_level(x).id in levels) | ||||
|  | ||||
|         if self._server is not None: | ||||
|             servers = self._server.filter(query.select(lambda x: x.server)).select(lambda x: x.server_id) | ||||
|             query = query.where(lambda x: x.server.server_id in servers) | ||||
|             servers = self._server.filter(query.select(lambda x: x.server)).select(lambda x: x.id) | ||||
|             query = query.where(lambda x: x.server.id in servers) | ||||
|  | ||||
|         if self._left_server is not None: | ||||
|  | ||||
|             def _has_user_left_server(user: User): | ||||
|                 active_join = self._user_joined_servers.find_active_user_joined_server_by_user_id(user.id) | ||||
|                 return (active_join is None) == self._left_server | ||||
|  | ||||
|             query = query.where(_has_user_left_server) | ||||
|  | ||||
|         return query | ||||
|   | ||||
| @@ -42,7 +42,7 @@ class UserJoinedGameServerFilter(FilterABC): | ||||
|             query = query.where(lambda x: x.game_server == self._game_server) | ||||
|  | ||||
|         if self._user is not None: | ||||
|             users = self._user.filter(query.select(lambda x: x.user)).select(lambda x: x.user_id) | ||||
|             query = query.where(lambda x: x.user.user_id in users) | ||||
|             users = self._user.filter(query.select(lambda x: x.user)).select(lambda x: x.id) | ||||
|             query = query.where(lambda x: x.user.id in users) | ||||
|  | ||||
|         return query | ||||
|   | ||||
| @@ -43,8 +43,8 @@ class UserJoinedServerFilter(FilterABC): | ||||
|             query = query.where(lambda x: x.id == self._id) | ||||
|  | ||||
|         if self._user is not None: | ||||
|             users = self._user.filter(query.select(lambda x: x.user)).select(lambda x: x.user_id) | ||||
|             query = query.where(lambda x: x.user.user_id in users) | ||||
|             users = self._user.filter(query.select(lambda x: x.user)).select(lambda x: x.id) | ||||
|             query = query.where(lambda x: x.user.id in users) | ||||
|  | ||||
|         if self._joined_on is not None: | ||||
|             query = query.where(lambda x: x.joined_on == self._joined_on or self._joined_on in x.joined_on) | ||||
|   | ||||
| @@ -51,19 +51,19 @@ class UserJoinedVoiceChannelFilter(FilterABC): | ||||
|             query = query.where(lambda x: x.id == self._id) | ||||
|  | ||||
|         if self._channel_id is not None: | ||||
|             query = query.where(lambda x: x.dc_channel_id == self._channel_id) | ||||
|             query = query.where(lambda x: x.channel_id == self._channel_id) | ||||
|  | ||||
|         if self._channel_name is not None and self._channel_id is not None: | ||||
|  | ||||
|             def get_channel_name(x: UserJoinedVoiceChannel): | ||||
|                 name = self._bot.get_channel(x.dc_channel_id).name | ||||
|                 name = self._bot.get_channel(x.channel_id).name | ||||
|                 return name == self._channel_name or self._channel_name in name | ||||
|  | ||||
|             query = query.where(get_channel_name) | ||||
|  | ||||
|         if self._user is not None: | ||||
|             users = self._user.filter(query.select(lambda x: x.user)).select(lambda x: x.user_id) | ||||
|             query = query.where(lambda x: x.user.user_id in users) | ||||
|             users = self._user.filter(query.select(lambda x: x.user)).select(lambda x: x.id) | ||||
|             query = query.where(lambda x: x.user.id in users) | ||||
|  | ||||
|         if self._joined_on is not None: | ||||
|             query = query.where(lambda x: x.joined_on == self._joined_on or self._joined_on in x.joined_on) | ||||
|   | ||||
| @@ -9,6 +9,11 @@ input Page { | ||||
| } | ||||
|  | ||||
| input Sort { | ||||
|     sortDirection: String | ||||
|     sortDirection: SortDirection | ||||
|     sortColumn: String | ||||
| } | ||||
|  | ||||
| enum SortDirection { | ||||
|     ASC | ||||
|     DESC | ||||
| } | ||||
| @@ -17,6 +17,7 @@ type User implements TableQuery { | ||||
|     userJoinedGameServers(filter: UserJoinedGameServerFilter, page: Page, sort: Sort): [UserJoinedGameServer] | ||||
|  | ||||
|     server: Server | ||||
|     leftServer: Boolean | ||||
|  | ||||
|     createdAt: String | ||||
|     modifiedAt: String | ||||
| @@ -31,6 +32,7 @@ input UserFilter { | ||||
|     ontime: Float | ||||
|     level: LevelFilter | ||||
|     server: ServerFilter | ||||
|     leftServer: Boolean | ||||
| } | ||||
|  | ||||
| type UserMutation { | ||||
| @@ -40,4 +42,5 @@ type UserMutation { | ||||
| input UserInput { | ||||
|     id: ID | ||||
|     xp: Int | ||||
|     levelId: ID | ||||
| } | ||||
| @@ -2,6 +2,7 @@ type UserJoinedGameServer implements TableQuery { | ||||
|     id: ID | ||||
|     gameServer: String | ||||
|     user: User | ||||
|     time: Float | ||||
|     joinedOn: String | ||||
|     leavedOn: String | ||||
|  | ||||
|   | ||||
| @@ -3,6 +3,7 @@ type UserJoinedVoiceChannel implements TableQuery { | ||||
|     channelId: String | ||||
|     channelName: String | ||||
|     user: User | ||||
|     time: Float | ||||
|     joinedOn: String | ||||
|     leavedOn: String | ||||
|  | ||||
|   | ||||
| @@ -33,12 +33,12 @@ class AutoRoleMutation(QueryABC): | ||||
|  | ||||
|         def get_new(x: AutoRole): | ||||
|             return ( | ||||
|                 x.server.server_id == input["serverId"] | ||||
|                 x.server.id == input["serverId"] | ||||
|                 and x.discord_channel_id == input["channelId"] | ||||
|                 and x.discord_message_id == input["messageId"] | ||||
|             ) | ||||
|  | ||||
|         return self._auto_roles.get_auto_roles_by_server_id(auto_role.server.server_id).where(get_new).last() | ||||
|         return self._auto_roles.get_auto_roles_by_server_id(auto_role.server.id).where(get_new).last() | ||||
|  | ||||
|     def resolve_update_auto_role(self, *_, input: dict): | ||||
|         auto_role = self._auto_roles.get_auto_role_by_id(input["id"]) | ||||
|   | ||||
| @@ -35,16 +35,12 @@ class AutoRoleRuleMutation(QueryABC): | ||||
|  | ||||
|         def get_new(x: AutoRoleRule): | ||||
|             return ( | ||||
|                 x.auto_role.auto_role_id == input["autoRoleId"] | ||||
|                 x.auto_role.id == input["autoRoleId"] | ||||
|                 and x.emoji_name == input["emojiName"] | ||||
|                 and x.role_id == input["roleId"] | ||||
|             ) | ||||
|  | ||||
|         return ( | ||||
|             self._auto_roles.get_auto_role_rules_by_auto_role_id(auto_role_rule.auto_role.auto_role_id) | ||||
|             .where(get_new) | ||||
|             .last() | ||||
|         ) | ||||
|         return self._auto_roles.get_auto_role_rules_by_auto_role_id(auto_role_rule.auto_role.id).where(get_new).last() | ||||
|  | ||||
|     def resolve_update_auto_role_rule(self, *_, input: dict): | ||||
|         auto_role_rule = self._auto_roles.get_auto_role_rule_by_id(input["id"]) | ||||
|   | ||||
| @@ -46,7 +46,7 @@ class LevelMutation(QueryABC): | ||||
|                 and l.permissions == level.permissions | ||||
|             ) | ||||
|  | ||||
|         return self._levels.get_levels_by_server_id(level.server.server_id).where(get_new_level).last() | ||||
|         return self._levels.get_levels_by_server_id(level.server.id).where(get_new_level).last() | ||||
|  | ||||
|     def resolve_update_level(self, *_, input: dict): | ||||
|         level = self._levels.get_level_by_id(input["id"]) | ||||
|   | ||||
| @@ -45,11 +45,11 @@ class UserJoinedGameServerMutation(QueryABC): | ||||
|         user = self._users.get_user_by_id(input["userId"]) | ||||
|         self._can_user_mutate_data(user.server, UserRoleEnum.admin) | ||||
|  | ||||
|         active = self._user_joined_game_servers.find_active_user_joined_game_server_by_user_id(user.user_id) | ||||
|         active = self._user_joined_game_servers.find_active_user_joined_game_server_by_user_id(user.id) | ||||
|         if active is not None: | ||||
|             self._logger.debug( | ||||
|                 __name__, | ||||
|                 f"Skip UserJoinedGameServer for user {user.user_id}. User already plays on {active.game_server}.", | ||||
|                 f"Skip UserJoinedGameServer for user {user.id}. User already plays on {active.game_server}.", | ||||
|             ) | ||||
|             return | ||||
|  | ||||
| @@ -57,18 +57,18 @@ class UserJoinedGameServerMutation(QueryABC): | ||||
|         self._user_joined_game_servers.add_user_joined_game_server(new) | ||||
|         self._db.save_changes() | ||||
|  | ||||
|         return self._user_joined_game_servers.get_active_user_joined_game_server_by_user_id(user.user_id) | ||||
|         return self._user_joined_game_servers.get_active_user_joined_game_server_by_user_id(user.id) | ||||
|  | ||||
|     def resolve_user_leaved(self, *_, input: dict): | ||||
|         user = self._users.get_user_by_id(input["userId"]) | ||||
|         self._can_user_mutate_data(user.server, UserRoleEnum.admin) | ||||
|  | ||||
|         active = self._user_joined_game_servers.find_active_user_joined_game_server_by_user_id(user.user_id) | ||||
|         active = self._user_joined_game_servers.find_active_user_joined_game_server_by_user_id(user.id) | ||||
|         if active is None: | ||||
|             return None | ||||
|         active.leaved_on = datetime.now() | ||||
|  | ||||
|         settings: BaseServerSettings = self._base_helper.get_config(user.server.discord_server_id) | ||||
|         settings: BaseServerSettings = self._base_helper.get_config(user.server.discord_id) | ||||
|  | ||||
|         ontime = round((active.leaved_on - active.joined_on).total_seconds() / 3600, 2) | ||||
|         old_xp = user.xp | ||||
|   | ||||
| @@ -1,10 +1,12 @@ | ||||
| from cpl_core.database.context import DatabaseContextABC | ||||
| from cpl_discord.service import DiscordBotServiceABC | ||||
|  | ||||
| from bot_data.abc.level_repository_abc import LevelRepositoryABC | ||||
| from bot_data.abc.server_repository_abc import ServerRepositoryABC | ||||
| from bot_data.abc.user_repository_abc import UserRepositoryABC | ||||
| from bot_data.model.user_role_enum import UserRoleEnum | ||||
| from bot_graphql.abc.query_abc import QueryABC | ||||
| from modules.level.service.level_service import LevelService | ||||
| from modules.permission.service.permission_service import PermissionService | ||||
|  | ||||
|  | ||||
| @@ -16,6 +18,8 @@ class UserMutation(QueryABC): | ||||
|         bot: DiscordBotServiceABC, | ||||
|         db: DatabaseContextABC, | ||||
|         permissions: PermissionService, | ||||
|         levels: LevelRepositoryABC, | ||||
|         level_service: LevelService, | ||||
|     ): | ||||
|         QueryABC.__init__(self, "UserMutation") | ||||
|  | ||||
| @@ -24,6 +28,8 @@ class UserMutation(QueryABC): | ||||
|         self._bot = bot | ||||
|         self._db = db | ||||
|         self._permissions = permissions | ||||
|         self._levels = levels | ||||
|         self._level_service = level_service | ||||
|  | ||||
|         self.set_field("updateUser", self.resolve_update_user) | ||||
|  | ||||
| @@ -31,10 +37,15 @@ class UserMutation(QueryABC): | ||||
|         user = self._users.get_user_by_id(input["id"]) | ||||
|         self._can_user_mutate_data(user.server, UserRoleEnum.moderator) | ||||
|  | ||||
|         if "levelId" in input: | ||||
|             level = self._levels.get_level_by_id(input["levelId"]) | ||||
|             user.xp = level.min_xp | ||||
|  | ||||
|         user.xp = input["xp"] if "xp" in input else user.xp | ||||
|  | ||||
|         self._users.update_user(user) | ||||
|         self._db.save_changes() | ||||
|         self._bot.loop.create_task(self._level_service.set_level(user)) | ||||
|  | ||||
|         user = self._users.get_user_by_id(input["id"]) | ||||
|         return user | ||||
|   | ||||
| @@ -28,21 +28,21 @@ class AutoRoleQuery(DataQueryABC): | ||||
|         self.set_field("server", self.resolve_server) | ||||
|         self.add_collection( | ||||
|             "autoRoleRule", | ||||
|             lambda x, *_: self._auto_role_rules.get_auto_role_rules_by_auto_role_id(x.auto_role_id), | ||||
|             lambda x, *_: self._auto_role_rules.get_auto_role_rules_by_auto_role_id(x.id), | ||||
|             AutoRoleFilter, | ||||
|         ) | ||||
|  | ||||
|     @staticmethod | ||||
|     def resolve_id(x: AutoRole, *_): | ||||
|         return x.auto_role_id | ||||
|         return x.id | ||||
|  | ||||
|     @staticmethod | ||||
|     def resolve_channel_id(x: AutoRole, *_): | ||||
|         return x.discord_channel_id | ||||
|  | ||||
|     def resolve_channel_name(self, x: AutoRole, *_): | ||||
|         channel = self._bot.get_channel(x.discord_channel_id) | ||||
|         return None if channel is None else channel.name | ||||
|     @staticmethod | ||||
|     def resolve_channel_name(x: AutoRole, *_): | ||||
|         return x.discord_channel_name | ||||
|  | ||||
|     @staticmethod | ||||
|     def resolve_message_id(x: AutoRole, *_): | ||||
| @@ -50,6 +50,6 @@ class AutoRoleQuery(DataQueryABC): | ||||
|  | ||||
|     def resolve_server(self, x: AutoRole, *_, filter: ServerFilter = None): | ||||
|         if filter is not None: | ||||
|             return filter.filter(self._servers.get_server_by_id(x.server.server_id)) | ||||
|             return filter.filter(self._servers.get_server_by_id(x.server.id)) | ||||
|  | ||||
|         return self._servers.get_server_by_id(x.server.server_id) | ||||
|         return self._servers.get_server_by_id(x.server.id) | ||||
|   | ||||
| @@ -24,7 +24,7 @@ class AutoRoleRuleQuery(DataQueryABC): | ||||
|  | ||||
|     @staticmethod | ||||
|     def resolve_id(x: AutoRoleRule, *_): | ||||
|         return x.auto_role_rule_id | ||||
|         return x.id | ||||
|  | ||||
|     @staticmethod | ||||
|     def resolve_emoji_name(x: AutoRoleRule, *_): | ||||
| @@ -34,9 +34,9 @@ class AutoRoleRuleQuery(DataQueryABC): | ||||
|     def resolve_role_id(x: AutoRoleRule, *_): | ||||
|         return x.role_id | ||||
|  | ||||
|     def resolve_role_name(self, x: AutoRoleRule, *_): | ||||
|         guild = self._bot.get_guild(x.auto_role.server.discord_server_id) | ||||
|         return guild.get_role(x.role_id).name | ||||
|     @staticmethod | ||||
|     def resolve_role_name(x: AutoRoleRule, *_): | ||||
|         return x.role_name | ||||
|  | ||||
|     def resolve_auto_role(self, x: AutoRoleRule, *_): | ||||
|         return self._auto_roles.get_auto_role_by_id(x.auto_role.auto_role_id) | ||||
|         return self._auto_roles.get_auto_role_by_id(x.auto_role.id) | ||||
|   | ||||
| @@ -25,14 +25,15 @@ class ClientQuery(DataQueryABC): | ||||
|  | ||||
|     @staticmethod | ||||
|     def resolve_id(client: Client, *_): | ||||
|         return client.client_id | ||||
|         return client.id | ||||
|  | ||||
|     @staticmethod | ||||
|     def resolve_discord_id(client: Client, *_): | ||||
|         return client.discord_id | ||||
|  | ||||
|     def resolve_name(self, client: Client, *_): | ||||
|         return self._bot.user.name | ||||
|     @staticmethod | ||||
|     def resolve_name(client: Client, *_): | ||||
|         return client.name | ||||
|  | ||||
|     @staticmethod | ||||
|     def resolve_sent_message_count(client: Client, *_): | ||||
|   | ||||
| @@ -11,7 +11,7 @@ class KnownUserQuery(DataQueryABC): | ||||
|  | ||||
|     @staticmethod | ||||
|     def resolve_id(x: KnownUser, *_): | ||||
|         return x.known_user_id | ||||
|         return x.id | ||||
|  | ||||
|     @staticmethod | ||||
|     def resolve_discord_id(x: KnownUser, *_): | ||||
|   | ||||
| @@ -42,29 +42,27 @@ class ServerQuery(DataQueryABC): | ||||
|  | ||||
|         self.add_collection( | ||||
|             "autoRole", | ||||
|             lambda server, *_: self._auto_roles.get_auto_roles_by_server_id(server.server_id), | ||||
|             lambda server, *_: self._auto_roles.get_auto_roles_by_server_id(server.id), | ||||
|             AutoRoleFilter, | ||||
|         ) | ||||
|         self.add_collection( | ||||
|             "client", lambda server, *_: self._clients.get_clients_by_server_id(server.server_id), ClientFilter | ||||
|             "client", lambda server, *_: self._clients.get_clients_by_server_id(server.id), ClientFilter | ||||
|         ) | ||||
|         self.add_collection( | ||||
|             "level", lambda server, *_: self._levels.get_levels_by_server_id(server.server_id), LevelFilter | ||||
|         ) | ||||
|         self.add_collection("user", lambda server, *_: self._users.get_users_by_server_id(server.server_id), UserFilter) | ||||
|         self.add_collection("level", lambda server, *_: self._levels.get_levels_by_server_id(server.id), LevelFilter) | ||||
|         self.add_collection("user", lambda server, *_: self._users.get_users_by_server_id(server.id), UserFilter) | ||||
|  | ||||
|     @staticmethod | ||||
|     def resolve_id(server: Server, *_): | ||||
|         return server.server_id | ||||
|         return server.id | ||||
|  | ||||
|     @staticmethod | ||||
|     def resolve_discord_id(server: Server, *_): | ||||
|         return server.discord_server_id | ||||
|         return server.discord_id | ||||
|  | ||||
|     def resolve_name(self, server: Server, *_): | ||||
|         guild = self._bot.get_guild(server.discord_server_id) | ||||
|         return None if guild is None else guild.name | ||||
|     @staticmethod | ||||
|     def resolve_name(server: Server, *_): | ||||
|         return server.name | ||||
|  | ||||
|     def resolve_icon_url(self, server: Server, *_): | ||||
|         guild = self._bot.get_guild(server.discord_server_id) | ||||
|         return None if guild is None else guild.icon.url | ||||
|     @staticmethod | ||||
|     def resolve_icon_url(server: Server, *_): | ||||
|         return server.icon_url | ||||
|   | ||||
| @@ -28,6 +28,10 @@ class UserJoinedGameServerQuery(DataQueryABC): | ||||
|     def resolve_user(x: UserJoinedGameServer, *_): | ||||
|         return x.user | ||||
|  | ||||
|     @staticmethod | ||||
|     def resolve_time(x: UserJoinedGameServer, *_): | ||||
|         return x.time | ||||
|  | ||||
|     @staticmethod | ||||
|     def resolve_joined_on(x: UserJoinedGameServer, *_): | ||||
|         return x.joined_on | ||||
|   | ||||
| @@ -13,7 +13,7 @@ class UserJoinedServerQuery(DataQueryABC): | ||||
|  | ||||
|     @staticmethod | ||||
|     def resolve_id(x: UserJoinedServer, *_): | ||||
|         return x.join_id | ||||
|         return x.id | ||||
|  | ||||
|     @staticmethod | ||||
|     def resolve_user(x: UserJoinedServer, *_): | ||||
|   | ||||
| @@ -14,24 +14,30 @@ class UserJoinedVoiceChannelQuery(DataQueryABC): | ||||
|         self.set_field("channelId", self.resolve_channel_id) | ||||
|         self.set_field("channelName", self.resolve_channel_name) | ||||
|         self.set_field("user", self.resolve_user) | ||||
|         self.set_field("time", self.resolve_time) | ||||
|         self.set_field("joinedOn", self.resolve_joined_on) | ||||
|         self.set_field("leavedOn", self.resolve_leaved_on) | ||||
|  | ||||
|     @staticmethod | ||||
|     def resolve_id(x: UserJoinedVoiceChannel, *_): | ||||
|         return x.join_id | ||||
|         return x.id | ||||
|  | ||||
|     @staticmethod | ||||
|     def resolve_channel_id(x: UserJoinedVoiceChannel, *_): | ||||
|         return x.dc_channel_id | ||||
|         return x.channel_id | ||||
|  | ||||
|     def resolve_channel_name(self, x: UserJoinedVoiceChannel, *_): | ||||
|         return self._bot.get_channel(x.dc_channel_id).name | ||||
|     @staticmethod | ||||
|     def resolve_channel_name(x: UserJoinedVoiceChannel, *_): | ||||
|         return x.channel_name | ||||
|  | ||||
|     @staticmethod | ||||
|     def resolve_user(x: UserJoinedVoiceChannel, *_): | ||||
|         return x.user | ||||
|  | ||||
|     @staticmethod | ||||
|     def resolve_time(x: UserJoinedVoiceChannel, *_): | ||||
|         return x.time | ||||
|  | ||||
|     @staticmethod | ||||
|     def resolve_joined_on(x: UserJoinedVoiceChannel, *_): | ||||
|         return x.joined_on | ||||
|   | ||||
| @@ -10,6 +10,7 @@ from bot_graphql.filter.user_joined_game_server_filter import UserJoinedGameServ | ||||
| from bot_graphql.filter.user_joined_server_filter import UserJoinedServerFilter | ||||
| from bot_graphql.filter.user_joined_voice_channel_filter import UserJoinedVoiceChannelFilter | ||||
| from modules.level.service.level_service import LevelService | ||||
| from modules.permission.abc.permission_service_abc import PermissionServiceABC | ||||
|  | ||||
|  | ||||
| class UserQuery(DataQueryABC): | ||||
| @@ -21,6 +22,7 @@ class UserQuery(DataQueryABC): | ||||
|         ujs: UserJoinedServerRepositoryABC, | ||||
|         ujvs: UserJoinedVoiceChannelRepositoryABC, | ||||
|         user_joined_game_server: UserJoinedGameServerRepositoryABC, | ||||
|         permissions: PermissionServiceABC, | ||||
|     ): | ||||
|         DataQueryABC.__init__(self, "User") | ||||
|  | ||||
| @@ -30,6 +32,7 @@ class UserQuery(DataQueryABC): | ||||
|         self._user_joined_game_server = user_joined_game_server | ||||
|         self._ujs = ujs | ||||
|         self._ujvs = ujvs | ||||
|         self._permissions = permissions | ||||
|  | ||||
|         self.set_field("id", self.resolve_id) | ||||
|         self.set_field("discordId", self.resolve_discord_id) | ||||
| @@ -40,33 +43,33 @@ class UserQuery(DataQueryABC): | ||||
|         self.set_field("level", self.resolve_level) | ||||
|         self.add_collection( | ||||
|             "joinedServer", | ||||
|             lambda user, *_: self._ujs.get_user_joined_servers_by_user_id(user.user_id), | ||||
|             lambda user, *_: self._ujs.get_user_joined_servers_by_user_id(user.id), | ||||
|             UserJoinedServerFilter, | ||||
|         ) | ||||
|         self.add_collection( | ||||
|             "joinedVoiceChannel", | ||||
|             lambda user, *_: self._ujvs.get_user_joined_voice_channels_by_user_id(user.user_id), | ||||
|             lambda user, *_: self._ujvs.get_user_joined_voice_channels_by_user_id(user.id), | ||||
|             UserJoinedVoiceChannelFilter, | ||||
|         ) | ||||
|         self.add_collection( | ||||
|             "userJoinedGameServer", | ||||
|             lambda user, *_: self._user_joined_game_server.get_user_joined_game_servers_by_user_id(user.user_id), | ||||
|             lambda user, *_: self._user_joined_game_server.get_user_joined_game_servers_by_user_id(user.id), | ||||
|             UserJoinedGameServerFilter, | ||||
|         ) | ||||
|         self.set_field("server", self.resolve_server) | ||||
|         self.set_field("leftServer", self.resolve_left_server) | ||||
|  | ||||
|     @staticmethod | ||||
|     def resolve_id(user: User, *_): | ||||
|         return user.user_id | ||||
|         return user.id | ||||
|  | ||||
|     @staticmethod | ||||
|     def resolve_discord_id(user: User, *_): | ||||
|         return user.discord_id | ||||
|  | ||||
|     def resolve_name(self, user: User, *_): | ||||
|         guild = self._bot.get_guild(user.server.discord_server_id) | ||||
|         user = guild.get_member(user.discord_id) | ||||
|         return None if user is None else user.name | ||||
|     @staticmethod | ||||
|     def resolve_name(user: User, *_): | ||||
|         return user.name | ||||
|  | ||||
|     @staticmethod | ||||
|     def resolve_xp(user: User, *_): | ||||
| @@ -76,12 +79,18 @@ class UserQuery(DataQueryABC): | ||||
|     def resolve_minecraft_id(user: User, *_): | ||||
|         return user.minecraft_id | ||||
|  | ||||
|     def resolve_ontime(self, user: User, *_): | ||||
|         return self._client_utils.get_ontime_for_user(user) | ||||
|     @staticmethod | ||||
|     def resolve_ontime(user: User, *_): | ||||
|         return user.ontime | ||||
|  | ||||
|     def resolve_level(self, user: User, *_): | ||||
|         return self._levels.get_level(user) | ||||
|     @staticmethod | ||||
|     def resolve_level(user: User, *_): | ||||
|         return user.level | ||||
|  | ||||
|     @staticmethod | ||||
|     def resolve_server(user: User, *_): | ||||
|         return user.server | ||||
|  | ||||
|     @staticmethod | ||||
|     def resolve_left_server(user: User, *_): | ||||
|         return user.left_server | ||||
|   | ||||
| @@ -52,7 +52,7 @@ class AutoRoleGroup(DiscordCommandABC): | ||||
|         self, interaction: discord.Interaction, current: str | ||||
|     ) -> TList[app_commands.Choice[str]]: | ||||
|         server = self._servers.get_server_by_discord_id(interaction.guild.id) | ||||
|         auto_roles = self._auto_roles.get_auto_roles_by_server_id(server.server_id).select(lambda x: x.auto_role_id) | ||||
|         auto_roles = self._auto_roles.get_auto_roles_by_server_id(server.id).select(lambda x: x.id) | ||||
|         return [ | ||||
|             app_commands.Choice(name=auto_role, value=auto_role) | ||||
|             for auto_role in self._client_utils.get_auto_complete_list(auto_roles, current) | ||||
| @@ -79,7 +79,7 @@ class AutoRoleGroup(DiscordCommandABC): | ||||
|             color=int("ef9d0d", 16), | ||||
|         ) | ||||
|         server = self._servers.get_server_by_discord_id(ctx.guild.id) | ||||
|         auto_roles = self._auto_roles.get_auto_roles_by_server_id(server.server_id) | ||||
|         auto_roles = self._auto_roles.get_auto_roles_by_server_id(server.id) | ||||
|         if auto_roles.count() < 1: | ||||
|             await self._message_service.send_ctx_msg(ctx, self._t.transform("modules.auto_role.error.nothing_found")) | ||||
|             self._logger.trace(__name__, f"Finished command auto-role list") | ||||
| @@ -88,7 +88,7 @@ class AutoRoleGroup(DiscordCommandABC): | ||||
|         auto_role_id = "" | ||||
|         message_id = "" | ||||
|         for auto_role in auto_roles: | ||||
|             auto_role_id += f"\n{auto_role.auto_role_id}" | ||||
|             auto_role_id += f"\n{auto_role.id}" | ||||
|             message_id += f"\n{auto_role.discord_message_id}" | ||||
|  | ||||
|         embed.add_field( | ||||
| @@ -181,7 +181,7 @@ class AutoRoleGroup(DiscordCommandABC): | ||||
|             self._logger.trace(__name__, f"Finished command auto-role remove") | ||||
|             return | ||||
|  | ||||
|         for rule in self._auto_roles.get_auto_role_rules_by_auto_role_id(auto_role_from_db.auto_role_id): | ||||
|         for rule in self._auto_roles.get_auto_role_rules_by_auto_role_id(auto_role_from_db.id): | ||||
|             self._auto_roles.delete_auto_role_rule(rule) | ||||
|             self._logger.info(__name__, f"Removed auto-role rule {rule.role_id}") | ||||
|  | ||||
| @@ -392,12 +392,12 @@ class AutoRoleGroup(DiscordCommandABC): | ||||
|         self, interaction: discord.Interaction, current: str | ||||
|     ) -> TList[app_commands.Choice[str]]: | ||||
|         server = self._servers.get_server_by_discord_id(interaction.guild.id) | ||||
|         auto_roles = self._auto_roles.get_auto_roles_by_server_id(server.server_id).select(lambda x: x.auto_role_id) | ||||
|         auto_roles = self._auto_roles.get_auto_roles_by_server_id(server.id).select(lambda x: x.id) | ||||
|         rules = auto_roles.select_many(lambda ar: self._auto_roles.get_auto_role_rules_by_auto_role_id(ar)) | ||||
|         return [ | ||||
|             app_commands.Choice( | ||||
|                 name=f"{rule.auto_role_rule_id} {rule.emoji_name} {interaction.guild.get_role(int(rule.role_id))}", | ||||
|                 value=rule.auto_role_rule_id, | ||||
|                 name=f"{rule.id} {rule.emoji_name} {interaction.guild.get_role(int(rule.role_id))}", | ||||
|                 value=rule.id, | ||||
|             ) | ||||
|             for rule in self._client_utils.get_auto_complete_list(rules, current, lambda r: r.auto_role_rule_id) | ||||
|             for rule in self._client_utils.get_auto_complete_list(rules, current, lambda r: r.id) | ||||
|         ] | ||||
|   | ||||
| @@ -1,4 +1,3 @@ | ||||
| import discord | ||||
| from cpl_core.logging import LoggerABC | ||||
| from cpl_discord.service import DiscordBotServiceABC | ||||
| from cpl_query.extension import List | ||||
| @@ -50,7 +49,7 @@ class AutoRoleReactionHandler: | ||||
|             self._logger.debug(__name__, f"auto-role for message not found - skipping") | ||||
|             return | ||||
|  | ||||
|         rules: List[AutoRoleRule] = self._auto_roles.get_auto_role_rules_by_auto_role_id(auto_role.auto_role_id) | ||||
|         rules: List[AutoRoleRule] = self._auto_roles.get_auto_role_rules_by_auto_role_id(auto_role.id) | ||||
|         if rules.count() == 0: | ||||
|             self._logger.debug(__name__, f"auto-role rules not found - skipping") | ||||
|             return | ||||
|   | ||||
| @@ -59,7 +59,7 @@ class PingCommand(DiscordCommandABC): | ||||
|                 color=int("ef9d0d", 16), | ||||
|             ) | ||||
|             server = self._servers.get_server_by_discord_id(ctx.guild.id) | ||||
|             settings: BaseServerSettings = self._base_helper.get_config(server.discord_server_id) | ||||
|             settings: BaseServerSettings = self._base_helper.get_config(server.discord_id) | ||||
|             for server in settings.ping_urls: | ||||
|                 embed.add_field(name=server, value=f"{self._get_ping(server)} ms", inline=False) | ||||
|             await self._message_service.send_ctx_msg(ctx, embed) | ||||
|   | ||||
| @@ -73,7 +73,7 @@ class RegisterGroup(DiscordCommandABC): | ||||
|             return | ||||
|  | ||||
|         server = self._servers.get_server_by_discord_id(ctx.guild.id) | ||||
|         user = self._users.get_user_by_discord_id_and_server_id(member.id, server.server_id) | ||||
|         user = self._users.get_user_by_discord_id_and_server_id(member.id, server.id) | ||||
|         user.minecraft_id = minecraft_id | ||||
|         self._users.update_user(user) | ||||
|         self._db.save_changes() | ||||
|   | ||||
| @@ -52,7 +52,7 @@ class UnregisterGroup(DiscordCommandABC): | ||||
|         self._logger.debug(__name__, f"Received command register minecraft {ctx}") | ||||
|  | ||||
|         server = self._servers.get_server_by_discord_id(ctx.guild.id) | ||||
|         user = self._users.get_user_by_discord_id_and_server_id(member.id, server.server_id) | ||||
|         user = self._users.get_user_by_discord_id_and_server_id(member.id, server.id) | ||||
|         user.minecraft_id = None | ||||
|         self._users.update_user(user) | ||||
|         self._db.save_changes() | ||||
|   | ||||
| @@ -81,7 +81,7 @@ class UserGroup(DiscordCommandABC): | ||||
|             member = ctx.author | ||||
|  | ||||
|         server = self._servers.find_server_by_discord_id(ctx.guild.id) | ||||
|         user = self._users.find_user_by_discord_id_and_server_id(member.id, server.server_id) | ||||
|         user = self._users.find_user_by_discord_id_and_server_id(member.id, server.id) | ||||
|  | ||||
|         if atr == "xp": | ||||
|             if is_remove: | ||||
| @@ -125,8 +125,8 @@ class UserGroup(DiscordCommandABC): | ||||
|             member = ctx.author | ||||
|  | ||||
|         server = self._servers.find_server_by_discord_id(ctx.guild.id) | ||||
|         user = self._users.find_user_by_discord_id_and_server_id(member.id, server.server_id) | ||||
|         joins = self._user_joined_servers.get_user_joined_servers_by_user_id(user.user_id) | ||||
|         user = self._users.find_user_by_discord_id_and_server_id(member.id, server.id) | ||||
|         joins = self._user_joined_servers.get_user_joined_servers_by_user_id(user.id) | ||||
|  | ||||
|         embed = discord.Embed(title=member.name, description=member.name, color=int("ef9d0d", 16)) | ||||
|  | ||||
| @@ -206,7 +206,7 @@ class UserGroup(DiscordCommandABC): | ||||
|             member = ctx.author | ||||
|  | ||||
|         server = self._servers.find_server_by_discord_id(ctx.guild.id) | ||||
|         user = self._users.find_user_by_discord_id_and_server_id(member.id, server.server_id) | ||||
|         user = self._users.find_user_by_discord_id_and_server_id(member.id, server.id) | ||||
|  | ||||
|         if atr == "xp": | ||||
|             value = str(user.xp) | ||||
| @@ -241,7 +241,7 @@ class UserGroup(DiscordCommandABC): | ||||
|             member = ctx.author | ||||
|  | ||||
|         server = self._servers.find_server_by_discord_id(ctx.guild.id) | ||||
|         user = self._users.find_user_by_discord_id_and_server_id(member.id, server.server_id) | ||||
|         user = self._users.find_user_by_discord_id_and_server_id(member.id, server.id) | ||||
|  | ||||
|         if atr == "xp": | ||||
|             try: | ||||
| @@ -312,7 +312,7 @@ class UserGroup(DiscordCommandABC): | ||||
|             member = ctx.author | ||||
|  | ||||
|         server = self._servers.find_server_by_discord_id(ctx.guild.id) | ||||
|         user = self._users.find_user_by_discord_id_and_server_id(member.id, server.server_id) | ||||
|         user = self._users.find_user_by_discord_id_and_server_id(member.id, server.id) | ||||
|  | ||||
|         if atr == "xp": | ||||
|             user.xp = 0 | ||||
| @@ -321,7 +321,7 @@ class UserGroup(DiscordCommandABC): | ||||
|             await self._level.check_level(member) | ||||
|  | ||||
|         elif atr == "ontime": | ||||
|             self._user_joined_voice_channel.delete_user_joined_voice_channel_by_user_id(user.user_id) | ||||
|             self._user_joined_voice_channel.delete_user_joined_voice_channel_by_user_id(user.id) | ||||
|             self._db.save_changes() | ||||
|  | ||||
|         else: | ||||
|   | ||||
| @@ -64,7 +64,7 @@ class BaseOnCommandEvent(OnCommandABC): | ||||
|  | ||||
|         user: Optional[User] = None | ||||
|         try: | ||||
|             user = self._users.get_user_by_discord_id_and_server_id(dc_user_id, server.server_id) | ||||
|             user = self._users.get_user_by_discord_id_and_server_id(dc_user_id, server.id) | ||||
|         except Exception as e: | ||||
|             self._logger.error(__name__, f"Cannot get user {dc_user_id}", e) | ||||
|             return | ||||
|   | ||||
| @@ -85,7 +85,7 @@ class BaseOnMemberJoinEvent(OnMemberJoinABC): | ||||
|  | ||||
|         try: | ||||
|             server = self._servers.get_server_by_discord_id(member.guild.id) | ||||
|             user = self._users.find_user_by_discord_id_and_server_id(member.id, server.server_id) | ||||
|             user = self._users.find_user_by_discord_id_and_server_id(member.id, server.id) | ||||
|             if user is not None: | ||||
|                 self._user_joins.add_user_joined_server(UserJoinedServer(user, datetime.now())) | ||||
|                 self._db.save_changes() | ||||
| @@ -94,7 +94,7 @@ class BaseOnMemberJoinEvent(OnMemberJoinABC): | ||||
|             self._logger.debug(__name__, f"Add user: {member.id}") | ||||
|             self._users.add_user(User(member.id, 0, server)) | ||||
|             self._db.save_changes() | ||||
|             user = self._users.get_user_by_discord_id_and_server_id(member.id, server.server_id) | ||||
|             user = self._users.get_user_by_discord_id_and_server_id(member.id, server.id) | ||||
|             self._user_joins.add_user_joined_server(UserJoinedServer(user, datetime.now())) | ||||
|             self._db.save_changes() | ||||
|         except Exception as e: | ||||
|   | ||||
| @@ -47,12 +47,12 @@ class BaseOnMemberRemoveEvent(OnMemberRemoveABC): | ||||
|         try: | ||||
|             server = self._servers.get_server_by_discord_id(member.guild.id) | ||||
|  | ||||
|             user = self._users.find_user_by_discord_id_and_server_id(member.id, server.server_id) | ||||
|             user = self._users.find_user_by_discord_id_and_server_id(member.id, server.id) | ||||
|             if user is None: | ||||
|                 self._logger.error(__name__, f"Cannot find user {member}") | ||||
|                 return | ||||
|  | ||||
|             join = self._user_joins.get_active_user_joined_server_by_user_id(user.user_id) | ||||
|             join = self._user_joins.get_active_user_joined_server_by_user_id(user.id) | ||||
|             join.leaved_on = datetime.now() | ||||
|             self._user_joins.update_user_joined_server(join) | ||||
|             self._db.save_changes() | ||||
|   | ||||
| @@ -52,7 +52,7 @@ class BaseOnMessageDeleteEvent(OnMessageDeleteABC): | ||||
|  | ||||
|         user: Optional[User] = None | ||||
|         try: | ||||
|             user = self._users.find_user_by_discord_id_and_server_id(dc_user_id, server.server_id) | ||||
|             user = self._users.find_user_by_discord_id_and_server_id(dc_user_id, server.id) | ||||
|         except Exception as e: | ||||
|             self._logger.error(__name__, f"Cannot get user {dc_user_id}", e) | ||||
|             return | ||||
|   | ||||
| @@ -57,7 +57,7 @@ class BaseOnMessageEvent(OnMessageABC): | ||||
|  | ||||
|         user: Optional[User] = None | ||||
|         try: | ||||
|             user = self._users.find_user_by_discord_id_and_server_id(dc_user_id, server.server_id) | ||||
|             user = self._users.find_user_by_discord_id_and_server_id(dc_user_id, server.id) | ||||
|         except Exception as e: | ||||
|             self._logger.error(__name__, f"Cannot get user {dc_user_id}", e) | ||||
|             return | ||||
|   | ||||
| @@ -48,10 +48,10 @@ class BaseOnVoiceStateUpdateEvent(OnVoiceStateUpdateABC): | ||||
|  | ||||
|         self._logger.info(__name__, f"Module {type(self)} loaded") | ||||
|  | ||||
|     def _update_voice_state(self, joined: bool, dc_user_id: int, dc_channel_id: int, server: Server): | ||||
|     def _update_voice_state(self, joined: bool, dc_user_id: int, channel_id: int, server: Server): | ||||
|         user: Optional[User] = None | ||||
|         try: | ||||
|             user = self._users.get_user_by_discord_id_and_server_id(dc_user_id, server.server_id) | ||||
|             user = self._users.get_user_by_discord_id_and_server_id(dc_user_id, server.id) | ||||
|         except Exception as e: | ||||
|             self._logger.error(__name__, f"Cannot get user {dc_user_id}", e) | ||||
|             return | ||||
| @@ -62,20 +62,18 @@ class BaseOnVoiceStateUpdateEvent(OnVoiceStateUpdateABC): | ||||
|  | ||||
|         try: | ||||
|             if joined: | ||||
|                 join = UserJoinedVoiceChannel(user, dc_channel_id, datetime.now()) | ||||
|                 join = UserJoinedVoiceChannel(user, channel_id, datetime.now()) | ||||
|                 self._user_joins_vc.add_user_joined_voice_channel(join) | ||||
|                 self._db.save_changes() | ||||
|                 return | ||||
|  | ||||
|             settings: BaseServerSettings = self._base_helper.get_config(server.discord_server_id) | ||||
|             settings: BaseServerSettings = self._base_helper.get_config(server.discord_id) | ||||
|  | ||||
|             join = self._user_joins_vc.get_active_user_joined_voice_channel_by_user_id(user.user_id) | ||||
|             join = self._user_joins_vc.get_active_user_joined_voice_channel_by_user_id(user.id) | ||||
|             join.leaved_on = datetime.now() | ||||
|  | ||||
|             # ontime as hours | ||||
|             ontime = round((join.leaved_on - join.joined_on).total_seconds() / 3600, 2) | ||||
|             old_xp = user.xp | ||||
|             user.xp += round(ontime * settings.xp_per_ontime_hour) | ||||
|             user.xp += round(join.time * settings.xp_per_ontime_hour) | ||||
|  | ||||
|             self._user_joins_vc.update_user_joined_voice_channel(join) | ||||
|             self._users.update_user(user) | ||||
| @@ -83,7 +81,7 @@ class BaseOnVoiceStateUpdateEvent(OnVoiceStateUpdateABC): | ||||
|  | ||||
|             self._logger.debug( | ||||
|                 __name__, | ||||
|                 f"User {user} leaved_on {join.leaved_on}. Ontime: {ontime}h | xp: from {old_xp} to {user.xp}", | ||||
|                 f"User {user} leaved_on {join.leaved_on}. Ontime: {join.time}h | xp: from {old_xp} to {user.xp}", | ||||
|             ) | ||||
|         except Exception as e: | ||||
|             self._logger.error(__name__, f"Ontime validation failed", e) | ||||
|   | ||||
| @@ -43,7 +43,7 @@ class BaseOnVoiceStateUpdateEventHelpChannel(OnVoiceStateUpdateABC): | ||||
|     ): | ||||
|         self._logger.debug(__name__, f"Module {type(self)} started") | ||||
|         server = self._servers.get_server_by_discord_id(member.guild.id) | ||||
|         settings: BaseServerSettings = self._base_helper.get_config(server.discord_server_id) | ||||
|         settings: BaseServerSettings = self._base_helper.get_config(server.discord_id) | ||||
|         if after.channel is None or after.channel.id != settings.help_voice_channel_id: | ||||
|             return | ||||
|  | ||||
|   | ||||
| @@ -62,7 +62,7 @@ class BaseReactionHandler: | ||||
|             return | ||||
|  | ||||
|         server = self._servers.get_server_by_discord_id(guild.id) | ||||
|         user = self._users.get_user_by_discord_id_and_server_id(member.id, server.server_id) | ||||
|         user = self._users.get_user_by_discord_id_and_server_id(member.id, server.id) | ||||
|         settings: BaseServerSettings = self._base_helper.get_config(guild.id) | ||||
|  | ||||
|         if r_type == "add": | ||||
|   | ||||
| @@ -144,7 +144,7 @@ class DatabaseOnReadyEvent(OnReadyABC): | ||||
|                 if server is None: | ||||
|                     self._logger.fatal(__name__, f"Server not found in database: {g.id}") | ||||
|  | ||||
|                 client = self._clients.find_client_by_server_id(server.server_id) | ||||
|                 client = self._clients.find_client_by_server_id(server.id) | ||||
|                 if client is not None: | ||||
|                     continue | ||||
|  | ||||
| @@ -156,7 +156,7 @@ class DatabaseOnReadyEvent(OnReadyABC): | ||||
|                 self._clients.add_client(Client(self._bot.user.id, 0, 0, 0, 0, 0, server)) | ||||
|                 self._db_context.save_changes() | ||||
|  | ||||
|                 client = self._clients.find_client_by_server_id(server.server_id) | ||||
|                 client = self._clients.find_client_by_server_id(server.id) | ||||
|                 if client is None: | ||||
|                     self._logger.fatal( | ||||
|                         __name__, | ||||
| @@ -187,7 +187,7 @@ class DatabaseOnReadyEvent(OnReadyABC): | ||||
|                         self._logger.trace(__name__, f"User {u.id} is ignored, because its a bot") | ||||
|                         continue | ||||
|  | ||||
|                     user = self._users.find_user_by_discord_id_and_server_id(u.id, server.server_id) | ||||
|                     user = self._users.find_user_by_discord_id_and_server_id(u.id, server.id) | ||||
|                     if user is not None: | ||||
|                         continue | ||||
|  | ||||
| @@ -220,11 +220,11 @@ class DatabaseOnReadyEvent(OnReadyABC): | ||||
|                         self._logger.trace(__name__, f"User {u.id} is ignored, because its a bot") | ||||
|                         continue | ||||
|  | ||||
|                     user = self._users.find_user_by_discord_id_and_server_id(u.id, server.server_id) | ||||
|                     user = self._users.find_user_by_discord_id_and_server_id(u.id, server.id) | ||||
|                     if user is None: | ||||
|                         self._logger.fatal(__name__, f"User not found in database: {u.id}") | ||||
|  | ||||
|                     join = self._user_joins.find_active_user_joined_server_by_user_id(user.user_id) | ||||
|                     join = self._user_joins.find_active_user_joined_server_by_user_id(user.id) | ||||
|                     if join is not None: | ||||
|                         continue | ||||
|  | ||||
| @@ -253,7 +253,7 @@ class DatabaseOnReadyEvent(OnReadyABC): | ||||
|             joins = self._user_joins.get_user_joined_servers() | ||||
|             for join in joins: | ||||
|                 join: UserJoinedServer = join | ||||
|                 if join.user.server.discord_server_id != guild.id: | ||||
|                 if join.user.server.discord_id != guild.id: | ||||
|                     continue | ||||
|  | ||||
|                 if join.leaved_on is not None: | ||||
| @@ -285,11 +285,11 @@ class DatabaseOnReadyEvent(OnReadyABC): | ||||
|                         self._logger.trace(__name__, f"User {member.id} is ignored, because its a bot") | ||||
|                         continue | ||||
|  | ||||
|                     user = self._users.find_user_by_discord_id_and_server_id(member.id, server.server_id) | ||||
|                     user = self._users.find_user_by_discord_id_and_server_id(member.id, server.id) | ||||
|                     if user is None: | ||||
|                         self._logger.fatal(__name__, f"User not found in database: {member.id}") | ||||
|  | ||||
|                     joins = self._user_joins_vc.find_active_user_joined_voice_channels_by_user_id(user.user_id) | ||||
|                     joins = self._user_joins_vc.find_active_user_joined_voice_channels_by_user_id(user.id) | ||||
|                     if joins is None or len(joins) == 0: | ||||
|                         continue | ||||
|  | ||||
| @@ -318,7 +318,7 @@ class DatabaseOnReadyEvent(OnReadyABC): | ||||
|                     if member.voice is None: | ||||
|                         continue | ||||
|  | ||||
|                     user = self._users.find_user_by_discord_id_and_server_id(member.id, server.server_id) | ||||
|                     user = self._users.find_user_by_discord_id_and_server_id(member.id, server.id) | ||||
|                     if user is None: | ||||
|                         self._logger.fatal(__name__, f"User not found in database: {member.id}") | ||||
|  | ||||
| @@ -345,11 +345,11 @@ class DatabaseOnReadyEvent(OnReadyABC): | ||||
|                         self._logger.trace(__name__, f"User {member.id} is ignored, because its a bot") | ||||
|                         continue | ||||
|  | ||||
|                     user = self._users.find_user_by_discord_id_and_server_id(member.id, server.server_id) | ||||
|                     user = self._users.find_user_by_discord_id_and_server_id(member.id, server.id) | ||||
|                     if user is None: | ||||
|                         self._logger.fatal(__name__, f"User not found in database: {member.id}") | ||||
|  | ||||
|                     joins = self._user_joined_gs.find_active_user_joined_game_servers_by_user_id(user.user_id) | ||||
|                     joins = self._user_joined_gs.find_active_user_joined_game_servers_by_user_id(user.id) | ||||
|                     if joins is None or len(joins) == 0: | ||||
|                         continue | ||||
|  | ||||
|   | ||||
| @@ -108,7 +108,7 @@ class LevelGroup(DiscordCommandABC): | ||||
|         self, interaction: discord.Interaction, current: str | ||||
|     ) -> TList[app_commands.Choice[str]]: | ||||
|         server = self._servers.get_server_by_discord_id(interaction.guild.id) | ||||
|         levels = self._levels.get_levels_by_server_id(server.server_id).select(lambda l: l.name) | ||||
|         levels = self._levels.get_levels_by_server_id(server.id).select(lambda l: l.name) | ||||
|         return [ | ||||
|             app_commands.Choice(name=level, value=level) | ||||
|             for level in self._client_utils.get_auto_complete_list(levels, current) | ||||
| @@ -130,7 +130,7 @@ class LevelGroup(DiscordCommandABC): | ||||
|             return | ||||
|  | ||||
|         server = self._servers.get_server_by_discord_id(ctx.guild.id) | ||||
|         levels = self._levels.get_levels_by_server_id(server.server_id) | ||||
|         levels = self._levels.get_levels_by_server_id(server.id) | ||||
|         if levels.count() < 1: | ||||
|             await self._message_service.send_ctx_msg(ctx, self._t.transform("modules.level.error.nothing_found")) | ||||
|             self._logger.trace(__name__, f"Finished command level list") | ||||
| @@ -187,7 +187,7 @@ class LevelGroup(DiscordCommandABC): | ||||
|  | ||||
|         server = self._servers.get_server_by_discord_id(ctx.guild.id) | ||||
|         level = Level(name, color, min_xp, permissions, server) | ||||
|         levels = self._levels.get_levels_by_server_id(server.server_id) | ||||
|         levels = self._levels.get_levels_by_server_id(server.id) | ||||
|  | ||||
|         if levels.where(lambda l: l.name == level.name).first_or_default() is not None: | ||||
|             self._logger.debug(__name__, f"Level with name {level.name} already exists") | ||||
| @@ -261,7 +261,7 @@ class LevelGroup(DiscordCommandABC): | ||||
|  | ||||
|         server = self._servers.get_server_by_discord_id(ctx.guild.id) | ||||
|         level_from_db = ( | ||||
|             self._levels.get_levels_by_server_id(server.server_id).where(lambda l: l.name == level).single_or_default() | ||||
|             self._levels.get_levels_by_server_id(server.id).where(lambda l: l.name == level).single_or_default() | ||||
|         ) | ||||
|         if level_from_db is None: | ||||
|             await self._message_service.send_ctx_msg( | ||||
| @@ -353,7 +353,7 @@ class LevelGroup(DiscordCommandABC): | ||||
|  | ||||
|         server = self._servers.get_server_by_discord_id(ctx.guild.id) | ||||
|         level_from_db = ( | ||||
|             self._levels.get_levels_by_server_id(server.server_id).where(lambda l: l.name == level).first_or_default() | ||||
|             self._levels.get_levels_by_server_id(server.id).where(lambda l: l.name == level).first_or_default() | ||||
|         ) | ||||
|         if level_from_db is None: | ||||
|             self._logger.debug(__name__, f"level {level} not found") | ||||
| @@ -399,9 +399,9 @@ class LevelGroup(DiscordCommandABC): | ||||
|             return | ||||
|  | ||||
|         server = self._servers.get_server_by_discord_id(ctx.guild.id) | ||||
|         user = self._users.get_user_by_discord_id_and_server_id(member.id, server.server_id) | ||||
|         user = self._users.get_user_by_discord_id_and_server_id(member.id, server.id) | ||||
|         level = self._level_service.get_level(user) | ||||
|         levels = self._levels.get_levels_by_server_id(server.server_id).order_by(lambda l: l.min_xp) | ||||
|         levels = self._levels.get_levels_by_server_id(server.id).order_by(lambda l: l.min_xp) | ||||
|  | ||||
|         if level == levels.first(): | ||||
|             await self._message_service.send_ctx_msg( | ||||
| @@ -441,9 +441,9 @@ class LevelGroup(DiscordCommandABC): | ||||
|             return | ||||
|  | ||||
|         server = self._servers.get_server_by_discord_id(ctx.guild.id) | ||||
|         user = self._users.get_user_by_discord_id_and_server_id(member.id, server.server_id) | ||||
|         user = self._users.get_user_by_discord_id_and_server_id(member.id, server.id) | ||||
|         level = self._level_service.get_level(user) | ||||
|         levels = self._levels.get_levels_by_server_id(server.server_id).order_by(lambda l: l.min_xp) | ||||
|         levels = self._levels.get_levels_by_server_id(server.id).order_by(lambda l: l.min_xp) | ||||
|  | ||||
|         if level.name == levels.last().name: | ||||
|             await self._message_service.send_ctx_msg( | ||||
| @@ -482,11 +482,9 @@ class LevelGroup(DiscordCommandABC): | ||||
|             return | ||||
|  | ||||
|         server = self._servers.get_server_by_discord_id(ctx.guild.id) | ||||
|         user = self._users.get_user_by_discord_id_and_server_id(member.id, server.server_id) | ||||
|         user = self._users.get_user_by_discord_id_and_server_id(member.id, server.id) | ||||
|         current_level = self._level_service.get_level(user) | ||||
|         new_level = ( | ||||
|             self._levels.get_levels_by_server_id(server.server_id).where(lambda l: l.name == level).single_or_default() | ||||
|         ) | ||||
|         new_level = self._levels.get_levels_by_server_id(server.id).where(lambda l: l.name == level).single_or_default() | ||||
|  | ||||
|         if new_level is None: | ||||
|             await self._message_service.send_ctx_msg( | ||||
|   | ||||
| @@ -47,7 +47,7 @@ class LevelSeeder(DataSeederABC): | ||||
|                 ) | ||||
|                 self._logger.debug(__name__, f"Created role {level.name}") | ||||
|  | ||||
|             levels = self._levels.find_levels_by_server_id(server.server_id) | ||||
|             levels = self._levels.find_levels_by_server_id(server.id) | ||||
|             if levels is None or levels.where(lambda l: l.name == level.name).first_or_default() is None: | ||||
|                 self._levels.add_level(level) | ||||
|                 self._logger.debug(__name__, f"Saved level {level.name}") | ||||
| @@ -69,7 +69,7 @@ class LevelSeeder(DataSeederABC): | ||||
|             if server is None: | ||||
|                 continue | ||||
|  | ||||
|             levels = self._levels.find_levels_by_server_id(server.server_id) | ||||
|             levels = self._levels.find_levels_by_server_id(server.id) | ||||
|             if levels is not None and levels.count() > 0: | ||||
|                 # create levels from db | ||||
|                 for level in levels: | ||||
|   | ||||
| @@ -1,5 +1,3 @@ | ||||
| import asyncio | ||||
|  | ||||
| import discord | ||||
| from cpl_core.configuration import ConfigurationABC | ||||
| from cpl_core.database.context import DatabaseContextABC | ||||
| @@ -41,7 +39,7 @@ class LevelService: | ||||
|         self._t = t | ||||
|  | ||||
|     def get_level(self, user: User) -> Level: | ||||
|         levels_by_server = self._levels.get_levels_by_server_id(user.server.server_id) | ||||
|         levels_by_server = self._levels.get_levels_by_server_id(user.server.id) | ||||
|         levels = levels_by_server.order_by(lambda l: l.min_xp).where(lambda l: user.xp >= l.min_xp) | ||||
|  | ||||
|         if levels.count() == 0: | ||||
| @@ -50,8 +48,8 @@ class LevelService: | ||||
|         return levels.last() | ||||
|  | ||||
|     async def set_level(self, user: User): | ||||
|         level_names = self._levels.get_levels_by_server_id(user.server.server_id).select(lambda l: l.name) | ||||
|         guild: Guild = self._bot.guilds.where(lambda g: g.id == user.server.discord_server_id).single() | ||||
|         level_names = self._levels.get_levels_by_server_id(user.server.id).select(lambda l: l.name) | ||||
|         guild: Guild = self._bot.guilds.where(lambda g: g.id == user.server.discord_id).single() | ||||
|         member: Member = guild.members.where(lambda m: m.id == user.discord_id).single() | ||||
|  | ||||
|         level = self.get_level(user) | ||||
| @@ -89,7 +87,7 @@ class LevelService: | ||||
|             return | ||||
|  | ||||
|         server = self._servers.get_server_by_discord_id(member.guild.id) | ||||
|         user = self._users.find_user_by_discord_id_and_server_id(member.id, server.server_id) | ||||
|         user = self._users.find_user_by_discord_id_and_server_id(member.id, server.id) | ||||
|         if user is None: | ||||
|             self._logger.warn(__name__, f"User not found {member.guild.name}@{member.name}") | ||||
|             return | ||||
|   | ||||
| @@ -66,7 +66,7 @@ class StatsGroup(DiscordCommandABC): | ||||
|         ) | ||||
|  | ||||
|         server = self._servers.get_server_by_discord_id(ctx.guild.id) | ||||
|         stats = self._stats.get_statistics_by_server_id(server.server_id) | ||||
|         stats = self._stats.get_statistics_by_server_id(server.id) | ||||
|  | ||||
|         if stats.count() == 0: | ||||
|             await self._message_service.send_ctx_msg(ctx, self._t.transform("modules.stats.list.nothing_found")) | ||||
| @@ -103,7 +103,7 @@ class StatsGroup(DiscordCommandABC): | ||||
|  | ||||
|         try: | ||||
|             server = self._servers.get_server_by_discord_id(ctx.guild.id) | ||||
|             stats = self._stats.get_statistics_by_server_id(server.server_id) | ||||
|             stats = self._stats.get_statistics_by_server_id(server.id) | ||||
|             statistic = stats.where(lambda s: s.name == name).single() | ||||
|             result = await self._statistic.execute(statistic.code, server) | ||||
|  | ||||
| @@ -132,7 +132,7 @@ class StatsGroup(DiscordCommandABC): | ||||
|         self, interaction: discord.Interaction, current: str | ||||
|     ) -> TList[app_commands.Choice[str]]: | ||||
|         server = self._servers.get_server_by_discord_id(interaction.guild.id) | ||||
|         stats = self._stats.get_statistics_by_server_id(server.server_id) | ||||
|         stats = self._stats.get_statistics_by_server_id(server.id) | ||||
|         return [ | ||||
|             app_commands.Choice(name=f"{statistic.name}: {statistic.description}", value=statistic.name) | ||||
|             for statistic in stats | ||||
| @@ -171,7 +171,7 @@ class StatsGroup(DiscordCommandABC): | ||||
|  | ||||
|         try: | ||||
|             server = self._servers.get_server_by_discord_id(ctx.guild.id) | ||||
|             stats = self._stats.get_statistics_by_server_id(server.server_id) | ||||
|             stats = self._stats.get_statistics_by_server_id(server.id) | ||||
|             statistic = stats.where(lambda s: s.name == name).single() | ||||
|             form = AddStatisticForm( | ||||
|                 server, | ||||
| @@ -196,7 +196,7 @@ class StatsGroup(DiscordCommandABC): | ||||
|         self, interaction: discord.Interaction, current: str | ||||
|     ) -> TList[app_commands.Choice[str]]: | ||||
|         server = self._servers.get_server_by_discord_id(interaction.guild.id) | ||||
|         stats = self._stats.get_statistics_by_server_id(server.server_id) | ||||
|         stats = self._stats.get_statistics_by_server_id(server.id) | ||||
|         return [ | ||||
|             app_commands.Choice(name=f"{statistic.name}: {statistic.description}", value=statistic.name) | ||||
|             for statistic in stats | ||||
| @@ -211,7 +211,7 @@ class StatsGroup(DiscordCommandABC): | ||||
|  | ||||
|         try: | ||||
|             server = self._servers.get_server_by_discord_id(ctx.guild.id) | ||||
|             statistic = self._stats.get_statistic_by_name(name, server.server_id) | ||||
|             statistic = self._stats.get_statistic_by_name(name, server.id) | ||||
|             self._stats.delete_statistic(statistic) | ||||
|             self._db.save_changes() | ||||
|             await self._message_service.send_ctx_msg(ctx, self._t.transform("modules.stats.remove.success")) | ||||
| @@ -225,7 +225,7 @@ class StatsGroup(DiscordCommandABC): | ||||
|         self, interaction: discord.Interaction, current: str | ||||
|     ) -> TList[app_commands.Choice[str]]: | ||||
|         server = self._servers.get_server_by_discord_id(interaction.guild.id) | ||||
|         stats = self._stats.get_statistics_by_server_id(server.server_id) | ||||
|         stats = self._stats.get_statistics_by_server_id(server.id) | ||||
|         return [ | ||||
|             app_commands.Choice(name=f"{statistic.name}: {statistic.description}", value=statistic.name) | ||||
|             for statistic in stats | ||||
|   | ||||
| @@ -1,5 +1,3 @@ | ||||
| from abc import abstractmethod | ||||
|  | ||||
| from cpl_discord.service import DiscordBotServiceABC | ||||
| from cpl_query.extension import List | ||||
| from discord import Guild | ||||
| @@ -49,22 +47,20 @@ class StatisticService: | ||||
|         self._bot = bot | ||||
|  | ||||
|     async def execute(self, code: str, server: Server) -> StatisticResult: | ||||
|         guild = self._bot.guilds.where(lambda g: g.id == server.discord_server_id).single() | ||||
|         guild = self._bot.guilds.where(lambda g: g.id == server.discord_id).single() | ||||
|  | ||||
|         return await self.get_data( | ||||
|             code, | ||||
|             self._auto_roles.get_auto_roles().where(lambda x: x.server.server_id == server.server_id), | ||||
|             self._clients.get_clients().where(lambda x: x.server.server_id == server.server_id), | ||||
|             self._auto_roles.get_auto_roles().where(lambda x: x.server.id == server.id), | ||||
|             self._clients.get_clients().where(lambda x: x.server.id == server.id), | ||||
|             self._known_users.get_users(), | ||||
|             self._levels.get_levels().where(lambda x: x.server.server_id == server.server_id), | ||||
|             self._servers.get_servers().where(lambda x: x.server_id == server.server_id), | ||||
|             self._user_joined_servers.get_user_joined_servers().where( | ||||
|                 lambda x: x.user.server.server_id == server.server_id | ||||
|             ), | ||||
|             self._levels.get_levels().where(lambda x: x.server.id == server.id), | ||||
|             self._servers.get_servers().where(lambda x: x.id == server.id), | ||||
|             self._user_joined_servers.get_user_joined_servers().where(lambda x: x.user.server.id == server.id), | ||||
|             self._user_joined_voice_channel.get_user_joined_voice_channels().where( | ||||
|                 lambda x: x.user.server.server_id == server.server_id | ||||
|                 lambda x: x.user.server.id == server.id | ||||
|             ), | ||||
|             self._users.get_users().where(lambda x: x.server.server_id == server.server_id), | ||||
|             self._users.get_users().where(lambda x: x.server.id == server.id), | ||||
|             guild, | ||||
|         ) | ||||
|  | ||||
|   | ||||
| @@ -1,6 +1,5 @@ | ||||
| import discord | ||||
| from cpl_core.database.context import DatabaseContextABC | ||||
| from cpl_query.extension import List | ||||
| from cpl_translation import TranslatePipe | ||||
| from discord import ui, TextStyle | ||||
|  | ||||
| @@ -45,7 +44,7 @@ class AddStatisticForm(ui.Modal): | ||||
|  | ||||
|     async def on_submit(self, interaction: discord.Interaction): | ||||
|         statistic = ( | ||||
|             self._stats.get_statistics_by_server_id(self._server.server_id) | ||||
|             self._stats.get_statistics_by_server_id(self._server.id) | ||||
|             .where(lambda s: s.name == self._name) | ||||
|             .single_or_default() | ||||
|         ) | ||||
|   | ||||
| @@ -95,7 +95,7 @@ class ApiKeyGroup(DiscordCommandABC): | ||||
|         self._logger.debug(__name__, f"Received command api-key add {ctx}: {identifier}") | ||||
|  | ||||
|         server = self._servers.get_server_by_discord_id(ctx.guild.id) | ||||
|         user = self._users.get_user_by_discord_id_and_server_id(ctx.author.id, server.server_id) | ||||
|         user = self._users.get_user_by_discord_id_and_server_id(ctx.author.id, server.id) | ||||
|         api_key = ApiKey(identifier, str(uuid.uuid4()), user) | ||||
|         self._api_keys.add_api_key(api_key) | ||||
|         self._db.save_changes() | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "kdb-web", | ||||
|     "version": "0.3.dev78", | ||||
|     "version": "0.3.dev130", | ||||
|     "scripts": { | ||||
|         "ng": "ng", | ||||
|         "update-version": "ts-node-esm update-version.ts", | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| <main [class]="themeName"> | ||||
|  | ||||
|   <ng-container *ngIf="isLoggedIn; else login"> | ||||
|     <app-header></app-header> | ||||
|  | ||||
| @@ -33,4 +34,4 @@ | ||||
|     </ng-template> | ||||
|   </p-confirmDialog> | ||||
|   <p-toast></p-toast> | ||||
| </main> | ||||
| </main> | ||||
|   | ||||
| @@ -1,14 +1,21 @@ | ||||
| import { Component, OnInit } from '@angular/core'; | ||||
| import { TranslateService } from '@ngx-translate/core'; | ||||
| import { PrimeNGConfig } from 'primeng/api'; | ||||
| import { AuthService } from './services/auth/auth.service'; | ||||
| import { SocketService } from './services/socket/socket.service'; | ||||
| import { ThemeService } from './services/theme/theme.service'; | ||||
| import { Component, OnInit } from "@angular/core"; | ||||
| import { TranslateService } from "@ngx-translate/core"; | ||||
| import { PrimeNGConfig } from "primeng/api"; | ||||
| import { AuthService } from "./services/auth/auth.service"; | ||||
| import { SocketService } from "./services/socket/socket.service"; | ||||
| import { ThemeService } from "./services/theme/theme.service"; | ||||
| import { ActivatedRoute, Router } from "@angular/router"; | ||||
| import { SpinnerService } from "./services/spinner/spinner.service"; | ||||
| import { DataService } from "./services/data/data.service"; | ||||
| import { SidebarService } from "./services/sidebar/sidebar.service"; | ||||
| import { Server } from "./models/data/server.model"; | ||||
| import { Queries } from "./models/graphql/queries.model"; | ||||
| import { Query } from "./models/graphql/query.model"; | ||||
|  | ||||
| @Component({ | ||||
|   selector: 'app-root', | ||||
|   templateUrl: './app.component.html', | ||||
|   styleUrls: ['./app.component.scss'] | ||||
|   selector: "app-root", | ||||
|   templateUrl: "./app.component.html", | ||||
|   styleUrls: ["./app.component.scss"] | ||||
| }) | ||||
| export class AppComponent implements OnInit { | ||||
|  | ||||
| @@ -22,7 +29,7 @@ export class AppComponent implements OnInit { | ||||
|     private themeService: ThemeService, | ||||
|     private socket: SocketService, | ||||
|     private translateService: TranslateService, | ||||
|     private config: PrimeNGConfig | ||||
|     private config: PrimeNGConfig, | ||||
|   ) { | ||||
|     this.themeService.sidebarWidth$.subscribe(value => { | ||||
|       this.sidebarWidth = value; | ||||
| @@ -36,7 +43,7 @@ export class AppComponent implements OnInit { | ||||
|   } | ||||
|  | ||||
|   ngOnInit(): void { | ||||
|     this.translateService.setDefaultLang('en'); | ||||
|     this.translateService.setDefaultLang("en"); | ||||
|  | ||||
|     this.themeService.loadTheme(); | ||||
|     this.socket.startSocket(); | ||||
| @@ -45,7 +52,7 @@ export class AppComponent implements OnInit { | ||||
|   loadLang(): void { | ||||
|     let lang = localStorage.getItem(`default_lang`); | ||||
|     if (!lang) { | ||||
|       lang = 'en'; | ||||
|       lang = "en"; | ||||
|       this.setLang(lang); | ||||
|     } | ||||
|     this.translate(lang); | ||||
| @@ -57,7 +64,7 @@ export class AppComponent implements OnInit { | ||||
|  | ||||
|   translate(lang: string) { | ||||
|     this.translateService.use(lang); | ||||
|     this.translateService.get('primeng').subscribe(res => this.config.setTranslation(res)); | ||||
|     this.translateService.get("primeng").subscribe(res => this.config.setTranslation(res)); | ||||
|   } | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| import { Component, OnInit } from "@angular/core"; | ||||
| import { LangChangeEvent, TranslateService } from "@ngx-translate/core"; | ||||
| import { TranslateService } from "@ngx-translate/core"; | ||||
| import { MenuItem } from "primeng/api"; | ||||
| import { AuthService } from "src/app/services/auth/auth.service"; | ||||
| import { ThemeService } from "src/app/services/theme/theme.service"; | ||||
| @@ -21,15 +21,6 @@ export class SidebarComponent implements OnInit { | ||||
|     private themeService: ThemeService, | ||||
|     private sidebar: SidebarService | ||||
|   ) { | ||||
|     this.translateService.onLangChange.subscribe((event: LangChangeEvent) => { | ||||
|       this.sidebar.setMenu(); | ||||
|     }); | ||||
|  | ||||
|     this.themeService.isSidebarOpen$.subscribe(value => { | ||||
|       this.isSidebarOpen = value; | ||||
|       this.sidebar.setMenu(); | ||||
|     }); | ||||
|  | ||||
|     this.sidebar.menuItems$.subscribe(value => { | ||||
|       this.menuItems = value; | ||||
|     }); | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| <ng-container *ngIf="spinnerService.showSpinnerState"> | ||||
| <ng-container *ngIf="showSpinnerState"> | ||||
|     <div class="spinner-component-wrapper"> | ||||
|         <div class="spinner-wrapper"> | ||||
|             <p-progressSpinner styleClass="custom-spinner" animationDuration=".8s"></p-progressSpinner> | ||||
|         </div> | ||||
|     </div> | ||||
| </ng-container> | ||||
| </ng-container> | ||||
|   | ||||
| @@ -8,9 +8,15 @@ import { SpinnerService } from 'src/app/services/spinner/spinner.service'; | ||||
| }) | ||||
| export class SpinnerComponent implements OnInit { | ||||
|  | ||||
|   showSpinnerState: boolean = false; | ||||
|  | ||||
|   constructor( | ||||
|     public spinnerService: SpinnerService | ||||
|   ) { } | ||||
|   ) { | ||||
|     this.spinnerService.showSpinnerState$.subscribe(value => { | ||||
|       this.showSpinnerState = value; | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   ngOnInit(): void { | ||||
|   } | ||||
|   | ||||
| @@ -1,13 +1,28 @@ | ||||
| import { AuthRoles } from "./auth-roles.enum"; | ||||
| import {AuthRoles} from "./auth-roles.enum"; | ||||
|  | ||||
| export interface AuthUserDTO { | ||||
|     id?: number; | ||||
|     firstName: string | null; | ||||
|     lastName: string | null; | ||||
|     email: string | null; | ||||
|     password: string | null; | ||||
|     isConfirmed?: boolean | ||||
|     authRole?: AuthRoles; | ||||
|     createdAt?: string; | ||||
|     modifiedAt?: string; | ||||
|   id?: number; | ||||
|   firstName: string | null; | ||||
|   lastName: string | null; | ||||
|   email: string | null; | ||||
|   password: string | null; | ||||
|   isConfirmed?: boolean; | ||||
|   authRole?: AuthRoles; | ||||
|   users?: UserDTO[]; | ||||
|   createdAt?: string; | ||||
|   modifiedAt?: string; | ||||
| } | ||||
|  | ||||
|  | ||||
| export interface UserDTO { | ||||
|   id: number; | ||||
|   discordId: number; | ||||
|   xp: number; | ||||
|   minecraftId: number | null; | ||||
|   server: number; | ||||
|   createdAt: string; | ||||
|   modifiedAt: string; | ||||
|   isTechnician: boolean; | ||||
|   isAdmin: boolean; | ||||
|   isModerator: boolean; | ||||
| } | ||||
|   | ||||
							
								
								
									
										17
									
								
								kdb-web/src/app/models/data/level.model.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								kdb-web/src/app/models/data/level.model.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| import { Data } from "./data.model"; | ||||
| import { Server, ServerFilter } from "./server.model"; | ||||
|  | ||||
| export interface Level extends Data { | ||||
|   id?: number; | ||||
|   name?: string; | ||||
|   color?: string; | ||||
|   minXp?: number; | ||||
|   permissions?: string; | ||||
|   server?: Server; | ||||
| } | ||||
|  | ||||
| export interface LevelFilter { | ||||
|   id?: number; | ||||
|   name?: String; | ||||
|   server?: ServerFilter; | ||||
| } | ||||
| @@ -1,8 +1,10 @@ | ||||
| import { Data } from "./data.model"; | ||||
| import { User } from "./user.model"; | ||||
| import { Level } from "./level.model"; | ||||
|  | ||||
| export interface Server extends Data { | ||||
|   id?: number; | ||||
|   discordId?: number; | ||||
|   discordId?: String; | ||||
|   name?: string; | ||||
|   iconURL?: string; | ||||
|   autoRoleCount?: number; | ||||
| @@ -10,7 +12,13 @@ export interface Server extends Data { | ||||
|   clientCount?: number; | ||||
|   clients?: []; | ||||
|   levelCount?: number; | ||||
|   levels?: []; | ||||
|   levels?: Level[]; | ||||
|   userCount?: number; | ||||
|   users?: []; | ||||
|   users?: User[]; | ||||
| } | ||||
|  | ||||
| export interface ServerFilter { | ||||
|   id?: number; | ||||
|   discordId?: String; | ||||
|   name?: String; | ||||
| } | ||||
|   | ||||
							
								
								
									
										39
									
								
								kdb-web/src/app/models/data/user.model.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								kdb-web/src/app/models/data/user.model.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| import { Data } from "./data.model"; | ||||
| import { Level, LevelFilter } from "./level.model"; | ||||
| import { Server, ServerFilter } from "./server.model"; | ||||
| import { UserJoinedServer } from "./user_joined_server.model"; | ||||
| import { UserJoinedVoiceChannel } from "./user_joined_voice_channel.model"; | ||||
| import { UserJoinedGameServer } from "./user_joined_game_server.model"; | ||||
|  | ||||
| export interface User extends Data { | ||||
|   id?: number; | ||||
|   discordId?: number; | ||||
|   name?: string; | ||||
|   xp?: number; | ||||
|   minecraftId?: number; | ||||
|   ontime?: number; | ||||
|   level?: Level; | ||||
|   server?: Server; | ||||
|   leftServer?: boolean; | ||||
|  | ||||
|   joinedServerCount?: number; | ||||
|   joinedServers?: UserJoinedServer[]; | ||||
|  | ||||
|   joinedVoiceChannelCount?: number; | ||||
|   joinedVoiceChannels?: UserJoinedVoiceChannel[]; | ||||
|  | ||||
|   userJoinedGameServerCount?: number; | ||||
|   userJoinedGameServers?: UserJoinedGameServer[]; | ||||
| } | ||||
|  | ||||
| export interface UserFilter { | ||||
|   id?: number; | ||||
|   discordId?: number; | ||||
|   name?: string; | ||||
|   xp?: number; | ||||
|   minecraftId?: number; | ||||
|   ontime?: number; | ||||
|   level?: LevelFilter; | ||||
|   server?: ServerFilter; | ||||
|   leftServer?: boolean; | ||||
| } | ||||
							
								
								
									
										11
									
								
								kdb-web/src/app/models/data/user_joined_game_server.model.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								kdb-web/src/app/models/data/user_joined_game_server.model.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| import { Data } from "./data.model"; | ||||
| import { User } from "./user.model"; | ||||
|  | ||||
| export interface UserJoinedGameServer extends Data { | ||||
|   id: number; | ||||
|   gameServer: string; | ||||
|   user: User; | ||||
|   time: number; | ||||
|   joinedOn: string; | ||||
|   leavedOn: string; | ||||
| } | ||||
							
								
								
									
										9
									
								
								kdb-web/src/app/models/data/user_joined_server.model.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								kdb-web/src/app/models/data/user_joined_server.model.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| import { Data } from "./data.model"; | ||||
| import { User } from "./user.model"; | ||||
|  | ||||
| export interface UserJoinedServer extends Data { | ||||
|   id: number; | ||||
|   user: User; | ||||
|   joinedOn: string; | ||||
|   leavedOn: string; | ||||
| } | ||||
| @@ -0,0 +1,12 @@ | ||||
| import { Data } from "./data.model"; | ||||
| import { User } from "./user.model"; | ||||
|  | ||||
| export interface UserJoinedVoiceChannel extends Data { | ||||
|   id: number; | ||||
|   channelId: string; | ||||
|   channelName: string; | ||||
|   user: User; | ||||
|   time: number; | ||||
|   joinedOn: string; | ||||
|   leavedOn: string; | ||||
| } | ||||
| @@ -1,4 +1,9 @@ | ||||
| export interface Sort { | ||||
|   sortColumn?: string; | ||||
|   sortDirection?: string; | ||||
|   sortDirection?: SortDirection; | ||||
| } | ||||
|  | ||||
| export enum SortDirection { | ||||
|   ASC = "ASC", | ||||
|   DESC = "DESC", | ||||
| } | ||||
|   | ||||
							
								
								
									
										17
									
								
								kdb-web/src/app/models/graphql/mutations.model.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								kdb-web/src/app/models/graphql/mutations.model.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| export class Mutations { | ||||
|   static updateUser = ` | ||||
|     mutation updateUser($id: ID, $xp: Int, $levelId: ID) { | ||||
|       user { | ||||
|         updateUser(input: { id: $id, xp: $xp, levelId: $levelId }) { | ||||
|           id | ||||
|           name | ||||
|           xp | ||||
|           level { | ||||
|             id | ||||
|             name | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   `; | ||||
| } | ||||
| @@ -21,4 +21,115 @@ export class Queries { | ||||
|       } | ||||
|     } | ||||
|   `; | ||||
|  | ||||
|   static levelQuery = ` | ||||
|     query LevelsList($filter: LevelFilter, $page: Page, $sort: Sort) { | ||||
|       levelCount | ||||
|       levels(filter: $filter, page: $page, sort: $sort) { | ||||
|         id | ||||
|         name | ||||
|         color | ||||
|         minXp | ||||
|         permissions | ||||
|         server { | ||||
|           id | ||||
|           name | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   `; | ||||
|  | ||||
|   static usersQuery = ` | ||||
|     query UsersList($filter: UserFilter, $page: Page, $sort: Sort) { | ||||
|       userCount | ||||
|       users(filter: $filter, page: $page, sort: $sort) { | ||||
|         id | ||||
|         discordId | ||||
|         name | ||||
|         xp | ||||
|         ontime | ||||
|         level { | ||||
|           id | ||||
|           name | ||||
|         } | ||||
|         server { | ||||
|           id | ||||
|           name | ||||
|         } | ||||
|         leftServer | ||||
|  | ||||
|         joinedServerCount | ||||
|         joinedServers { | ||||
|           id | ||||
|         } | ||||
|  | ||||
|         joinedVoiceChannelCount | ||||
|         joinedVoiceChannels { | ||||
|           id | ||||
|           channelId | ||||
|           channelName | ||||
|         } | ||||
|  | ||||
|         userJoinedGameServerCount | ||||
|         userJoinedGameServers { | ||||
|           id | ||||
|           gameServer | ||||
|         } | ||||
|  | ||||
|         createdAt | ||||
|         modifiedAt | ||||
|       } | ||||
|     } | ||||
|   `; | ||||
|  | ||||
|   static singleUserQuery = ` | ||||
|     query singleUserQuery($filter: UserFilter) { | ||||
|       users(filter: $filter) { | ||||
|         id | ||||
|         discordId | ||||
|         name | ||||
|         xp | ||||
|         ontime | ||||
|         minecraftId | ||||
|         level { | ||||
|           id | ||||
|           name | ||||
|         } | ||||
|         leftServer | ||||
|         server { | ||||
|           id | ||||
|           name | ||||
|         } | ||||
|  | ||||
|         joinedServerCount | ||||
|         joinedServers { | ||||
|           id | ||||
|           joinedOn | ||||
|           leavedOn | ||||
|         } | ||||
|  | ||||
|         joinedVoiceChannelCount | ||||
|         joinedVoiceChannels { | ||||
|           id | ||||
|           channelId | ||||
|           channelName | ||||
|           time | ||||
|           joinedOn | ||||
|           leavedOn | ||||
|         } | ||||
|  | ||||
|         userJoinedGameServerCount | ||||
|         userJoinedGameServers { | ||||
|           id | ||||
|           gameServer | ||||
|           time | ||||
|           joinedOn | ||||
|           leavedOn | ||||
|         } | ||||
|  | ||||
|         createdAt | ||||
|         modifiedAt | ||||
|       } | ||||
|     } | ||||
|   `; | ||||
| } | ||||
|   | ||||
| @@ -1,6 +1,18 @@ | ||||
| import { Server } from "../data/server.model"; | ||||
| import { User } from "../data/user.model"; | ||||
|  | ||||
| export interface Query { | ||||
|   serverCount: number; | ||||
|   servers: Server[]; | ||||
| } | ||||
|  | ||||
| export interface UserListQuery { | ||||
|   userCount: number; | ||||
|   users: User[]; | ||||
| } | ||||
|  | ||||
| export interface LevelListQuery { | ||||
|   levelCount: number; | ||||
|   levels: User[]; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -1,5 +1,11 @@ | ||||
| import { Query } from "./query.model"; | ||||
| import { User } from "../data/user.model"; | ||||
|  | ||||
| export interface QueryResult { | ||||
|   data: any; | ||||
| } | ||||
|  | ||||
| export interface UpdateUserMutationResult { | ||||
|   user: { | ||||
|     updateUser: User | ||||
|   }; | ||||
| } | ||||
|   | ||||
| @@ -32,7 +32,7 @@ | ||||
|           <th pSortableColumn="firstName"> | ||||
|             <div class="table-header-label"> | ||||
|               <div class="table-header-text">{{'admin.auth_users.headers.first_name' | translate}}</div> | ||||
|               <p-sortIcon icon="sort" field="firstName" class="table-header-icon"></p-sortIcon> | ||||
|               <p-sortIcon field="firstName" class="table-header-icon"></p-sortIcon> | ||||
|             </div> | ||||
|           </th> | ||||
|  | ||||
| @@ -72,13 +72,13 @@ | ||||
|  | ||||
|           <th class="table-header-small-dropdown"> | ||||
|             <div class="table-header-label"> | ||||
|               <div class="table-header-text">{{'admin.auth_users.headers.created_at' | translate}}</div> | ||||
|               <div class="table-header-text">{{'common.created_at' | translate}}</div> | ||||
|             </div> | ||||
|           </th> | ||||
|  | ||||
|           <th class="table-header-small-dropdown"> | ||||
|             <div class="table-header-label"> | ||||
|               <div class="table-header-text">{{'admin.auth_users.headers.modified_at' | translate}}</div> | ||||
|               <div class="table-header-text">{{'common.modified_at' | translate}}</div> | ||||
|             </div> | ||||
|           </th> | ||||
|  | ||||
| @@ -87,7 +87,6 @@ | ||||
|               <div class="table-header-text">{{'admin.auth_users.headers.actions' | translate}}</div> | ||||
|             </div> | ||||
|           </th> | ||||
|  | ||||
|         </tr> | ||||
|         <tr> | ||||
|           <th> | ||||
| @@ -108,7 +107,7 @@ | ||||
|           <th></th> | ||||
|           <th> | ||||
|             <form [formGroup]="filterForm"> | ||||
|               <p-dropdown formControlName="authRole" [options]="authRoles"></p-dropdown> | ||||
|               <p-dropdown formControlName="authRole" [options]="authRoles" placeholder="{{'admin.auth_users.headers.auth_role' | translate}}"></p-dropdown> | ||||
|             </form> | ||||
|           </th> | ||||
|           <th></th> | ||||
| @@ -190,7 +189,7 @@ | ||||
|           <td> | ||||
|             <p-cellEditor> | ||||
|               <ng-template pTemplate="input"> | ||||
|                 {{user.createdAt}} | ||||
|                 {{user.createdAt | date:'dd.MM.yy HH:mm'}} | ||||
|               </ng-template> | ||||
|               <ng-template pTemplate="output"> | ||||
|                 {{user.createdAt | date:'dd.MM.yy HH:mm'}} | ||||
| @@ -200,7 +199,7 @@ | ||||
|           <td> | ||||
|             <p-cellEditor> | ||||
|               <ng-template pTemplate="input"> | ||||
|                 {{user.modifiedAt}} | ||||
|                 {{user.modifiedAt | date:'dd.MM.yy HH:mm'}} | ||||
|               </ng-template> | ||||
|               <ng-template pTemplate="output"> | ||||
|                 {{user.modifiedAt | date:'dd.MM.yy HH:mm'}} | ||||
| @@ -223,9 +222,9 @@ | ||||
|         </tr> | ||||
|       </ng-template> | ||||
|  | ||||
|       <ng-template pTemplate="Invalidmessage"> | ||||
|       <ng-template pTemplate="emptymessage"> | ||||
|         <tr> | ||||
|           <td colspan="7">{{'admin.auth_users.no_entries_found' | translate}}</td> | ||||
|           <td colspan="9">{{'admin.auth_users.no_entries_found' | translate}}</td> | ||||
|         </tr> | ||||
|       </ng-template> | ||||
|  | ||||
| @@ -234,3 +233,4 @@ | ||||
|     </p-table> | ||||
|   </div> | ||||
| </div> | ||||
|  | ||||
|   | ||||
| @@ -10,11 +10,15 @@ export class BoolPipe implements PipeTransform { | ||||
|     private translate: TranslateService | ||||
|   ) {} | ||||
|  | ||||
|   transform(value: boolean): string { | ||||
|     if (value === true) { | ||||
|   transform(value?: boolean): string { | ||||
|     if (value === undefined || value === null) { | ||||
|       return ''; | ||||
|     } | ||||
|  | ||||
|     if (value) { | ||||
|       return this.translate.instant('common.bool_as_string.true'); | ||||
|     } | ||||
|    | ||||
|  | ||||
|     return this.translate.instant('common.bool_as_string.false'); | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -19,6 +19,7 @@ import { AuthRolePipe } from './pipes/auth-role.pipe'; | ||||
| import { IpAddressPipe } from './pipes/ip-address.pipe'; | ||||
| import { BoolPipe } from './pipes/bool.pipe'; | ||||
| import { PanelMenuModule } from 'primeng/panelmenu'; | ||||
| import { PanelModule } from "primeng/panel"; | ||||
|  | ||||
|  | ||||
|  | ||||
| @@ -47,6 +48,7 @@ import { PanelMenuModule } from 'primeng/panelmenu'; | ||||
|     TranslateModule, | ||||
|     DynamicDialogModule, | ||||
|     PanelMenuModule, | ||||
|     PanelModule, | ||||
|   ], | ||||
|   exports: [ | ||||
|     ButtonModule, | ||||
| @@ -66,6 +68,7 @@ import { PanelMenuModule } from 'primeng/panelmenu'; | ||||
|     TranslateModule, | ||||
|     DynamicDialogModule, | ||||
|     PanelMenuModule, | ||||
|     PanelModule, | ||||
|     AuthRolePipe, | ||||
|     IpAddressPipe, | ||||
|     BoolPipe, | ||||
|   | ||||
| @@ -2,13 +2,12 @@ import { Component, OnInit } from "@angular/core"; | ||||
| import { FormBuilder, FormControl, FormGroup } from "@angular/forms"; | ||||
| import { Router } from "@angular/router"; | ||||
| import { TranslateService } from "@ngx-translate/core"; | ||||
| import { LazyLoadEvent } from "primeng/api"; | ||||
| import { debounceTime, throwError } from "rxjs"; | ||||
| import { ConfirmationDialogService } from "src/app/services/confirmation-dialog/confirmation-dialog.service"; | ||||
| import { DataService } from "src/app/services/data/data.service"; | ||||
| import { SpinnerService } from "src/app/services/spinner/spinner.service"; | ||||
| import { ToastService } from "src/app/services/toast/toast.service"; | ||||
| import { Server } from "../../../../../models/data/server.model"; | ||||
| import { Server, ServerFilter } from "../../../../../models/data/server.model"; | ||||
| import { catchError } from "rxjs/operators"; | ||||
| import { Queries } from "../../../../../models/graphql/queries.model"; | ||||
| import { Page } from "../../../../../models/graphql/filter/page.model"; | ||||
| @@ -27,9 +26,7 @@ export class DashboardComponent implements OnInit { | ||||
|  | ||||
|   totalRecords!: number; | ||||
|  | ||||
|   filter = { | ||||
|     name: "" | ||||
|   }; | ||||
|   filter: ServerFilter = {}; | ||||
|  | ||||
|   page: Page = { | ||||
|     pageIndex: 0, | ||||
| @@ -50,7 +47,7 @@ export class DashboardComponent implements OnInit { | ||||
|     private fb: FormBuilder, | ||||
|     private translate: TranslateService, | ||||
|     private router: Router, | ||||
|     private sidebar: SidebarService, | ||||
|     private sidebar: SidebarService | ||||
|   ) { | ||||
|   } | ||||
|  | ||||
| @@ -63,13 +60,15 @@ export class DashboardComponent implements OnInit { | ||||
|  | ||||
|   setFilterForm() { | ||||
|     this.filterForm = this.fb.group({ | ||||
|       name: [""] | ||||
|       name: new FormControl<string | null>(null) | ||||
|     }); | ||||
|  | ||||
|     this.filterForm.valueChanges.pipe( | ||||
|       debounceTime(600) | ||||
|     ).subscribe(async changes => { | ||||
|       if (changes.name) { | ||||
|       if (changes.name == "") { | ||||
|         this.filter.name = undefined; | ||||
|       } else if (changes.name) { | ||||
|         this.filter.name = changes.name; | ||||
|       } | ||||
|  | ||||
| @@ -85,10 +84,10 @@ export class DashboardComponent implements OnInit { | ||||
|  | ||||
|   loadNextPage() { | ||||
|     this.spinnerService.showSpinner(); | ||||
|     this.data.query<Query>(Queries.serversListQuery,{ | ||||
|     this.data.query<Query>(Queries.serversListQuery, { | ||||
|       filter: this.filter, | ||||
|       page: this.page, | ||||
|       sort: this.sort, | ||||
|       sort: this.sort | ||||
|     }).pipe(catchError(err => { | ||||
|       this.spinnerService.hideSpinner(); | ||||
|       return throwError(() => err); | ||||
| @@ -99,30 +98,8 @@ export class DashboardComponent implements OnInit { | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   nextPage(event: LazyLoadEvent) { | ||||
|     this.page.pageSize = event.rows ?? 0; | ||||
|     if (event.first != null && event.rows != null) | ||||
|       this.page.pageIndex = event.first / event.rows; | ||||
|  | ||||
|     this.sort = { | ||||
|       sortColumn: event.sortField ?? "", | ||||
|       sortDirection: event.sortOrder === 1 ? "asc" : event.sortOrder === -1 ? "desc" : "asc" | ||||
|     }; | ||||
|  | ||||
|     if (event.filters) { | ||||
|       // + "" => convert to string | ||||
|       this.filter.name = event.filters["name"] ? event.filters["name"] + "" : ""; | ||||
|     } | ||||
|  | ||||
|     this.loadNextPage(); | ||||
|   } | ||||
|  | ||||
|   resetFilters() { | ||||
|     this.filterForm.reset(); | ||||
|   } | ||||
|  | ||||
|   selectServer(server: Server) { | ||||
|     this.sidebar.serverName$.next(server.name ?? ""); | ||||
|     this.sidebar.setServer(server); | ||||
|     this.router.navigate(["/server", server.id]); | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -0,0 +1,250 @@ | ||||
| <h1> | ||||
|   {{'view.server.members.header' | translate}} | ||||
| </h1> | ||||
| <div class="content-wrapper"> | ||||
|   <div class="content"> | ||||
|     <p-table #dt [value]="members" dataKey="id" editMode="row" [rowHover]="true" [rows]="10" | ||||
|              [rowsPerPageOptions]="[10,25,50]" [paginator]="true" [loading]="loading" [totalRecords]="totalRecords" | ||||
|              [lazy]="true" (onLazyLoad)="nextPage($event)"> | ||||
|  | ||||
|       <ng-template pTemplate="caption"> | ||||
|         <div class="table-caption"> | ||||
|           <div class="table-caption-text"> | ||||
|             <ng-container *ngIf="!loading">{{members.length}} {{'view.server.members.of' | translate}} | ||||
|               {{dt.totalRecords}} | ||||
|             </ng-container> | ||||
|             {{'view.server.members.members' | translate}} | ||||
|           </div> | ||||
|  | ||||
|           <div class="table-caption-btn-wrapper btn-wrapper"> | ||||
|             <button pButton label="{{'view.server.members.reset_filters' | translate}}" icon="pi pi-undo" | ||||
|                     class="icon-btn btn" (click)="resetFilters()"> | ||||
|             </button> | ||||
|           </div> | ||||
|         </div> | ||||
|       </ng-template> | ||||
|  | ||||
|       <ng-template pTemplate="header"> | ||||
|         <tr> | ||||
|           <th pSortableColumn="id"> | ||||
|             <div class="table-header-label"> | ||||
|               <div class="table-header-text">{{'view.server.members.headers.id' | translate}}</div> | ||||
|               <p-sortIcon field="id" class="table-header-icon"></p-sortIcon> | ||||
|             </div> | ||||
|           </th> | ||||
|  | ||||
|           <th pSortableColumn="discordId"> | ||||
|             <div class="table-header-label"> | ||||
|               <div class="table-header-text">{{'view.server.members.headers.discord_id' | translate}}</div> | ||||
|               <p-sortIcon field="discordId" class="table-header-icon"></p-sortIcon> | ||||
|             </div> | ||||
|           </th> | ||||
|  | ||||
|           <th pSortableColumn="name"> | ||||
|             <div class="table-header-label"> | ||||
|               <div class="table-header-text">{{'view.server.members.headers.name' | translate}}</div> | ||||
|               <p-sortIcon field="name" class="table-header-icon"></p-sortIcon> | ||||
|             </div> | ||||
|           </th> | ||||
|  | ||||
|           <th pSortableColumn="xp"> | ||||
|             <div class="table-header-label"> | ||||
|               <div class="table-header-text">{{'view.server.members.headers.xp' | translate}}</div> | ||||
|               <p-sortIcon field="xp" class="table-header-icon"></p-sortIcon> | ||||
|             </div> | ||||
|           </th> | ||||
|  | ||||
|           <th pSortableColumn="ontime"> | ||||
|             <div class="table-header-label"> | ||||
|               <div class="table-header-text">{{'view.server.members.headers.ontime' | translate}}</div> | ||||
|               <p-sortIcon field="ontime" class="table-header-icon"></p-sortIcon> | ||||
|             </div> | ||||
|           </th> | ||||
|  | ||||
|           <th pSortableColumn="leftServer"> | ||||
|             <div class="table-header-label"> | ||||
|               <div class="table-header-text">{{'view.server.members.headers.left_server' | translate}}</div> | ||||
|               <p-sortIcon field="leftServer" class="table-header-icon"></p-sortIcon> | ||||
|             </div> | ||||
|           </th> | ||||
|  | ||||
|           <th pSortableColumn="level.name"> | ||||
|             <div class="table-header-label"> | ||||
|               <div class="table-header-text">{{'view.server.members.headers.level' | translate}}</div> | ||||
|               <p-sortIcon field="level.name" class="table-header-icon"></p-sortIcon> | ||||
|             </div> | ||||
|           </th> | ||||
|  | ||||
|           <th> | ||||
|             <div class="table-header-label"> | ||||
|               <div class="table-header-text">{{'common.created_at' | translate}}</div> | ||||
|             </div> | ||||
|           </th> | ||||
|  | ||||
|           <th> | ||||
|             <div class="table-header-label"> | ||||
|               <div class="table-header-text">{{'common.modified_at' | translate}}</div> | ||||
|             </div> | ||||
|           </th> | ||||
|  | ||||
|           <th> | ||||
|             <div class="table-header-label"> | ||||
|               <div class="table-header-text">{{'view.server.members.headers.actions' | translate}}</div> | ||||
|             </div> | ||||
|           </th> | ||||
|         </tr> | ||||
|  | ||||
|         <tr> | ||||
|           <th class="table-header-small"> | ||||
|             <form [formGroup]="filterForm"> | ||||
|               <input type="text" pInputText formControlName="id" placeholder="{{'view.server.members.headers.id' | translate}}"> | ||||
|             </form> | ||||
|           </th> | ||||
|           <th class="table-header-medium"> | ||||
|             <form [formGroup]="filterForm"> | ||||
|               <input type="text" pInputText formControlName="discordId" placeholder="{{'view.server.members.headers.discord_id' | translate}}"> | ||||
|             </form> | ||||
|           </th> | ||||
|           <th> | ||||
|             <form [formGroup]="filterForm"> | ||||
|               <input type="text" pInputText formControlName="name" placeholder="{{'view.server.members.headers.name' | translate}}"> | ||||
|             </form> | ||||
|           </th> | ||||
|           <th></th> | ||||
|           <th></th> | ||||
|           <th class="table-header-small-dropdown"> | ||||
|             <form [formGroup]="filterForm"> | ||||
|               <p-dropdown formControlName="leftServer" [options]="leftServerOptions" placeholder="{{'view.server.members.headers.left_server' | translate}}"></p-dropdown> | ||||
|             </form> | ||||
|           </th> | ||||
|           <th class="table-header-small-dropdown"> | ||||
|             <form [formGroup]="filterForm"> | ||||
|               <p-dropdown formControlName="level" [options]="levels" placeholder="{{'view.server.members.headers.level' | translate}}"></p-dropdown> | ||||
|             </form> | ||||
|           </th> | ||||
|           <th></th> | ||||
|           <th></th> | ||||
|           <th class="table-header-actions"></th> | ||||
|         </tr> | ||||
|       </ng-template> | ||||
|  | ||||
|       <ng-template pTemplate="body" let-member let-editing="editing" let-ri="rowIndex"> | ||||
|         <tr [pEditableRow]="member"> | ||||
|           <td> | ||||
|             <p-cellEditor> | ||||
|               <ng-template pTemplate="input"> | ||||
|                 {{member.id}} | ||||
|               </ng-template> | ||||
|               <ng-template pTemplate="output"> | ||||
|                 {{member.id}} | ||||
|               </ng-template> | ||||
|             </p-cellEditor> | ||||
|           </td> | ||||
|           <td> | ||||
|             <p-cellEditor> | ||||
|               <ng-template pTemplate="input"> | ||||
|                 {{member.discordId}} | ||||
|               </ng-template> | ||||
|               <ng-template pTemplate="output"> | ||||
|                 {{member.discordId}} | ||||
|               </ng-template> | ||||
|             </p-cellEditor> | ||||
|           </td> | ||||
|           <td> | ||||
|             <p-cellEditor> | ||||
|               <ng-template pTemplate="input"> | ||||
|                 {{member.name}} | ||||
|               </ng-template> | ||||
|               <ng-template pTemplate="output"> | ||||
|                 {{member.name}} | ||||
|               </ng-template> | ||||
|             </p-cellEditor> | ||||
|           </td> | ||||
|           <td> | ||||
|             <p-cellEditor> | ||||
|               <ng-template pTemplate="input"> | ||||
|                 <input class="table-edit-input" pInputText type="number" [(ngModel)]="member.xp"> | ||||
|               </ng-template> | ||||
|               <ng-template pTemplate="output"> | ||||
|                 {{member.xp}} | ||||
|               </ng-template> | ||||
|             </p-cellEditor> | ||||
|           </td> | ||||
|           <td> | ||||
|             <p-cellEditor> | ||||
|               <ng-template pTemplate="input"> | ||||
|                 {{member.ontime}} | ||||
|               </ng-template> | ||||
|               <ng-template pTemplate="output"> | ||||
|                 {{member.ontime}} | ||||
|               </ng-template> | ||||
|             </p-cellEditor> | ||||
|           </td> | ||||
|           <td> | ||||
|             <p-cellEditor> | ||||
|               <ng-template pTemplate="input"> | ||||
|                 {{!member.leftServer | bool}} | ||||
|               </ng-template> | ||||
|               <ng-template pTemplate="output"> | ||||
|                 {{!member.leftServer | bool}} | ||||
|               </ng-template> | ||||
|             </p-cellEditor> | ||||
|           </td> | ||||
|           <td> | ||||
|             <p-cellEditor> | ||||
|               <ng-template pTemplate="input"> | ||||
|                 <p-dropdown [options]="levels" [(ngModel)]="member.level" placeholder="{{'view.server.members.headers.level' | translate}}"></p-dropdown> | ||||
|               </ng-template> | ||||
|               <ng-template pTemplate="output"> | ||||
|                 {{member.level.name}} | ||||
|               </ng-template> | ||||
|             </p-cellEditor> | ||||
|           </td> | ||||
|           <td> | ||||
|             <p-cellEditor> | ||||
|               <ng-template pTemplate="input"> | ||||
|                 {{member.createdAt | date:'dd.MM.yy HH:mm'}} | ||||
|               </ng-template> | ||||
|               <ng-template pTemplate="output"> | ||||
|                 {{member.createdAt | date:'dd.MM.yy HH:mm'}} | ||||
|               </ng-template> | ||||
|             </p-cellEditor> | ||||
|           </td> | ||||
|           <td> | ||||
|             <p-cellEditor> | ||||
|               <ng-template pTemplate="input"> | ||||
|                 {{member.modifiedAt | date:'dd.MM.yy HH:mm'}} | ||||
|               </ng-template> | ||||
|               <ng-template pTemplate="output"> | ||||
|                 {{member.modifiedAt | date:'dd.MM.yy HH:mm'}} | ||||
|               </ng-template> | ||||
|             </p-cellEditor> | ||||
|           </td> | ||||
|           <td> | ||||
|             <div class="btn-wrapper"> | ||||
|               <button *ngIf="!editing" pButton pInitEditableRow class="btn icon-btn" icon="pi pi-pencil" | ||||
|                       (click)="onRowEditInit(dt, member, ri)"></button> | ||||
|               <button *ngIf="!editing" pButton pInitEditableRow class="btn icon-btn" icon="pi pi-user" [routerLink]="member.id"></button> | ||||
|  | ||||
|               <button *ngIf="editing" pButton pSaveEditableRow class="btn icon-btn" | ||||
|                       icon="pi pi-check-circle" (click)="onRowEditSave(dt, member, ri)"></button> | ||||
|               <button *ngIf="editing" pButton pCancelEditableRow class="btn icon-btn danger-icon-btn" | ||||
|                       icon="pi pi-times-circle" (click)="onRowEditCancel(member, ri)"></button> | ||||
|             </div> | ||||
|           </td> | ||||
|         </tr> | ||||
|       </ng-template> | ||||
|  | ||||
|       <ng-template pTemplate="emptymessage"> | ||||
|         <tr></tr> | ||||
|         <tr> | ||||
|           <td colspan="10">{{'view.server.members.no_entries_found' | translate}}</td> | ||||
|         </tr> | ||||
|         <tr></tr> | ||||
|       </ng-template> | ||||
|  | ||||
|       <ng-template pTemplate="paginatorleft"> | ||||
|       </ng-template> | ||||
|     </p-table> | ||||
|   </div> | ||||
| </div> | ||||
| @@ -0,0 +1,23 @@ | ||||
| import { ComponentFixture, TestBed } from '@angular/core/testing'; | ||||
|  | ||||
| import { MembersComponent } from './members.component'; | ||||
|  | ||||
| describe('MembersComponent', () => { | ||||
|   let component: MembersComponent; | ||||
|   let fixture: ComponentFixture<MembersComponent>; | ||||
|  | ||||
|   beforeEach(async () => { | ||||
|     await TestBed.configureTestingModule({ | ||||
|       declarations: [ MembersComponent ] | ||||
|     }) | ||||
|     .compileComponents(); | ||||
|  | ||||
|     fixture = TestBed.createComponent(MembersComponent); | ||||
|     component = fixture.componentInstance; | ||||
|     fixture.detectChanges(); | ||||
|   }); | ||||
|  | ||||
|   it('should create', () => { | ||||
|     expect(component).toBeTruthy(); | ||||
|   }); | ||||
| }); | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user