diff --git a/kdb-bot/src/bot_graphql/filter/achievement_filter.py b/kdb-bot/src/bot_graphql/filter/achievement_filter.py new file mode 100644 index 00000000..49c0eab9 --- /dev/null +++ b/kdb-bot/src/bot_graphql/filter/achievement_filter.py @@ -0,0 +1,60 @@ +from cpl_query.extension import List + +from bot_data.model.user import User +from bot_graphql.abc.filter_abc import FilterABC + + +class AchievementFilter(FilterABC): + def __init__(self): + FilterABC.__init__(self) + + self._id = None + self._name = None + self._attribute = None + self._operator = None + self._value = None + self._server = None + + def from_dict(self, values: dict): + if "id" in values: + self._id = int(values["id"]) + + if "name" in values: + self._name = values["name"] + + if "attribute" in values: + self._attribute = values["attribute"] + + if "operator" in values: + self._operator = values["operator"] + + if "value" in values: + self._value = values["value"] + + if "server" in values: + from bot_graphql.filter.server_filter import ServerFilter + + self._server: ServerFilter = self._services.get_service(ServerFilter) + self._server.from_dict(values["server"]) + + def filter(self, query: List[User]) -> List[User]: + if self._id is not None: + query = query.where(lambda x: x.id == self._id) + + if self._name is not None: + query = query.where(lambda x: x.name == self._name) + + if self._attribute is not None: + query = query.where(lambda x: x.attribute == self._attribute) + + if self._operator is not None: + query = query.where(lambda x: x.operator == self._operator) + + if self._value is not None: + query = query.where(lambda x: x.value == self._value) + + if self._server is not None: + 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 diff --git a/kdb-bot/src/bot_graphql/graphql_module.py b/kdb-bot/src/bot_graphql/graphql_module.py index 5ef7df09..b861aec1 100644 --- a/kdb-bot/src/bot_graphql/graphql_module.py +++ b/kdb-bot/src/bot_graphql/graphql_module.py @@ -8,6 +8,7 @@ from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum from bot_data.service.seeder_service import SeederService from bot_graphql.abc.filter_abc import FilterABC from bot_graphql.abc.query_abc import QueryABC +from bot_graphql.filter.achievement_filter import AchievementFilter from bot_graphql.filter.auto_role_filter import AutoRoleFilter from bot_graphql.filter.auto_role_rule_filter import AutoRoleRuleFilter from bot_graphql.filter.client_filter import ClientFilter @@ -19,11 +20,13 @@ from bot_graphql.filter.user_joined_server_filter import UserJoinedServerFilter from bot_graphql.filter.user_joined_voice_channel_filter import UserJoinedVoiceChannelFilter from bot_graphql.graphql_service import GraphQLService from bot_graphql.mutation import Mutation +from bot_graphql.mutations.achievement_mutation import AchievementMutation from bot_graphql.mutations.auto_role_mutation import AutoRoleMutation from bot_graphql.mutations.auto_role_rule_mutation import AutoRoleRuleMutation from bot_graphql.mutations.level_mutation import LevelMutation from bot_graphql.mutations.user_joined_game_server_mutation import UserJoinedGameServerMutation from bot_graphql.mutations.user_mutation import UserMutation +from bot_graphql.queries.achievement_query import AchievementQuery from bot_graphql.queries.auto_role_history_query import AutoRoleHistoryQuery from bot_graphql.queries.auto_role_query import AutoRoleQuery from bot_graphql.queries.auto_role_rule_history_query import AutoRoleRuleHistoryQuery @@ -76,6 +79,7 @@ class GraphQLModule(ModuleABC): services.add_transient(QueryABC, ServerQuery) services.add_transient(QueryABC, UserHistoryQuery) services.add_transient(QueryABC, UserQuery) + services.add_transient(QueryABC, AchievementQuery) services.add_transient(QueryABC, UserJoinedServerHistoryQuery) services.add_transient(QueryABC, UserJoinedServerQuery) services.add_transient(QueryABC, UserJoinedVoiceChannelHistoryQuery) @@ -90,6 +94,7 @@ class GraphQLModule(ModuleABC): services.add_transient(FilterABC, LevelFilter) services.add_transient(FilterABC, ServerFilter) services.add_transient(FilterABC, UserFilter) + services.add_transient(FilterABC, AchievementFilter) services.add_transient(FilterABC, UserJoinedServerFilter) services.add_transient(FilterABC, UserJoinedVoiceChannelFilter) services.add_transient(FilterABC, UserJoinedGameServerFilter) @@ -99,6 +104,7 @@ class GraphQLModule(ModuleABC): services.add_transient(QueryABC, AutoRoleRuleMutation) services.add_transient(QueryABC, LevelMutation) services.add_transient(QueryABC, UserMutation) + services.add_transient(QueryABC, AchievementMutation) services.add_transient(QueryABC, UserJoinedGameServerMutation) services.add_transient(SeederService) diff --git a/kdb-bot/src/bot_graphql/model/achievement.gql b/kdb-bot/src/bot_graphql/model/achievement.gql new file mode 100644 index 00000000..3a5f1328 --- /dev/null +++ b/kdb-bot/src/bot_graphql/model/achievement.gql @@ -0,0 +1,52 @@ +type Achievement implements TableWithHistoryQuery { + id: ID + name: String + attribute: String + operator: String + value: String + + server: Server + + createdAt: String + modifiedAt: String + + history: [AchievementHistory] +} + +type AchievementHistory implements HistoryTableQuery { + id: ID + name: String + attribute: String + operator: String + value: String + + server: Server + + deleted: Boolean + dateFrom: String + dateTo: String +} + +input AchievementFilter { + id: ID + name: String + attribute: String + operator: String + value: String + server: ServerFilter +} + +type AchievementMutation { + createAchievement(input: AchievementInput!): Achievement + updateAchievement(input: AchievementInput!): Achievement + deleteAchievement(id: ID): Achievement +} + +input AchievementInput { + id: ID + name: String + attribute: String + operator: String + value: String + serverId: ID +} \ No newline at end of file diff --git a/kdb-bot/src/bot_graphql/model/mutation.gql b/kdb-bot/src/bot_graphql/model/mutation.gql index 9631fd8d..0fb69b50 100644 --- a/kdb-bot/src/bot_graphql/model/mutation.gql +++ b/kdb-bot/src/bot_graphql/model/mutation.gql @@ -4,4 +4,5 @@ type Mutation { level: LevelMutation user: UserMutation userJoinedGameServer: UserJoinedGameServerMutation + achievement: AchievementMutation } \ No newline at end of file diff --git a/kdb-bot/src/bot_graphql/model/query.gql b/kdb-bot/src/bot_graphql/model/query.gql index 69b5a74a..17d8634c 100644 --- a/kdb-bot/src/bot_graphql/model/query.gql +++ b/kdb-bot/src/bot_graphql/model/query.gql @@ -29,5 +29,8 @@ type Query { userCount: Int users(filter: UserFilter, page: Page, sort: Sort): [User] + achievementCount: Int + achievements(filter: AchievementFilter, page: Page, sort: Sort): [Achievement] + guilds(filter: GuildFilter): [Guild] } \ No newline at end of file diff --git a/kdb-bot/src/bot_graphql/mutation.py b/kdb-bot/src/bot_graphql/mutation.py index 56bfa7c5..d8287d96 100644 --- a/kdb-bot/src/bot_graphql/mutation.py +++ b/kdb-bot/src/bot_graphql/mutation.py @@ -1,6 +1,6 @@ from ariadne import MutationType -from bot_data.model.user_joined_game_server import UserJoinedGameServer +from bot_graphql.mutations.achievement_mutation import AchievementMutation from bot_graphql.mutations.auto_role_mutation import AutoRoleMutation from bot_graphql.mutations.auto_role_rule_mutation import AutoRoleRuleMutation from bot_graphql.mutations.level_mutation import LevelMutation @@ -15,6 +15,7 @@ class Mutation(MutationType): auto_role_rule_mutation: AutoRoleRuleMutation, level_mutation: LevelMutation, user_mutation: UserMutation, + achievement_mutation: AchievementMutation, user_joined_game_server: UserJoinedGameServerMutation, ): MutationType.__init__(self) @@ -23,4 +24,5 @@ class Mutation(MutationType): self.set_field("autoRoleRule", lambda *_: auto_role_rule_mutation) self.set_field("level", lambda *_: level_mutation) self.set_field("user", lambda *_: user_mutation) + self.set_field("achievement", lambda *_: achievement_mutation) self.set_field("userJoinedGameServer", lambda *_: user_joined_game_server) diff --git a/kdb-bot/src/bot_graphql/mutations/achievement_mutation.py b/kdb-bot/src/bot_graphql/mutations/achievement_mutation.py new file mode 100644 index 00000000..c7daa8c8 --- /dev/null +++ b/kdb-bot/src/bot_graphql/mutations/achievement_mutation.py @@ -0,0 +1,43 @@ +from cpl_core.database.context import DatabaseContextABC +from cpl_discord.service import DiscordBotServiceABC + +from bot_data.abc.achievement_repository_abc import AchievementRepositoryABC +from bot_data.abc.server_repository_abc import ServerRepositoryABC +from bot_data.model.user_role_enum import UserRoleEnum +from bot_graphql.abc.query_abc import QueryABC +from modules.permission.service.permission_service import PermissionService + + +class AchievementMutation(QueryABC): + def __init__( + self, + servers: ServerRepositoryABC, + achievements: AchievementRepositoryABC, + bot: DiscordBotServiceABC, + db: DatabaseContextABC, + permissions: PermissionService, + ): + QueryABC.__init__(self, "AchievementMutation") + + self._servers = servers + self._achievements = achievements + self._bot = bot + self._db = db + self._permissions = permissions + + self.set_field("updateAchievement", self.resolve_update_achievement) + + def resolve_update_achievement(self, *_, input: dict): + achievement = self._achievements.get_achievement_by_id(input["id"]) + self._can_user_mutate_data(achievement.server, UserRoleEnum.moderator) + + achievement.name = input["name"] if "name" in input else achievement.name + achievement.attribute = input["attribute"] if "attribute" in input else achievement.attribute + achievement.operator = input["operator"] if "operator" in input else achievement.operator + achievement.value = input["value"] if "value" in input else achievement.value + + self._achievements.update_achievement(achievement) + self._db.save_changes() + + achievement = self._achievements.get_achievement_by_id(input["id"]) + return achievement diff --git a/kdb-bot/src/bot_graphql/queries/achievement_query.py b/kdb-bot/src/bot_graphql/queries/achievement_query.py new file mode 100644 index 00000000..c9782973 --- /dev/null +++ b/kdb-bot/src/bot_graphql/queries/achievement_query.py @@ -0,0 +1,19 @@ +from cpl_core.database.context import DatabaseContextABC + +from bot_data.model.user_history import UserHistory +from bot_graphql.abc.data_query_with_history_abc import DataQueryWithHistoryABC + + +class AchievementQuery(DataQueryWithHistoryABC): + def __init__( + self, + db: DatabaseContextABC, + ): + DataQueryWithHistoryABC.__init__(self, "Achievement", "AchievementsHistory", UserHistory, db) + + self.set_field("id", lambda x: x.id) + self.set_field("name", lambda x: x.name) + self.set_field("attribute", lambda x: x.attribute) + self.set_field("operator", lambda x: x.operator) + self.set_field("value", lambda x: x.value) + self.set_field("server", lambda x: x.server) diff --git a/kdb-bot/src/bot_graphql/query.py b/kdb-bot/src/bot_graphql/query.py index 8133e4dc..976b1950 100644 --- a/kdb-bot/src/bot_graphql/query.py +++ b/kdb-bot/src/bot_graphql/query.py @@ -1,5 +1,6 @@ from cpl_discord.service import DiscordBotServiceABC +from bot_data.abc.achievement_repository_abc import AchievementRepositoryABC from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC from bot_data.abc.client_repository_abc import ClientRepositoryABC from bot_data.abc.known_user_repository_abc import KnownUserRepositoryABC @@ -10,6 +11,7 @@ from bot_data.abc.user_joined_server_repository_abc import UserJoinedServerRepos from bot_data.abc.user_joined_voice_channel_repository_abc import UserJoinedVoiceChannelRepositoryABC from bot_data.abc.user_repository_abc import UserRepositoryABC from bot_graphql.abc.query_abc import QueryABC +from bot_graphql.filter.achievement_filter import AchievementFilter from bot_graphql.filter.auto_role_filter import AutoRoleFilter from bot_graphql.filter.auto_role_rule_filter import AutoRoleRuleFilter from bot_graphql.filter.client_filter import ClientFilter @@ -34,6 +36,7 @@ class Query(QueryABC): user_joined_voice_channels: UserJoinedVoiceChannelRepositoryABC, user_joined_game_server: UserJoinedGameServerRepositoryABC, users: UserRepositoryABC, + achievements: AchievementRepositoryABC, ): QueryABC.__init__(self, "Query") @@ -59,6 +62,7 @@ class Query(QueryABC): UserJoinedGameServerFilter, ) self.add_collection("user", lambda *_: users.get_users(), UserFilter) + self.add_collection("achievement", lambda *_: achievements.get_achievements(), AchievementFilter) self.set_field("guilds", self._resolve_guilds) diff --git a/kdb-web/package.json b/kdb-web/package.json index 8e415632..e77d9ec0 100644 --- a/kdb-web/package.json +++ b/kdb-web/package.json @@ -51,4 +51,4 @@ "tslib": "^2.4.1", "typescript": "~4.9.5" } -} +} \ No newline at end of file diff --git a/kdb-web/src/assets/config.json b/kdb-web/src/assets/config.json index f9117e39..57eaafa7 100644 --- a/kdb-web/src/assets/config.json +++ b/kdb-web/src/assets/config.json @@ -25,4 +25,4 @@ "Name": "sh-edraft-dark-theme" } ] -} +} \ No newline at end of file