1.0.0 #253
| @@ -5,7 +5,6 @@ from typing import Callable | ||||
| from cpl_query.extension import List | ||||
| from discord.ext.commands import Context | ||||
|  | ||||
| from bot_data.model.user import User | ||||
| from modules.base.configuration.base_server_settings import BaseServerSettings | ||||
|  | ||||
|  | ||||
| @@ -50,12 +49,12 @@ class ClientUtilsABC(ABC): | ||||
|     def is_message_xp_count_by_hour_higher_that_max_message_count_per_hour( | ||||
|         self, | ||||
|         created_at: datetime, | ||||
|         user: User, | ||||
|         user: "User", | ||||
|         settings: BaseServerSettings, | ||||
|         is_reaction: bool = False, | ||||
|     ) -> bool: | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def get_ontime_for_user(self, user: User) -> float: | ||||
|     def get_ontime_for_user(self, user: "User") -> float: | ||||
|         pass | ||||
|   | ||||
| @@ -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) | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|  | ||||
| @@ -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,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.server import Server | ||||
|  | ||||
| @@ -40,6 +42,11 @@ class Client(TableABC): | ||||
|     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 | ||||
|   | ||||
| @@ -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 | ||||
|  | ||||
|  | ||||
| class Server(TableABC): | ||||
| @@ -26,6 +28,18 @@ class Server(TableABC): | ||||
|     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( | ||||
|   | ||||
| @@ -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_core.abc.client_utils_abc import ClientUtilsABC | ||||
| from bot_data.model.server import Server | ||||
|  | ||||
|  | ||||
| @@ -35,6 +38,20 @@ class User(TableABC): | ||||
|     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,19 @@ class User(TableABC): | ||||
|         self._modified_at = datetime.now().isoformat() | ||||
|         self._xp = value | ||||
|  | ||||
|     @property | ||||
|     @ServiceProviderABC.inject | ||||
|     def ontime(self, client_utils: ClientUtilsABC) -> float: | ||||
|         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 | ||||
|   | ||||
| @@ -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 | ||||
| @@ -31,8 +33,13 @@ class UserJoinedVoiceChannel(TableABC): | ||||
|         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: | ||||
| @@ -101,7 +108,7 @@ class UserJoinedVoiceChannel(TableABC): | ||||
|                     `UserId`, `DiscordChannelId`, `JoinedOn`, `LeavedOn`, `CreatedAt`, `LastModifiedAt` | ||||
|                 ) VALUES ( | ||||
|                     {self._user.id}, | ||||
|                     {self._dc_channel_id}, | ||||
|                     {self._channel_id}, | ||||
|                     '{self._joined_on}', | ||||
|                     '{self._leaved_on}', | ||||
|                     '{self._created_at}', | ||||
| @@ -116,7 +123,7 @@ class UserJoinedVoiceChannel(TableABC): | ||||
|                     `UserId`, `DiscordChannelId`, `JoinedOn`, `CreatedAt`, `LastModifiedAt` | ||||
|                 ) VALUES ( | ||||
|                     {self._user.id}, | ||||
|                     {self._dc_channel_id}, | ||||
|                     {self._channel_id}, | ||||
|                     '{self._joined_on}', | ||||
|                     '{self._created_at}', | ||||
|                     '{self._modified_at}' | ||||
|   | ||||
| @@ -36,7 +36,7 @@ class ServerFilter(FilterABC): | ||||
|         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,11 +1,17 @@ | ||||
| import functools | ||||
|  | ||||
| from cpl_core.utils import String | ||||
| from cpl_query.extension import List | ||||
|  | ||||
| from bot_api.exception.service_error_code_enum import ServiceErrorCode | ||||
| from bot_api.exception.service_exception import ServiceException | ||||
| 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,8 +22,19 @@ 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 = getattr(x, self._sort_column, None) | ||||
|         atr = self._rgetattr(x, String.convert_to_snake_case(self._sort_column), None) | ||||
|         if atr is None: | ||||
|             raise ServiceException( | ||||
|                 ServiceErrorCode.InvalidData, f"Attribute {self._sort_column} in object of {type(x)} not found" | ||||
|             ) | ||||
|         return atr | ||||
|  | ||||
|     def filter(self, query: List, *args) -> List: | ||||
|   | ||||
| @@ -51,12 +51,12 @@ 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) | ||||
|   | ||||
| @@ -40,9 +40,9 @@ class AutoRoleQuery(DataQueryABC): | ||||
|     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, *_): | ||||
|   | ||||
| @@ -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_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.id) | ||||
|   | ||||
| @@ -31,8 +31,9 @@ class ClientQuery(DataQueryABC): | ||||
|     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, *_): | ||||
|   | ||||
| @@ -59,10 +59,10 @@ class ServerQuery(DataQueryABC): | ||||
|     def resolve_discord_id(server: Server, *_): | ||||
|         return server.discord_id | ||||
|  | ||||
|     def resolve_name(self, server: Server, *_): | ||||
|         guild = self._bot.get_guild(server.discord_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_id) | ||||
|         return None if guild is None else guild.icon.url | ||||
|     @staticmethod | ||||
|     def resolve_icon_url(server: Server, *_): | ||||
|         return server.icon_url | ||||
|   | ||||
| @@ -23,10 +23,11 @@ class UserJoinedVoiceChannelQuery(DataQueryABC): | ||||
|  | ||||
|     @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, *_): | ||||
|   | ||||
| @@ -67,10 +67,9 @@ class UserQuery(DataQueryABC): | ||||
|     def resolve_discord_id(user: User, *_): | ||||
|         return user.discord_id | ||||
|  | ||||
|     def resolve_name(self, user: User, *_): | ||||
|         guild = self._bot.get_guild(user.server.discord_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, *_): | ||||
| @@ -80,11 +79,13 @@ 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, *_): | ||||
|   | ||||
| @@ -48,7 +48,7 @@ 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.id) | ||||
| @@ -62,7 +62,7 @@ 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 | ||||
|   | ||||
| @@ -1,4 +1,9 @@ | ||||
| export interface Sort { | ||||
|   sortColumn?: string; | ||||
|   sortDirection?: string; | ||||
|   sortDirection?: SortDirection; | ||||
| } | ||||
|  | ||||
| export enum SortDirection { | ||||
|   ASC = "ASC", | ||||
|   DESC = "DESC", | ||||
| } | ||||
|   | ||||
| @@ -12,7 +12,7 @@ import { Server } 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"; | ||||
| import { Sort } from "../../../../../models/graphql/filter/sort.model"; | ||||
| import { Sort, SortDirection } from "../../../../../models/graphql/filter/sort.model"; | ||||
| import { Query } from "../../../../../models/graphql/query.model"; | ||||
| import { SidebarService } from "../../../../../services/sidebar/sidebar.service"; | ||||
|  | ||||
| @@ -106,7 +106,7 @@ export class DashboardComponent implements OnInit { | ||||
|  | ||||
|     this.sort = { | ||||
|       sortColumn: event.sortField ?? "", | ||||
|       sortDirection: event.sortOrder === 1 ? "asc" : event.sortOrder === -1 ? "desc" : "asc" | ||||
|       sortDirection: event.sortOrder === 1 ? SortDirection.ASC : event.sortOrder === -1 ? SortDirection.DESC: SortDirection.ASC | ||||
|     }; | ||||
|  | ||||
|     if (event.filters) { | ||||
|   | ||||
| @@ -26,7 +26,7 @@ | ||||
|  | ||||
|       <ng-template pTemplate="header"> | ||||
|         <tr> | ||||
|           <th pSortableColumn="id"> | ||||
|           <th class="table-header-small" 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> | ||||
| @@ -61,10 +61,10 @@ | ||||
|             </div> | ||||
|           </th> | ||||
|  | ||||
|           <th class="table-header-small-dropdown" pSortableColumn="level"> | ||||
|           <th class="table-header-small-dropdown" pSortableColumn="level.name"> | ||||
|             <div class="table-header-label"> | ||||
|               <div class="table-header-text">{{'view.server.members.headers.level' | translate}}</div> | ||||
|               <p-sortIcon field="level" class="table-header-icon"></p-sortIcon> | ||||
|               <p-sortIcon field="level.name" class="table-header-icon"></p-sortIcon> | ||||
|             </div> | ||||
|           </th> | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user