diff --git a/kdb-bot/src/bot_core/abc/client_utils_abc.py b/kdb-bot/src/bot_core/abc/client_utils_abc.py index 022665c0..a8489080 100644 --- a/kdb-bot/src/bot_core/abc/client_utils_abc.py +++ b/kdb-bot/src/bot_core/abc/client_utils_abc.py @@ -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 diff --git a/kdb-bot/src/bot_data/model/auto_role.py b/kdb-bot/src/bot_data/model/auto_role.py index b783f470..28ad489d 100644 --- a/kdb-bot/src/bot_data/model/auto_role.py +++ b/kdb-bot/src/bot_data/model/auto_role.py @@ -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 diff --git a/kdb-bot/src/bot_data/model/auto_role_rule.py b/kdb-bot/src/bot_data/model/auto_role_rule.py index bc47c489..3630f134 100644 --- a/kdb-bot/src/bot_data/model/auto_role_rule.py +++ b/kdb-bot/src/bot_data/model/auto_role_rule.py @@ -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 diff --git a/kdb-bot/src/bot_data/model/client.py b/kdb-bot/src/bot_data/model/client.py index c932da78..79f5c0fe 100644 --- a/kdb-bot/src/bot_data/model/client.py +++ b/kdb-bot/src/bot_data/model/client.py @@ -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 diff --git a/kdb-bot/src/bot_data/model/server.py b/kdb-bot/src/bot_data/model/server.py index f97795a0..e2412295 100644 --- a/kdb-bot/src/bot_data/model/server.py +++ b/kdb-bot/src/bot_data/model/server.py @@ -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( diff --git a/kdb-bot/src/bot_data/model/user.py b/kdb-bot/src/bot_data/model/user.py index e2b0058e..12c73f51 100644 --- a/kdb-bot/src/bot_data/model/user.py +++ b/kdb-bot/src/bot_data/model/user.py @@ -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 diff --git a/kdb-bot/src/bot_data/model/user_joined_voice_channel.py b/kdb-bot/src/bot_data/model/user_joined_voice_channel.py index 23148f41..87cd7aeb 100644 --- a/kdb-bot/src/bot_data/model/user_joined_voice_channel.py +++ b/kdb-bot/src/bot_data/model/user_joined_voice_channel.py @@ -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}' diff --git a/kdb-bot/src/bot_graphql/filter/server_filter.py b/kdb-bot/src/bot_graphql/filter/server_filter.py index e758f410..6260f3a9 100644 --- a/kdb-bot/src/bot_graphql/filter/server_filter.py +++ b/kdb-bot/src/bot_graphql/filter/server_filter.py @@ -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() ) diff --git a/kdb-bot/src/bot_graphql/filter/sort.py b/kdb-bot/src/bot_graphql/filter/sort.py index 8346c097..1df0cbc8 100644 --- a/kdb-bot/src/bot_graphql/filter/sort.py +++ b/kdb-bot/src/bot_graphql/filter/sort.py @@ -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: diff --git a/kdb-bot/src/bot_graphql/filter/user_joined_voice_channel_filter.py b/kdb-bot/src/bot_graphql/filter/user_joined_voice_channel_filter.py index d4e46050..51ba446a 100644 --- a/kdb-bot/src/bot_graphql/filter/user_joined_voice_channel_filter.py +++ b/kdb-bot/src/bot_graphql/filter/user_joined_voice_channel_filter.py @@ -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) diff --git a/kdb-bot/src/bot_graphql/queries/auto_role_query.py b/kdb-bot/src/bot_graphql/queries/auto_role_query.py index d4d6715e..26f8b390 100644 --- a/kdb-bot/src/bot_graphql/queries/auto_role_query.py +++ b/kdb-bot/src/bot_graphql/queries/auto_role_query.py @@ -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, *_): diff --git a/kdb-bot/src/bot_graphql/queries/auto_role_rule_query.py b/kdb-bot/src/bot_graphql/queries/auto_role_rule_query.py index dda4220d..faa8df8f 100644 --- a/kdb-bot/src/bot_graphql/queries/auto_role_rule_query.py +++ b/kdb-bot/src/bot_graphql/queries/auto_role_rule_query.py @@ -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) diff --git a/kdb-bot/src/bot_graphql/queries/client_query.py b/kdb-bot/src/bot_graphql/queries/client_query.py index a9528fab..fe2312b7 100644 --- a/kdb-bot/src/bot_graphql/queries/client_query.py +++ b/kdb-bot/src/bot_graphql/queries/client_query.py @@ -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, *_): diff --git a/kdb-bot/src/bot_graphql/queries/server_query.py b/kdb-bot/src/bot_graphql/queries/server_query.py index 04c689cd..059a87fd 100644 --- a/kdb-bot/src/bot_graphql/queries/server_query.py +++ b/kdb-bot/src/bot_graphql/queries/server_query.py @@ -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 diff --git a/kdb-bot/src/bot_graphql/queries/user_joined_voice_channel_query.py b/kdb-bot/src/bot_graphql/queries/user_joined_voice_channel_query.py index e231090c..333fbfa5 100644 --- a/kdb-bot/src/bot_graphql/queries/user_joined_voice_channel_query.py +++ b/kdb-bot/src/bot_graphql/queries/user_joined_voice_channel_query.py @@ -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, *_): diff --git a/kdb-bot/src/bot_graphql/queries/user_query.py b/kdb-bot/src/bot_graphql/queries/user_query.py index 2be4b47a..e609e81d 100644 --- a/kdb-bot/src/bot_graphql/queries/user_query.py +++ b/kdb-bot/src/bot_graphql/queries/user_query.py @@ -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, *_): diff --git a/kdb-bot/src/modules/base/events/base_on_voice_state_update_event.py b/kdb-bot/src/modules/base/events/base_on_voice_state_update_event.py index 16ca9fa2..8ff32383 100644 --- a/kdb-bot/src/modules/base/events/base_on_voice_state_update_event.py +++ b/kdb-bot/src/modules/base/events/base_on_voice_state_update_event.py @@ -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 diff --git a/kdb-web/src/app/models/graphql/filter/sort.model.ts b/kdb-web/src/app/models/graphql/filter/sort.model.ts index 61ee7627..aca195a4 100644 --- a/kdb-web/src/app/models/graphql/filter/sort.model.ts +++ b/kdb-web/src/app/models/graphql/filter/sort.model.ts @@ -1,4 +1,9 @@ export interface Sort { sortColumn?: string; - sortDirection?: string; + sortDirection?: SortDirection; +} + +export enum SortDirection { + ASC = "ASC", + DESC = "DESC", } diff --git a/kdb-web/src/app/modules/view/dashboard/components/dashboard/dashboard.component.ts b/kdb-web/src/app/modules/view/dashboard/components/dashboard/dashboard.component.ts index d4df31b8..c2605c72 100644 --- a/kdb-web/src/app/modules/view/dashboard/components/dashboard/dashboard.component.ts +++ b/kdb-web/src/app/modules/view/dashboard/components/dashboard/dashboard.component.ts @@ -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) { diff --git a/kdb-web/src/app/modules/view/server/members/members.component.html b/kdb-web/src/app/modules/view/server/members/members.component.html index 841daf53..ce92f0b2 100644 --- a/kdb-web/src/app/modules/view/server/members/members.component.html +++ b/kdb-web/src/app/modules/view/server/members/members.component.html @@ -26,7 +26,7 @@ - +
{{'view.server.members.headers.id' | translate}}
@@ -61,10 +61,10 @@
- +
{{'view.server.members.headers.level' | translate}}
- +