diff --git a/kdb-bot/.cpl/schematic_query.py b/kdb-bot/.cpl/schematic_query.py new file mode 100644 index 00000000..e34a3b6e --- /dev/null +++ b/kdb-bot/.cpl/schematic_query.py @@ -0,0 +1,34 @@ +from cpl_cli.abc.generate_schematic_abc import GenerateSchematicABC + + +class query(GenerateSchematicABC): + def __init__(self, *args: str): + GenerateSchematicABC.__init__(self, *args) + + def get_code(self) -> str: + import textwrap + + code = textwrap.dedent( + """\ + from bot_graphql.abc.data_query_abc import DataQueryABC + + + class $ClassName(DataQueryABC): + def __init__(self): + DataQueryABC.__init__(self, "Name") + + self.set_field("id", self.resolve_id) + + @staticmethod + def resolve_id(x, *_): + return x.id + """ + ) + return self.build_code_str( + code, + ClassName=self._class_name, + ) + + @classmethod + def register(cls): + GenerateSchematicABC.register(cls, "query", []) diff --git a/kdb-bot/cpl-workspace.json b/kdb-bot/cpl-workspace.json index 5a5654f3..2c9a6445 100644 --- a/kdb-bot/cpl-workspace.json +++ b/kdb-bot/cpl-workspace.json @@ -6,6 +6,7 @@ "bot-api": "src/bot_api/bot-api.json", "bot-core": "src/bot_core/bot-core.json", "bot-data": "src/bot_data/bot-data.json", + "bot-graphql": "src/bot_graphql/bot-graphql.json", "auto-role": "src/modules/auto_role/auto-role.json", "base": "src/modules/base/base.json", "boot-log": "src/modules/boot_log/boot-log.json", diff --git a/kdb-bot/src/bot/bot.json b/kdb-bot/src/bot/bot.json index 8d20c966..2245c518 100644 --- a/kdb-bot/src/bot/bot.json +++ b/kdb-bot/src/bot/bot.json @@ -16,7 +16,7 @@ "LicenseName": "MIT", "LicenseDescription": "MIT, see LICENSE for more details.", "Dependencies": [ - "cpl-core==2022.12.1.post2", + "cpl-core==2022.12.1.post3", "cpl-translation==2022.12.1", "cpl-query==2022.12.2.post1", "cpl-discord==2022.12.1.post2", @@ -28,10 +28,11 @@ "Flask-SocketIO==5.3.2", "eventlet==0.33.2", "requests-oauthlib==1.3.1", - "icmplib==3.0.3" + "icmplib==3.0.3", + "ariadne==0.17.1" ], "DevDependencies": [ - "cpl-cli==2022.12.1.post2" + "cpl-cli==2022.12.1.post3" ], "PythonVersion": ">=3.10.4", "PythonPath": {}, @@ -55,6 +56,7 @@ "../bot_api/bot-api.json", "../bot_core/bot-core.json", "../bot_data/bot-data.json", + "../bot_graphql/bot-graphql.json", "../modules/auto_role/auto-role.json", "../modules/base/base.json", "../modules/boot_log/boot-log.json", diff --git a/kdb-bot/src/bot/config b/kdb-bot/src/bot/config index 54b1b386..b0ae8762 160000 --- a/kdb-bot/src/bot/config +++ b/kdb-bot/src/bot/config @@ -1 +1 @@ -Subproject commit 54b1b3860cb570d29c8ba2590dd082a1fa744265 +Subproject commit b0ae87621bbe54fd9c5650071ec8c1c9ec32df48 diff --git a/kdb-bot/src/bot/module_list.py b/kdb-bot/src/bot/module_list.py index a48a2e39..b5388245 100644 --- a/kdb-bot/src/bot/module_list.py +++ b/kdb-bot/src/bot/module_list.py @@ -4,6 +4,7 @@ from bot_api.api_module import ApiModule from bot_core.core_extension.core_extension_module import CoreExtensionModule from bot_core.core_module import CoreModule from bot_data.data_module import DataModule +from bot_graphql.graphql_module import GraphQLModule from modules.auto_role.auto_role_module import AutoRoleModule from modules.base.base_module import BaseModule from modules.boot_log.boot_log_module import BootLogModule @@ -23,6 +24,7 @@ class ModuleList: [ CoreModule, # has to be first! DataModule, + GraphQLModule, PermissionModule, DatabaseModule, AutoRoleModule, diff --git a/kdb-bot/src/bot_api/api.py b/kdb-bot/src/bot_api/api.py index e8872a5c..023fd54b 100644 --- a/kdb-bot/src/bot_api/api.py +++ b/kdb-bot/src/bot_api/api.py @@ -1,4 +1,3 @@ -import re import sys import textwrap import uuid @@ -16,7 +15,6 @@ from werkzeug.exceptions import NotFound from bot_api.configuration.api_settings import ApiSettings from bot_api.configuration.authentication_settings import AuthenticationSettings -from bot_api.configuration.frontend_settings import FrontendSettings from bot_api.exception.service_error_code_enum import ServiceErrorCode from bot_api.exception.service_exception import ServiceException from bot_api.logging.api_logger import ApiLogger @@ -30,7 +28,6 @@ class Api(Flask): logger: ApiLogger, services: ServiceProviderABC, api_settings: ApiSettings, - frontend_settings: FrontendSettings, auth_settings: AuthenticationSettings, *args, **kwargs, @@ -146,20 +143,13 @@ class Api(Flask): return response def start(self): - self._logger.info( - __name__, - f"Starting API {self._api_settings.host}:{self._api_settings.port}", - ) + self._logger.info(__name__, f"Starting API {self._api_settings.host}:{self._api_settings.port}") self._register_routes() self.secret_key = CredentialManager.decrypt(self._auth_settings.secret_key) # from waitress import serve # https://docs.pylonsproject.org/projects/waitress/en/stable/arguments.html # serve(self, host=self._apt_settings.host, port=self._apt_settings.port, threads=10, connection_limit=1000, channel_timeout=10) - wsgi.server( - eventlet.listen((self._api_settings.host, self._api_settings.port)), - self, - log_output=False, - ) + wsgi.server(eventlet.listen((self._api_settings.host, self._api_settings.port)), self, log_output=False) def on_connect(self): self._logger.info(__name__, f"Client connected") diff --git a/kdb-bot/src/bot_api/api_module.py b/kdb-bot/src/bot_api/api_module.py index 81030d51..21097b40 100644 --- a/kdb-bot/src/bot_api/api_module.py +++ b/kdb-bot/src/bot_api/api_module.py @@ -14,6 +14,7 @@ from bot_api.api_thread import ApiThread from bot_api.controller.auth_controller import AuthController from bot_api.controller.auth_discord_controller import AuthDiscordController from bot_api.controller.discord.server_controller import ServerController +from bot_api.controller.grahpql_controller import GraphQLController from bot_api.controller.gui_controller import GuiController from bot_api.event.bot_api_on_ready_event import BotApiOnReadyEvent from bot_api.service.auth_service import AuthService @@ -46,6 +47,7 @@ class ApiModule(ModuleABC): services.add_transient(GuiController) services.add_transient(DiscordService) services.add_transient(ServerController) + services.add_transient(GraphQLController) # cpl-discord self._dc.add_event(DiscordEventTypesEnum.on_ready.value, BotApiOnReadyEvent) diff --git a/kdb-bot/src/bot_api/controller/grahpql_controller.py b/kdb-bot/src/bot_api/controller/grahpql_controller.py new file mode 100644 index 00000000..cc5e4c7c --- /dev/null +++ b/kdb-bot/src/bot_api/controller/grahpql_controller.py @@ -0,0 +1,39 @@ +from ariadne import graphql_sync +from ariadne.constants import PLAYGROUND_HTML +from cpl_core.configuration import ConfigurationABC +from cpl_core.environment import ApplicationEnvironmentABC +from flask import request, jsonify + +from bot_api.logging.api_logger import ApiLogger +from bot_api.route.route import Route +from bot_graphql.schema import Schema + + +class GraphQLController: + BasePath = f"/api/graphql" + + def __init__( + self, + config: ConfigurationABC, + env: ApplicationEnvironmentABC, + logger: ApiLogger, + schema: Schema, + ): + self._config = config + self._env = env + self._logger = logger + self._schema = schema + + @Route.get(f"{BasePath}/playground") + async def playground(self): + return PLAYGROUND_HTML, 200 + + @Route.post(f"{BasePath}") + async def graphql(self): + data = request.get_json() + + # Note: Passing the request to the context is optional. + # In Flask, the current request is always accessible as flask.request + success, result = graphql_sync(self._schema.schema, data, context_value=request) + + return jsonify(result), 200 if success else 400 diff --git a/kdb-bot/src/bot_api/exception/service_error_code_enum.py b/kdb-bot/src/bot_api/exception/service_error_code_enum.py index 5848bf33..4bb3072f 100644 --- a/kdb-bot/src/bot_api/exception/service_error_code_enum.py +++ b/kdb-bot/src/bot_api/exception/service_error_code_enum.py @@ -4,7 +4,6 @@ from werkzeug.exceptions import Unauthorized class ServiceErrorCode(Enum): - Unknown = 0 InvalidDependencies = 1 diff --git a/kdb-bot/src/bot_data/abc/client_repository_abc.py b/kdb-bot/src/bot_data/abc/client_repository_abc.py index 97d34e13..3b9f9132 100644 --- a/kdb-bot/src/bot_data/abc/client_repository_abc.py +++ b/kdb-bot/src/bot_data/abc/client_repository_abc.py @@ -2,6 +2,7 @@ from abc import ABC, abstractmethod from typing import Optional from cpl_query.extension import List + from bot_data.model.client import Client @@ -22,6 +23,10 @@ class ClientRepositoryABC(ABC): def get_client_by_discord_id(self, discord_id: int) -> Client: pass + @abstractmethod + def get_clients_by_server_id(self, server_id: int) -> List[Client]: + pass + @abstractmethod def find_client_by_discord_id(self, discord_id: int) -> Optional[Client]: pass diff --git a/kdb-bot/src/bot_data/abc/user_joined_server_repository_abc.py b/kdb-bot/src/bot_data/abc/user_joined_server_repository_abc.py index 2b8dcc5f..cbc3a718 100644 --- a/kdb-bot/src/bot_data/abc/user_joined_server_repository_abc.py +++ b/kdb-bot/src/bot_data/abc/user_joined_server_repository_abc.py @@ -2,6 +2,7 @@ from abc import ABC, abstractmethod from typing import Optional from cpl_query.extension import List + from bot_data.model.user_joined_server import UserJoinedServer @@ -18,6 +19,10 @@ class UserJoinedServerRepositoryABC(ABC): def get_user_joined_server_by_id(self, id: int) -> UserJoinedServer: pass + @abstractmethod + def get_user_joined_server_by_server_id(self, server_id: int) -> UserJoinedServer: + pass + @abstractmethod def get_user_joined_servers_by_user_id(self, user_id: int) -> list[UserJoinedServer]: pass diff --git a/kdb-bot/src/bot_data/abc/user_repository_abc.py b/kdb-bot/src/bot_data/abc/user_repository_abc.py index c40f20e5..0e3ced21 100644 --- a/kdb-bot/src/bot_data/abc/user_repository_abc.py +++ b/kdb-bot/src/bot_data/abc/user_repository_abc.py @@ -27,6 +27,10 @@ class UserRepositoryABC(ABC): def get_users_by_discord_id(self, discord_id: int) -> List[User]: pass + @abstractmethod + def get_users_by_server_id(self, server_id: int) -> List[User]: + pass + @abstractmethod def get_user_by_discord_id_and_server_id(self, discord_id: int, server_id: int) -> User: pass diff --git a/kdb-bot/src/bot_data/db_context.py b/kdb-bot/src/bot_data/db_context.py index 6e208ed9..6e11f284 100644 --- a/kdb-bot/src/bot_data/db_context.py +++ b/kdb-bot/src/bot_data/db_context.py @@ -6,7 +6,6 @@ from bot_core.logging.database_logger import DatabaseLogger class DBContext(DatabaseContext): def __init__(self, logger: DatabaseLogger): - self._logger = logger DatabaseContext.__init__(self) diff --git a/kdb-bot/src/bot_data/model/auth_role_enum.py b/kdb-bot/src/bot_data/model/auth_role_enum.py index e1526136..8b93629b 100644 --- a/kdb-bot/src/bot_data/model/auth_role_enum.py +++ b/kdb-bot/src/bot_data/model/auth_role_enum.py @@ -2,6 +2,5 @@ from enum import Enum class AuthRoleEnum(Enum): - normal = 0 admin = 1 diff --git a/kdb-bot/src/bot_data/model/auto_role.py b/kdb-bot/src/bot_data/model/auto_role.py index dfef0155..16287e6e 100644 --- a/kdb-bot/src/bot_data/model/auto_role.py +++ b/kdb-bot/src/bot_data/model/auto_role.py @@ -3,11 +3,13 @@ from typing import Optional from cpl_core.database import TableABC +from bot_data.model.server import Server + class AutoRole(TableABC): def __init__( self, - server_id: int, + server: Optional[Server], dc_channel_id: int, dc_message_id: int, created_at: datetime = None, @@ -15,7 +17,7 @@ class AutoRole(TableABC): id=0, ): self._auto_role_id = id - self._server_id = server_id + self._server = server self._discord_channel_id = dc_channel_id self._discord_message_id = dc_message_id @@ -28,17 +30,25 @@ class AutoRole(TableABC): return self._auto_role_id @property - def server_id(self) -> int: - return self._server_id + def server(self) -> Server: + return self._server @property def discord_channel_id(self) -> int: return self._discord_channel_id + @discord_channel_id.setter + def discord_channel_id(self, value: int): + self._discord_channel_id = value + @property def discord_message_id(self) -> int: return self._discord_message_id + @discord_message_id.setter + def discord_message_id(self, value: int): + self._discord_message_id = value + @staticmethod def get_select_all_string() -> str: return str( @@ -81,7 +91,7 @@ class AutoRole(TableABC): INSERT INTO `AutoRoles` ( `ServerId`, `DiscordChannelId`, `DiscordMessageId`, `CreatedAt`, `LastModifiedAt` ) VALUES ( - {self._server_id}, + {self._server.server_id}, {self._discord_channel_id}, {self._discord_message_id}, '{self._created_at}', @@ -95,7 +105,7 @@ class AutoRole(TableABC): return str( f""" UPDATE `AutoRoles` - SET `ServerId` = {self._server_id}, + SET `ServerId` = {self._server.server_id}, `DiscordChannelId` = {self._discord_channel_id}, `DiscordMessageId` = {self._discord_message_id}, `LastModifiedAt` = '{self._modified_at}' 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 01d45ebe..f7166637 100644 --- a/kdb-bot/src/bot_data/model/auto_role_rule.py +++ b/kdb-bot/src/bot_data/model/auto_role_rule.py @@ -1,13 +1,14 @@ from datetime import datetime -from typing import Optional from cpl_core.database import TableABC +from bot_data.model.auto_role import AutoRole + class AutoRoleRule(TableABC): def __init__( self, - auto_role_id: int, + auto_role: AutoRole, discord_emoji_name: str, discord_role_id: int, created_at: datetime = None, @@ -15,7 +16,7 @@ class AutoRoleRule(TableABC): id=0, ): self._auto_role_rule_id = id - self._auto_role_id = auto_role_id + self._auto_role = auto_role self._discord_emoji_name = discord_emoji_name self._discord_role_id = discord_role_id @@ -28,17 +29,25 @@ class AutoRoleRule(TableABC): return self._auto_role_rule_id @property - def auto_role_id(self) -> int: - return self._auto_role_id + def auto_role(self) -> AutoRole: + return self._auto_role @property def emoji_name(self) -> str: return self._discord_emoji_name + @emoji_name.setter + def emoji_name(self, value: str): + self._discord_emoji_name = value + @property def role_id(self) -> int: return self._discord_role_id + @role_id.setter + def role_id(self, value: int): + self._discord_role_id = value + @staticmethod def get_select_all_string() -> str: return str( @@ -72,7 +81,7 @@ class AutoRoleRule(TableABC): INSERT INTO `AutoRoleRules` ( `AutoRoleId`, `DiscordEmojiName`, `DiscordRoleId`, `CreatedAt`, `LastModifiedAt` ) VALUES ( - {self._auto_role_id}, + {self._auto_role}, '{self._discord_emoji_name}', {self._discord_role_id}, '{self._created_at}', @@ -86,7 +95,7 @@ class AutoRoleRule(TableABC): return str( f""" UPDATE `AutoRoleRules` - SET `AutoRoleId` = {self._auto_role_id}, + SET `AutoRoleId` = {self._auto_role}, `DiscordEmojiName` = {self._discord_emoji_name}, `DiscordRoleId` = {self._discord_role_id}, `LastModifiedAt` = '{self._modified_at}' diff --git a/kdb-bot/src/bot_data/model/known_user.py b/kdb-bot/src/bot_data/model/known_user.py index be64d9d5..3c708f9b 100644 --- a/kdb-bot/src/bot_data/model/known_user.py +++ b/kdb-bot/src/bot_data/model/known_user.py @@ -1,8 +1,6 @@ from datetime import datetime -from typing import Optional -from cpl_core.database import TableABC -from bot_data.model.server import Server +from cpl_core.database import TableABC class KnownUser(TableABC): diff --git a/kdb-bot/src/bot_data/model/user.py b/kdb-bot/src/bot_data/model/user.py index 1592e471..ab97ecd1 100644 --- a/kdb-bot/src/bot_data/model/user.py +++ b/kdb-bot/src/bot_data/model/user.py @@ -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 @@ -62,6 +63,15 @@ class User(TableABC): """ ) + @staticmethod + def get_select_by_server_id_string(server_id: int) -> str: + return str( + f""" + SELECT * FROM `Users` + WHERE `ServerId` = {server_id}; + """ + ) + @staticmethod def get_select_by_discord_id_string(id: int) -> str: return str( diff --git a/kdb-bot/src/bot_data/model/user_joined_server.py b/kdb-bot/src/bot_data/model/user_joined_server.py index 7c0764d1..134e2f47 100644 --- a/kdb-bot/src/bot_data/model/user_joined_server.py +++ b/kdb-bot/src/bot_data/model/user_joined_server.py @@ -1,10 +1,8 @@ from datetime import datetime -from typing import Optional from cpl_core.database import TableABC from bot_data.model.user import User -from bot_data.model.server import Server class UserJoinedServer(TableABC): @@ -69,6 +67,15 @@ class UserJoinedServer(TableABC): """ ) + @staticmethod + def get_select_by_server_id_string(id: int) -> str: + return str( + f""" + SELECT * FROM `UserJoinedServers` + WHERE `ServerId` = {id}; + """ + ) + @staticmethod def get_select_by_user_id_string(id: int) -> str: return str( diff --git a/kdb-bot/src/bot_data/service/auto_role_repository_service.py b/kdb-bot/src/bot_data/service/auto_role_repository_service.py index b9d51e12..d1599341 100644 --- a/kdb-bot/src/bot_data/service/auto_role_repository_service.py +++ b/kdb-bot/src/bot_data/service/auto_role_repository_service.py @@ -5,14 +5,16 @@ from cpl_query.extension import List from bot_core.logging.database_logger import DatabaseLogger from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC +from bot_data.abc.server_repository_abc import ServerRepositoryABC from bot_data.model.auto_role import AutoRole from bot_data.model.auto_role_rule import AutoRoleRule class AutoRoleRepositoryService(AutoRoleRepositoryABC): - def __init__(self, logger: DatabaseLogger, db_context: DatabaseContextABC): + def __init__(self, logger: DatabaseLogger, db_context: DatabaseContextABC, servers: ServerRepositoryABC): self._logger = logger self._context = db_context + self._servers = servers AutoRoleRepositoryABC.__init__(self) @@ -21,14 +23,20 @@ class AutoRoleRepositoryService(AutoRoleRepositoryABC): self._logger.trace(__name__, f"Send SQL command: {AutoRole.get_select_all_string()}") results = self._context.select(AutoRole.get_select_all_string()) for result in results: - auto_roles.append(AutoRole(result[1], result[2], result[3], result[4], result[5], id=result[0])) + auto_roles.append( + AutoRole( + self._servers.get_server_by_id(result[1]), result[2], result[3], result[4], result[5], id=result[0] + ) + ) return auto_roles def get_auto_role_by_id(self, id: int) -> AutoRole: self._logger.trace(__name__, f"Send SQL command: {AutoRole.get_select_by_id_string(id)}") result = self._context.select(AutoRole.get_select_by_id_string(id))[0] - return AutoRole(result[1], result[2], result[3], result[4], result[5], id=result[0]) + return AutoRole( + self._servers.get_server_by_id(result[1]), result[2], result[3], result[4], result[5], id=result[0] + ) def find_auto_role_by_id(self, id: int) -> Optional[AutoRole]: self._logger.trace(__name__, f"Send SQL command: {AutoRole.get_select_by_id_string(id)}") @@ -38,14 +46,20 @@ class AutoRoleRepositoryService(AutoRoleRepositoryABC): result = result[0] - return AutoRole(result[1], result[2], result[3], result[4], result[5], id=result[0]) + return AutoRole( + self._servers.get_server_by_id(result[1]), result[2], result[3], result[4], result[5], id=result[0] + ) def get_auto_roles_by_server_id(self, id: int) -> List[AutoRole]: self._logger.trace(__name__, f"Send SQL command: {AutoRole.get_select_by_server_id_string(id)}") auto_roles = List(AutoRole) results = self._context.select(AutoRole.get_select_by_server_id_string(id)) for result in results: - auto_roles.append(AutoRole(result[1], result[2], result[3], result[4], result[5], id=result[0])) + auto_roles.append( + AutoRole( + self._servers.get_server_by_id(result[1]), result[2], result[3], result[4], result[5], id=result[0] + ) + ) return auto_roles @@ -55,7 +69,9 @@ class AutoRoleRepositoryService(AutoRoleRepositoryABC): f"Send SQL command: {AutoRole.get_select_by_message_id_string(id)}", ) result = self._context.select(AutoRole.get_select_by_message_id_string(id))[0] - return AutoRole(result[1], result[2], result[3], result[4], result[5], id=result[0]) + return AutoRole( + self._servers.get_server_by_id(result[1]), result[2], result[3], result[4], result[5], id=result[0] + ) def find_auto_role_by_message_id(self, id: int) -> Optional[AutoRole]: self._logger.trace( @@ -68,7 +84,9 @@ class AutoRoleRepositoryService(AutoRoleRepositoryABC): result = result[0] - return AutoRole(result[1], result[2], result[3], result[4], result[5], id=result[0]) + return AutoRole( + self._servers.get_server_by_id(result[1]), result[2], result[3], result[4], result[5], id=result[0] + ) def add_auto_role(self, auto_role: AutoRole): self._logger.trace(__name__, f"Send SQL command: {auto_role.insert_string}") @@ -87,14 +105,20 @@ class AutoRoleRepositoryService(AutoRoleRepositoryABC): self._logger.trace(__name__, f"Send SQL command: {AutoRoleRule.get_select_all_string()}") results = self._context.select(AutoRoleRule.get_select_all_string()) for result in results: - auto_role_rules.append(AutoRoleRule(result[1], result[2], result[3], result[4], result[5], id=result[0])) + auto_role_rules.append( + AutoRoleRule( + self.get_auto_role_by_id(result[1]), result[2], result[3], result[4], result[5], id=result[0] + ) + ) return auto_role_rules def get_auto_role_rule_by_id(self, id: int) -> AutoRoleRule: self._logger.trace(__name__, f"Send SQL command: {AutoRoleRule.get_select_by_id_string(id)}") result = self._context.select(AutoRoleRule.get_select_by_id_string(id))[0] - return AutoRoleRule(result[1], result[2], result[3], result[4], result[5], id=result[0]) + return AutoRoleRule( + self.get_auto_role_by_id(result[1]), result[2], result[3], result[4], result[5], id=result[0] + ) def get_auto_role_rules_by_auto_role_id(self, id: int) -> List[AutoRoleRule]: auto_role_rules = List(AutoRoleRule) @@ -104,7 +128,11 @@ class AutoRoleRepositoryService(AutoRoleRepositoryABC): ) results = self._context.select(AutoRoleRule.get_select_by_auto_role_id_string(id)) for result in results: - auto_role_rules.append(AutoRoleRule(result[1], result[2], result[3], result[4], result[5], id=result[0])) + auto_role_rules.append( + AutoRoleRule( + self.get_auto_role_by_id(result[1]), result[2], result[3], result[4], result[5], id=result[0] + ) + ) return auto_role_rules diff --git a/kdb-bot/src/bot_data/service/client_repository_service.py b/kdb-bot/src/bot_data/service/client_repository_service.py index 85a4f51e..51d3b6cf 100644 --- a/kdb-bot/src/bot_data/service/client_repository_service.py +++ b/kdb-bot/src/bot_data/service/client_repository_service.py @@ -38,6 +38,8 @@ class ClientRepositoryService(ClientRepositoryABC): result[5], result[6], self._servers.get_server_by_id(result[7]), + result[8], + result[9], id=result[0], ) ) @@ -55,9 +57,33 @@ class ClientRepositoryService(ClientRepositoryABC): result[5], result[6], self._servers.get_server_by_id(result[7]), + result[8], + result[9], id=result[0], ) + def get_clients_by_server_id(self, server_id: int) -> List[Client]: + clients = List(Client) + self._logger.trace(__name__, f"Send SQL command: {Client.get_select_by_server_id_string(server_id)}") + results = self._context.select(Client.get_select_by_server_id_string(server_id)) + for result in results: + clients.append( + Client( + result[1], + result[2], + result[3], + result[4], + result[5], + result[6], + self._servers.get_server_by_id(result[7]), + result[8], + result[9], + id=result[0], + ) + ) + + return clients + def get_client_by_discord_id(self, discord_id: int) -> Client: self._logger.trace( __name__, @@ -72,6 +98,8 @@ class ClientRepositoryService(ClientRepositoryABC): result[5], result[6], self._servers.get_server_by_id(result[7]), + result[8], + result[9], id=result[0], ) @@ -94,6 +122,8 @@ class ClientRepositoryService(ClientRepositoryABC): result[5], result[6], self._servers.get_server_by_id(result[7]), + result[8], + result[9], id=result[0], ) @@ -116,6 +146,8 @@ class ClientRepositoryService(ClientRepositoryABC): result[5], result[6], self._servers.get_server_by_id(result[7]), + result[8], + result[9], id=result[0], ) @@ -138,6 +170,8 @@ class ClientRepositoryService(ClientRepositoryABC): result[5], result[6], self._servers.get_server_by_id(result[7]), + result[8], + result[9], id=result[0], ) diff --git a/kdb-bot/src/bot_data/service/server_repository_service.py b/kdb-bot/src/bot_data/service/server_repository_service.py index ab6fbe84..3291ceaa 100644 --- a/kdb-bot/src/bot_data/service/server_repository_service.py +++ b/kdb-bot/src/bot_data/service/server_repository_service.py @@ -22,7 +22,7 @@ class ServerRepositoryService(ServerRepositoryABC): self._logger.trace(__name__, f"Send SQL command: {Server.get_select_all_string()}") results = self._context.select(Server.get_select_all_string()) for result in results: - servers.append(Server(result[1], id=result[0])) + servers.append(Server(result[1], result[2], result[3], id=result[0])) return servers @@ -54,7 +54,7 @@ class ServerRepositoryService(ServerRepositoryABC): def get_server_by_id(self, server_id: int) -> Server: self._logger.trace(__name__, f"Send SQL command: {Server.get_select_by_id_string(server_id)}") result = self._context.select(Server.get_select_by_id_string(server_id))[0] - return Server(result[1], id=result[0]) + return Server(result[1], result[2], result[3], id=result[0]) def get_server_by_discord_id(self, discord_id: int) -> Server: self._logger.trace( @@ -62,7 +62,7 @@ class ServerRepositoryService(ServerRepositoryABC): f"Send SQL command: {Server.get_select_by_discord_id_string(discord_id)}", ) result = self._context.select(Server.get_select_by_discord_id_string(discord_id))[0] - return Server(result[1], id=result[0]) + return Server(result[1], result[2], result[3], id=result[0]) def find_server_by_discord_id(self, discord_id: int) -> Optional[Server]: self._logger.trace( diff --git a/kdb-bot/src/bot_data/service/user_joined_server_repository_service.py b/kdb-bot/src/bot_data/service/user_joined_server_repository_service.py index 3c8a9d4b..abd0a17b 100644 --- a/kdb-bot/src/bot_data/service/user_joined_server_repository_service.py +++ b/kdb-bot/src/bot_data/service/user_joined_server_repository_service.py @@ -57,6 +57,21 @@ class UserJoinedServerRepositoryService(UserJoinedServerRepositoryABC): id=result[0], ) + def get_user_joined_server_by_server_id(self, server_id: int) -> UserJoinedServer: + self._logger.trace( + __name__, + f"Send SQL command: {UserJoinedServer.get(id)}", + ) + result = self._context.select(UserJoinedServer.get_select_by_id_string(id))[0] + return UserJoinedServer( + self._users.get_user_by_id(result[1]), + result[2], + result[3], + result[4], + result[5], + id=result[0], + ) + def get_user_joined_servers_by_user_id(self, user_id: int) -> List[UserJoinedServer]: joins = List(UserJoinedServer) self._logger.trace( diff --git a/kdb-bot/src/bot_data/service/user_repository_service.py b/kdb-bot/src/bot_data/service/user_repository_service.py index 00ee4a64..9d44c0ba 100644 --- a/kdb-bot/src/bot_data/service/user_repository_service.py +++ b/kdb-bot/src/bot_data/service/user_repository_service.py @@ -85,6 +85,25 @@ class UserRepositoryService(UserRepositoryABC): return users + def get_users_by_server_id(self, server_id: int) -> List[User]: + users = List(User) + self._logger.trace( + __name__, + f"Send SQL command: {User.get_select_by_server_id_string(server_id)}", + ) + results = self._context.select(User.get_select_by_server_id_string(server_id)) + for result in results: + users.append( + User( + result[1], + result[2], + self._servers.get_server_by_id(result[3]), + id=result[0], + ) + ) + + return users + def get_user_by_discord_id_and_server_id(self, discord_id: int, server_id: int) -> User: self._logger.trace( __name__, diff --git a/kdb-bot/src/bot_graphql/__init__.py b/kdb-bot/src/bot_graphql/__init__.py new file mode 100644 index 00000000..425ab6c1 --- /dev/null +++ b/kdb-bot/src/bot_graphql/__init__.py @@ -0,0 +1 @@ +# imports diff --git a/kdb-bot/src/bot_graphql/abc/__init__.py b/kdb-bot/src/bot_graphql/abc/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/kdb-bot/src/bot_graphql/abc/data_query_abc.py b/kdb-bot/src/bot_graphql/abc/data_query_abc.py new file mode 100644 index 00000000..7603a4d2 --- /dev/null +++ b/kdb-bot/src/bot_graphql/abc/data_query_abc.py @@ -0,0 +1,19 @@ +from cpl_core.database import TableABC + +from bot_graphql.abc.query_abc import QueryABC + + +class DataQueryABC(QueryABC): + def __init__(self, name: str): + QueryABC.__init__(self, name) + + self.set_field("createdAt", self.resolve_created_at) + self.set_field("modifiedAt", self.resolve_modified_at) + + @staticmethod + def resolve_created_at(entry: TableABC, *_): + return entry.created_at + + @staticmethod + def resolve_modified_at(entry: TableABC, *_): + return entry.modified_at diff --git a/kdb-bot/src/bot_graphql/abc/filter_abc.py b/kdb-bot/src/bot_graphql/abc/filter_abc.py new file mode 100644 index 00000000..e0d5ff8d --- /dev/null +++ b/kdb-bot/src/bot_graphql/abc/filter_abc.py @@ -0,0 +1,54 @@ +import functools +from abc import ABC, abstractmethod +from inspect import signature, Parameter + +from cpl_core.dependency_injection import ServiceProviderABC +from cpl_query.extension import List + + +class FilterABC(ABC): + def __init__(self): + ABC.__init__(self) + + @abstractmethod + def from_dict(self, values: dict): + pass + + @abstractmethod + def filter(self, query: List, *args) -> List: + pass + + @staticmethod + @ServiceProviderABC.inject + def get_filter(f, values: dict, services: ServiceProviderABC): + sig = signature(f) + for param in sig.parameters.items(): + parameter = param[1] + if parameter.name == "self" or parameter.name == "cls" or parameter.annotation == Parameter.empty: + continue + + if issubclass(parameter.annotation, FilterABC): + filter = services.get_service(parameter.annotation) + filter.from_dict(values) + return filter @ staticmethod + + @staticmethod + @ServiceProviderABC.inject + def get_collection_filter(filter_type: type, values: dict, services: ServiceProviderABC): + filter: FilterABC = services.get_service(filter_type) + filter.from_dict(values) + return filter + + @classmethod + def resolve_filter_annotation(cls, f=None): + if f is None: + return functools.partial(cls.resolve_filter_annotation) + + @functools.wraps(f) + def decorator(*args, **kwargs): + if "filter" in kwargs: + kwargs["filter"] = cls.get_filter(f, kwargs["filter"]) + + return f(*args, **kwargs) + + return decorator diff --git a/kdb-bot/src/bot_graphql/abc/query_abc.py b/kdb-bot/src/bot_graphql/abc/query_abc.py new file mode 100644 index 00000000..4e291ae4 --- /dev/null +++ b/kdb-bot/src/bot_graphql/abc/query_abc.py @@ -0,0 +1,50 @@ +from typing import Callable + +from ariadne import ObjectType +from cpl_query.extension import List + +from bot_graphql.abc.filter_abc import FilterABC +from bot_graphql.filter.page import Page +from bot_graphql.filter.sort import Sort + + +class QueryABC(ObjectType): + __abstract__ = True + + def __init__(self, name: str): + ObjectType.__init__(self, name) + + def add_collection(self, name: str, get_collection: Callable, filter_type: type = None): + def wrapper(*args, **kwargs): + if filter_type is not None and "filter" in kwargs: + kwargs["filter"] = FilterABC.get_collection_filter(filter_type, kwargs["filter"]) + else: + kwargs["filter"] = None + + if "page" in kwargs: + page = Page() + page.from_dict(kwargs["page"]) + kwargs["page"] = page + + if "sort" in kwargs: + sort = Sort() + sort.from_dict(kwargs["sort"]) + kwargs["sort"] = sort + + return self._resolve_collection(get_collection(*args), *args, **kwargs) + + self.set_field(f"{name}s", wrapper) + self.set_field(f"{name}Count", lambda *args: get_collection(*args).count()) + + # @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) + + if page is not None: + return page.filter(collection) + + if sort is not None: + return sort.filter(collection) + + return collection diff --git a/kdb-bot/src/bot_graphql/bot-graphql.json b/kdb-bot/src/bot_graphql/bot-graphql.json new file mode 100644 index 00000000..70ed81fd --- /dev/null +++ b/kdb-bot/src/bot_graphql/bot-graphql.json @@ -0,0 +1,44 @@ +{ + "ProjectSettings": { + "Name": "bot-data", + "Version": { + "Major": "0", + "Minor": "1", + "Micro": "0" + }, + "Author": "Sven Heidemann", + "AuthorEmail": "sven.heidemann@sh-edraft.de", + "Description": "Keksdose bot - graphql", + "LongDescription": "Discord bot for the Keksdose discord Server - graphql package", + "URL": "https://www.sh-edraft.de", + "CopyrightDate": "2023", + "CopyrightName": "sh-edraft.de", + "LicenseName": "MIT", + "LicenseDescription": "MIT, see LICENSE for more details.", + "Dependencies": [ + "cpl-core>=2022.12.1" + ], + "DevDependencies": [ + "cpl-cli>=2022.12.1" + ], + "PythonVersion": ">=3.10.4", + "PythonPath": {}, + "Classifiers": [] + }, + "BuildSettings": { + "ProjectType": "library", + "SourcePath": "", + "OutputPath": "../../dist", + "Main": "", + "EntryPoint": "", + "IncludePackageData": false, + "Included": [], + "Excluded": [ + "*/__pycache__", + "*/logs", + "*/tests" + ], + "PackageData": {}, + "ProjectReferences": [] + } +} \ No newline at end of file diff --git a/kdb-bot/src/bot_graphql/filter/__init__.py b/kdb-bot/src/bot_graphql/filter/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/kdb-bot/src/bot_graphql/filter/auto_role_filter.py b/kdb-bot/src/bot_graphql/filter/auto_role_filter.py new file mode 100644 index 00000000..ca02a7d4 --- /dev/null +++ b/kdb-bot/src/bot_graphql/filter/auto_role_filter.py @@ -0,0 +1,63 @@ +from cpl_discord.service import DiscordBotServiceABC +from cpl_query.extension import List + +from bot_data.model.auto_role import AutoRole +from bot_graphql.abc.filter_abc import FilterABC + + +class AutoRoleFilter(FilterABC): + def __init__( + self, + bot: DiscordBotServiceABC, + ): + FilterABC.__init__(self) + + self._bot = bot + + self._id = None + self._channel_id = None + self._channel_name = None + self._message_id = None + self._server = None + + def from_dict(self, values: dict): + if "id" in values: + self._id = int(values["id"]) + + if "channelId" in values: + self._channel_id = int(values["channelId"]) + + if "channelName" in values: + self._channel_name = values["channelName"] + + if "messageId" in values: + self._message_id = int(values["messageId"]) + + if "server" in values: + from bot_graphql.filter.server_filter import ServerFilter + + server = ServerFilter() + server.from_dict(values["server"]) + self._server = server + + 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) + + if self._channel_id is not None: + query = query.where(lambda x: x.discord_channel_id == self._channel_id) + + if self._channel_name is not None and self._channel_id is not None: + query = query.where( + lambda x: self._bot.get_channel(x.discord_channel_id).name == self._channel_name + or self._channel_name in self._bot.get_channel(x.discord_channel_id).name + ) + + if self._message_id is not None: + 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) + + return query diff --git a/kdb-bot/src/bot_graphql/filter/auto_role_rule_filter.py b/kdb-bot/src/bot_graphql/filter/auto_role_rule_filter.py new file mode 100644 index 00000000..44651957 --- /dev/null +++ b/kdb-bot/src/bot_graphql/filter/auto_role_rule_filter.py @@ -0,0 +1,63 @@ +from cpl_core.dependency_injection import ServiceProviderABC +from cpl_discord.service import DiscordBotServiceABC +from cpl_query.extension import List + +from bot_data.model.auto_role_rule import AutoRoleRule +from bot_graphql.abc.filter_abc import FilterABC + + +class AutoRoleRuleFilter(FilterABC): + def __init__(self, services: ServiceProviderABC, bot: DiscordBotServiceABC): + FilterABC.__init__(self) + self._services = services + self._bot = bot + + self._id = None + self._emoji_name = None + self._role_id = None + self._role_name = None + self._auto_role = None + + def from_dict(self, values: dict): + if "id" in values: + self._id = int(values["id"]) + + if "emojiName" in values: + self._emoji_name = values["emojiName"] + + if "roleId" in values: + self._role_id = int(values["roleId"]) + + if "roleName" in values: + self._role_name = values["roleName"] + + if "autoRole" in values: + from bot_graphql.filter.auto_role_filter import AutoRoleFilter + + self._auto_role: AutoRoleFilter = self._services.get_service(AutoRoleFilter) + self._auto_role.from_dict(values["auto_role"]) + + 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) + + if self._emoji_name is not None: + query = query.where(lambda x: x.emoji_name == self._emoji_name) + + if self._role_id is not None: + query = query.where(lambda x: x.role_id == self._role_id) + + 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) + 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) + + return query diff --git a/kdb-bot/src/bot_graphql/filter/client_filter.py b/kdb-bot/src/bot_graphql/filter/client_filter.py new file mode 100644 index 00000000..be81e742 --- /dev/null +++ b/kdb-bot/src/bot_graphql/filter/client_filter.py @@ -0,0 +1,47 @@ +from cpl_query.extension import List + +from bot_data.model.client import Client +from bot_graphql.abc.filter_abc import FilterABC + + +class ClientFilter(FilterABC): + def __init__(self): + FilterABC.__init__(self) + + self._id = None + self._discord_id = None + self._name = None + self._server = None + + def from_dict(self, values: dict): + if "id" in values: + self._id = int(values["id"]) + + if "discordId" in values: + self._id = int(values["discordId"]) + + if "name" in values: + self._name = values["name"] + + if "server" in values: + from bot_graphql.filter.server_filter import ServerFilter + + server = ServerFilter() + server.from_dict(values["server"]) + self._server = server + + def filter(self, query: List[Client]) -> List[Client]: + if self._id is not None: + query = query.where(lambda x: x.client_id == self._id) + + if self._discord_id is not None: + query = query.where(lambda x: x.client_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) + + return query diff --git a/kdb-bot/src/bot_graphql/filter/level_filter.py b/kdb-bot/src/bot_graphql/filter/level_filter.py new file mode 100644 index 00000000..c34ae63f --- /dev/null +++ b/kdb-bot/src/bot_graphql/filter/level_filter.py @@ -0,0 +1,42 @@ +from cpl_core.dependency_injection import ServiceProviderABC +from cpl_query.extension import List + +from bot_data.model.level import Level +from bot_graphql.abc.filter_abc import FilterABC + + +class LevelFilter(FilterABC): + def __init__(self, services: ServiceProviderABC): + FilterABC.__init__(self) + + self._services = services + + self._id = None + self._name = 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 "server" in values: + from bot_graphql.filter.server_filter import ServerFilter + + self._server: ServerFilter = self._services.get_service(LevelFilter) + self._server.from_dict(values["server"]) + + def filter(self, query: List[Level]) -> List[Level]: + 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: 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) + + return query diff --git a/kdb-bot/src/bot_graphql/filter/page.py b/kdb-bot/src/bot_graphql/filter/page.py new file mode 100644 index 00000000..b54080c9 --- /dev/null +++ b/kdb-bot/src/bot_graphql/filter/page.py @@ -0,0 +1,25 @@ +from cpl_query.extension import List + +from bot_graphql.abc.filter_abc import FilterABC + + +class Page(FilterABC): + def __init__(self): + FilterABC.__init__(self) + self._page_index = None + self._page_size = None + + def from_dict(self, values: dict): + if "pageIndex" in values: + self._page_index = int(values["pageIndex"]) + + if "pageSize" in values: + self._page_size = int(values["pageSize"]) + + def filter(self, query: List, *args) -> List: + if self._page_size is not None and self._page_index is not None: + skip = self._page_size * self._page_index + result = query.skip(skip).take(self._page_size) + return result + + return query diff --git a/kdb-bot/src/bot_graphql/filter/server_filter.py b/kdb-bot/src/bot_graphql/filter/server_filter.py new file mode 100644 index 00000000..2964d1d7 --- /dev/null +++ b/kdb-bot/src/bot_graphql/filter/server_filter.py @@ -0,0 +1,46 @@ +from cpl_core.dependency_injection import ServiceProviderABC +from cpl_discord.container import Guild +from cpl_discord.service import DiscordBotServiceABC +from cpl_query.extension import List + +from bot_data.model.server import Server +from bot_graphql.abc.filter_abc import FilterABC + + +class ServerFilter(FilterABC): + def __init__(self): + FilterABC.__init__(self) + + self._id = None + self._discord_id = None + self._name = None + + def from_dict(self, values: dict): + if "id" in values: + self._id = int(values["id"]) + + if "discordId" in values: + self._discord_id = int(values["discordId"]) + + if "name" in values: + self._name = values["name"] + + @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) + + if self._discord_id is not None: + query = query.where(lambda x: x.discord_server_id == self._discord_id) + + if self._name is not None: + + def where_guild(x: Guild): + guild = bot.get_guild(x.discord_server_id) + return guild is not None and ( + self._name.lower() == guild.name.lower() or self._name.lower() in guild.name.lower() + ) + + query = query.where(where_guild) + + return query diff --git a/kdb-bot/src/bot_graphql/filter/sort.py b/kdb-bot/src/bot_graphql/filter/sort.py new file mode 100644 index 00000000..f1c966dd --- /dev/null +++ b/kdb-bot/src/bot_graphql/filter/sort.py @@ -0,0 +1,20 @@ +from cpl_query.extension import List + +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 + + def from_dict(self, values: dict): + if "sortDirection" in values: + self._sort_direction = values["sortDirection"] + + if "sortColumn" in values: + self._sort_column = values["sortColumn"] + + def filter(self, query: List, *args) -> List: + return query diff --git a/kdb-bot/src/bot_graphql/filter/user_filter.py b/kdb-bot/src/bot_graphql/filter/user_filter.py new file mode 100644 index 00000000..b0028674 --- /dev/null +++ b/kdb-bot/src/bot_graphql/filter/user_filter.py @@ -0,0 +1,89 @@ +from typing import Optional + +from cpl_core.dependency_injection import ServiceProviderABC +from cpl_discord.service import DiscordBotServiceABC +from cpl_query.extension import List + +from bot_core.abc.client_utils_abc import ClientUtilsABC +from bot_data.model.user import User +from bot_graphql.abc.filter_abc import FilterABC +from bot_graphql.filter.level_filter import LevelFilter +from modules.level.service.level_service import LevelService + + +class UserFilter(FilterABC): + def __init__( + self, + services: ServiceProviderABC, + bot: DiscordBotServiceABC, + client_utils: ClientUtilsABC, + levels: LevelService, + ): + FilterABC.__init__(self) + + self._services = services + self._bot = bot + self._client_utils = client_utils + self._levels = levels + + self._id = None + self._discord_id = None + self._name = None + self._xp = None + self._ontime = None + self._level: Optional[LevelFilter] = None + + def from_dict(self, values: dict): + if "id" in values: + self._id = int(values["id"]) + + if "discordId" in values: + self._discord_id = int(values["discordId"]) + + if "name" in values: + self._name = values["name"] + + if "xp" in values: + self._xp = int(values["xp"]) + + if "ontime" in values: + self._ontime = int(values["ontime"]) + + if "level" in values: + self._level: LevelFilter = self._services.get_service(LevelFilter) + self._level.from_dict(values["level"]) + + 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._discord_id is not None: + query = query.where(lambda x: x.discord_id == self._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 + ) + + if self._xp is not None: + query = query.where(lambda x: x.xp == self._xp) + + if self._ontime is not None: + query = query.where(lambda x: self._client_utils.get_ontime_for_user(x) == self._ontime) + + if self._level is not None: + levels = self._level.filter(query.select(lambda x: self._levels.get_level(x))).select(lambda x: x.id) + 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) + + return query diff --git a/kdb-bot/src/bot_graphql/filter/user_joined_server_filter.py b/kdb-bot/src/bot_graphql/filter/user_joined_server_filter.py new file mode 100644 index 00000000..30af37fa --- /dev/null +++ b/kdb-bot/src/bot_graphql/filter/user_joined_server_filter.py @@ -0,0 +1,55 @@ +from cpl_core.dependency_injection import ServiceProviderABC +from cpl_discord.service import DiscordBotServiceABC +from cpl_query.extension import List + +from bot_data.model.user_joined_server import UserJoinedServer +from bot_graphql.abc.filter_abc import FilterABC + + +class UserJoinedServerFilter(FilterABC): + def __init__( + self, + services: ServiceProviderABC, + bot: DiscordBotServiceABC, + ): + FilterABC.__init__(self) + + self._services = services + self._bot = bot + + self._id = None + self._user = None + self._joined_on = None + self._leaved_on = None + + def from_dict(self, values: dict): + if "id" in values: + self._id = int(values["id"]) + + if "user" in values: + from bot_graphql.filter.user_filter import UserFilter + + self._user: UserFilter = self._services.get_service(UserFilter) + self._user.from_dict(values["user"]) + + if "joinedOn" in values: + self._joined_on = values["joinedOn"] + + if "leavedOn" in values: + self._leaved_on = values["leavedOn"] + + def filter(self, query: List[UserJoinedServer]) -> List[UserJoinedServer]: + if self._id is not None: + 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) + + 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) + + if self._leaved_on is not None: + query = query.where(lambda x: x.leaved_on == self._leaved_on or self._leaved_on in x.leaved_on) + + return query 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 new file mode 100644 index 00000000..bdbddeab --- /dev/null +++ b/kdb-bot/src/bot_graphql/filter/user_joined_voice_channel_filter.py @@ -0,0 +1,74 @@ +from cpl_core.dependency_injection import ServiceProviderABC +from cpl_discord.service import DiscordBotServiceABC +from cpl_query.extension import List + +from bot_data.model.user_joined_voice_channel import UserJoinedVoiceChannel +from bot_graphql.abc.filter_abc import FilterABC + + +class UserJoinedVoiceChannelFilter(FilterABC): + def __init__( + self, + services: ServiceProviderABC, + bot: DiscordBotServiceABC, + ): + FilterABC.__init__(self) + + self._services = services + self._bot = bot + + self._id = None + self._channel_id = None + self._channel_name = None + self._user = None + self._joined_on = None + self._leaved_on = None + + def from_dict(self, values: dict): + if "id" in values: + self._id = int(values["id"]) + + if "channelId" in values: + self._channel_id = int(values["channelId"]) + + if "channelName" in values: + self._channel_name = values["channelName"] + + if "user" in values: + from bot_graphql.filter.user_filter import UserFilter + + self._user: UserFilter = self._services.get_service(UserFilter) + self._user.from_dict(values["user"]) + + if "joinedOn" in values: + self._joined_on = values["joinedOn"] + + if "leavedOn" in values: + self._leaved_on = values["leavedOn"] + + def filter(self, query: List[UserJoinedVoiceChannel]) -> List[UserJoinedVoiceChannel]: + if self._id is not None: + 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) + + 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 + 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) + + 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) + + if self._leaved_on is not None: + query = query.where(lambda x: x.leaved_on == self._leaved_on or self._leaved_on in x.leaved_on) + + return query diff --git a/kdb-bot/src/bot_graphql/graphql_module.py b/kdb-bot/src/bot_graphql/graphql_module.py new file mode 100644 index 00000000..43da66e0 --- /dev/null +++ b/kdb-bot/src/bot_graphql/graphql_module.py @@ -0,0 +1,78 @@ +from cpl_core.configuration import ConfigurationABC +from cpl_core.dependency_injection import ServiceCollectionABC +from cpl_core.environment import ApplicationEnvironmentABC +from cpl_discord.service.discord_collection_abc import DiscordCollectionABC + +from bot_core.abc.module_abc import ModuleABC +from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum +from 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.auto_role_filter import AutoRoleFilter +from bot_graphql.filter.auto_role_rule_filter import AutoRoleRuleFilter +from bot_graphql.filter.client_filter import ClientFilter +from bot_graphql.filter.level_filter import LevelFilter +from bot_graphql.filter.server_filter import ServerFilter +from bot_graphql.filter.user_filter import UserFilter +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.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_mutation import UserMutation +from bot_graphql.queries.auto_role_query import AutoRoleQuery +from bot_graphql.queries.auto_role_rule_query import AutoRoleRuleQuery +from bot_graphql.queries.client_query import ClientQuery +from bot_graphql.queries.known_user_query import KnownUserQuery +from bot_graphql.queries.level_query import LevelQuery +from bot_graphql.queries.server_query import ServerQuery +from bot_graphql.queries.user_joined_server_query import UserJoinedServerQuery +from bot_graphql.queries.user_joined_voice_channel_query import UserJoinedVoiceChannelQuery +from bot_graphql.queries.user_query import UserQuery +from bot_graphql.query import Query +from bot_graphql.schema import Schema + + +class GraphQLModule(ModuleABC): + def __init__(self, dc: DiscordCollectionABC): + ModuleABC.__init__(self, dc, FeatureFlagsEnum.data_module) + + def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC): + pass + + def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC): + services.add_singleton(Schema) + services.add_singleton(GraphQLService) + services.add_singleton(Query) + services.add_singleton(Mutation) + + # queries + services.add_transient(QueryABC, AutoRoleQuery) + services.add_transient(QueryABC, AutoRoleRuleQuery) + services.add_transient(QueryABC, ClientQuery) + services.add_transient(QueryABC, KnownUserQuery) + services.add_transient(QueryABC, LevelQuery) + services.add_transient(QueryABC, ServerQuery) + services.add_transient(QueryABC, UserQuery) + services.add_transient(QueryABC, UserJoinedServerQuery) + services.add_transient(QueryABC, UserJoinedVoiceChannelQuery) + + # filters + services.add_singleton(FilterABC, AutoRoleFilter) + services.add_singleton(FilterABC, AutoRoleRuleFilter) + services.add_singleton(FilterABC, ClientFilter) + services.add_singleton(FilterABC, LevelFilter) + services.add_singleton(FilterABC, ServerFilter) + services.add_singleton(FilterABC, UserFilter) + services.add_singleton(FilterABC, UserJoinedServerFilter) + services.add_singleton(FilterABC, UserJoinedVoiceChannelFilter) + + # mutations + services.add_transient(QueryABC, AutoRoleMutation) + services.add_transient(QueryABC, AutoRoleRuleMutation) + services.add_transient(QueryABC, LevelMutation) + services.add_transient(QueryABC, UserMutation) + + services.add_transient(SeederService) diff --git a/kdb-bot/src/bot_graphql/graphql_service.py b/kdb-bot/src/bot_graphql/graphql_service.py new file mode 100644 index 00000000..699b57c6 --- /dev/null +++ b/kdb-bot/src/bot_graphql/graphql_service.py @@ -0,0 +1,6 @@ +from bot_graphql.abc.query_abc import QueryABC + + +class GraphQLService: + def __init__(self, queries: list[QueryABC]): + self._queries = queries diff --git a/kdb-bot/src/bot_graphql/model/autoRole.gql b/kdb-bot/src/bot_graphql/model/autoRole.gql new file mode 100644 index 00000000..0b523583 --- /dev/null +++ b/kdb-bot/src/bot_graphql/model/autoRole.gql @@ -0,0 +1,35 @@ +type AutoRole implements TableQuery { + id: ID + channelId: String + channelName: String + messageId: String + + server: Server + + autoRoleRuleCount: Int + autoRoleRules(filter: AutoRoleRuleFilter, page: Page, sort: Sort): [AutoRoleRule] + + createdAt: String + modifiedAt: String +} + +input AutoRoleFilter { + id: ID + channelId: String + channelName: String + messageId: String + server: ServerFilter +} + +type AutoRoleMutation { + createAutoRole(input: AutoRoleInput!): AutoRole + updateAutoRole(input: AutoRoleInput!): AutoRole + deleteAutoRole(id: ID): AutoRole +} + +input AutoRoleInput { + id: ID + channelId: String + messageId: String + serverId: ID +} \ No newline at end of file diff --git a/kdb-bot/src/bot_graphql/model/autoRoleRule.gql b/kdb-bot/src/bot_graphql/model/autoRoleRule.gql new file mode 100644 index 00000000..2484c8bd --- /dev/null +++ b/kdb-bot/src/bot_graphql/model/autoRoleRule.gql @@ -0,0 +1,32 @@ +type AutoRoleRule implements TableQuery { + id: ID + emojiName: String + roleId: String + roleName: String + + autoRole: AutoRole + + createdAt: String + modifiedAt: String +} + +input AutoRoleRuleFilter { + id: ID + emojiName: String + roleId: String + roleName: String + autoRole: AutoRoleFilter +} + +type AutoRoleRuleMutation { + createAutoRoleRule(input: AutoRoleRuleInput!): AutoRoleRule + updateAutoRoleRule(input: AutoRoleRuleInput!): AutoRoleRule + deleteAutoRoleRule(id: ID): AutoRoleRule +} + +input AutoRoleRuleInput { + id: ID + emojiName: String + roleId: String + autoRoleId: ID +} \ No newline at end of file diff --git a/kdb-bot/src/bot_graphql/model/base.gql b/kdb-bot/src/bot_graphql/model/base.gql new file mode 100644 index 00000000..1ae03045 --- /dev/null +++ b/kdb-bot/src/bot_graphql/model/base.gql @@ -0,0 +1,14 @@ +interface TableQuery { + createdAt: String + modifiedAt: String +} + +input Page { + pageIndex: Int + pageSize: Int +} + +input Sort { + sortDirection: String + sortColumn: String +} \ No newline at end of file diff --git a/kdb-bot/src/bot_graphql/model/client.gql b/kdb-bot/src/bot_graphql/model/client.gql new file mode 100644 index 00000000..8afc7c73 --- /dev/null +++ b/kdb-bot/src/bot_graphql/model/client.gql @@ -0,0 +1,22 @@ +type Client implements TableQuery { + id: ID + discordId: String + name: String + sentMessageCount: Int + receivedMessageCount: Int + deletedMessageCount: Int + receivedCommandCount: Int + movedUsersCount: Int + + server: Server + + createdAt: String + modifiedAt: String +} + +input ClientFilter { + id: ID + discordId: String + name: String + server: ServerFilter +} \ No newline at end of file diff --git a/kdb-bot/src/bot_graphql/model/knownUser.gql b/kdb-bot/src/bot_graphql/model/knownUser.gql new file mode 100644 index 00000000..bb96cd3d --- /dev/null +++ b/kdb-bot/src/bot_graphql/model/knownUser.gql @@ -0,0 +1,7 @@ +type KnownUser implements TableQuery { + id: ID + discordId: String + + createdAt: String + modifiedAt: String +} \ No newline at end of file diff --git a/kdb-bot/src/bot_graphql/model/level.gql b/kdb-bot/src/bot_graphql/model/level.gql new file mode 100644 index 00000000..2ef07540 --- /dev/null +++ b/kdb-bot/src/bot_graphql/model/level.gql @@ -0,0 +1,33 @@ +type Level implements TableQuery { + id: ID + name: String + color: String + minXp: Int + permissions: String + + server: Server + + createdAt: String + modifiedAt: String +} + +input LevelFilter { + id: ID + name: String + server: ServerFilter +} + +type LevelMutation { + createLevel(input: LevelInput!): Level + updateLevel(input: LevelInput!): Level + deleteLevel(id: ID): Level +} + +input LevelInput { + id: ID + name: String + color: String + minXp: Int + permissions: 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 new file mode 100644 index 00000000..5290dd1c --- /dev/null +++ b/kdb-bot/src/bot_graphql/model/mutation.gql @@ -0,0 +1,6 @@ +type Mutation { + autoRole: AutoRoleMutation + autoRoleRule: AutoRoleRuleMutation + level: LevelMutation + user: UserMutation +} \ 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 new file mode 100644 index 00000000..46f80381 --- /dev/null +++ b/kdb-bot/src/bot_graphql/model/query.gql @@ -0,0 +1,28 @@ +type Query { + autoRoleCount: Int + autoRoles(filter: AutoRoleFilter, page: Page, sort: Sort): [AutoRole] + + autoRoleRuleCount: Int + autoRoleRules(filter: AutoRoleRuleFilter, page: Page, sort: Sort): [AutoRoleRule] + + clientCount: Int + clients(filter: ClientFilter, page: Page, sort: Sort): [Client] + + knownUserCount: Int + knownUsers: [KnownUser] + + levelCount: Int + levels(filter: LevelFilter, page: Page, sort: Sort): [Level] + + serverCount: Int + servers(filter: ServerFilter, page: Page, sort: Sort): [Server] + + userJoinedServerCount: Int + userJoinedServers(filter: UserJoinedServerFilter, page: Page, sort: Sort): [User] + + userJoinedVoiceChannelCount: Int + userJoinedVoiceChannels(filter: UserJoinedVoiceChannelFilter, page: Page, sort: Sort): [User] + + userCount: Int + users(filter: UserFilter, page: Page, sort: Sort): [User] +} \ No newline at end of file diff --git a/kdb-bot/src/bot_graphql/model/server.gql b/kdb-bot/src/bot_graphql/model/server.gql new file mode 100644 index 00000000..04047892 --- /dev/null +++ b/kdb-bot/src/bot_graphql/model/server.gql @@ -0,0 +1,26 @@ +type Server implements TableQuery { + id: ID + discordId: String + name: String + + autoRoleCount: Int + autoRoles(filter: AutoRoleFilter, page: Page, sort: Sort): [AutoRole] + + clientCount: Int + clients(filter: ClientFilter, page: Page, sort: Sort): [Client] + + levelCount: Int + levels(filter: LevelFilter, page: Page, sort: Sort): [Level] + + userCount: Int + users(filter: UserFilter, page: Page, sort: Sort): [User] + + createdAt: String + modifiedAt: String +} + +input ServerFilter { + id: ID + discordId: String + name: String +} \ No newline at end of file diff --git a/kdb-bot/src/bot_graphql/model/user.gql b/kdb-bot/src/bot_graphql/model/user.gql new file mode 100644 index 00000000..07f7acc4 --- /dev/null +++ b/kdb-bot/src/bot_graphql/model/user.gql @@ -0,0 +1,38 @@ +type User implements TableQuery { + id: ID + discordId: String + name: String + xp: Int + ontime: Float + level: Level + + joinedServers(filter: UserJoinedServerFilter, page: Page, sort: Sort): [UserJoinedServer] + joinedServerCount: Int + + joinedVoiceChannels(filter: UserJoinedVoiceChannelFilter, page: Page, sort: Sort): [UserJoinedVoiceChannel] + joinedVoiceChannelCount: Int + + server: Server + + createdAt: String + modifiedAt: String +} + +input UserFilter { + id: ID + discordId: String + name: String + xp: Int + ontime: Float + level: LevelFilter + server: ServerFilter +} + +type UserMutation { + updateUser(input: UserInput!): User +} + +input UserInput { + id: ID + xp: Int +} \ No newline at end of file diff --git a/kdb-bot/src/bot_graphql/model/userJoinedServer.gql b/kdb-bot/src/bot_graphql/model/userJoinedServer.gql new file mode 100644 index 00000000..a8cbb343 --- /dev/null +++ b/kdb-bot/src/bot_graphql/model/userJoinedServer.gql @@ -0,0 +1,16 @@ +type UserJoinedServer implements TableQuery { + id: ID + user: User + joinedOn: String + leavedOn: String + + createdAt: String + modifiedAt: String +} + +input UserJoinedServerFilter { + id: ID + user: UserFilter + joinedOn: String + leavedOn: String +} \ No newline at end of file diff --git a/kdb-bot/src/bot_graphql/model/userJoinedVoiceChannel.gql b/kdb-bot/src/bot_graphql/model/userJoinedVoiceChannel.gql new file mode 100644 index 00000000..d49f8c9e --- /dev/null +++ b/kdb-bot/src/bot_graphql/model/userJoinedVoiceChannel.gql @@ -0,0 +1,20 @@ +type UserJoinedVoiceChannel implements TableQuery { + id: ID + channelId: String + channelName: String + user: User + joinedOn: String + leavedOn: String + + createdAt: String + modifiedAt: String +} + +input UserJoinedVoiceChannelFilter { + id: ID + channelId: String + channelName: String + user: UserFilter + joinedOn: String + leavedOn: String +} \ No newline at end of file diff --git a/kdb-bot/src/bot_graphql/mutation.py b/kdb-bot/src/bot_graphql/mutation.py new file mode 100644 index 00000000..5b980c14 --- /dev/null +++ b/kdb-bot/src/bot_graphql/mutation.py @@ -0,0 +1,39 @@ +from ariadne import MutationType + +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_mutation import UserMutation + + +class Mutation(MutationType): + def __init__( + self, + auto_role_mutation: AutoRoleMutation, + auto_role_rule_mutation: AutoRoleRuleMutation, + level_mutation: LevelMutation, + user_mutation: UserMutation, + ): + MutationType.__init__(self) + + self._auto_role_mutation = auto_role_mutation + self._auto_role_rule_mutation = auto_role_rule_mutation + self._level_mutation = level_mutation + self._user_mutation = user_mutation + + self.set_field("autoRole", self.resolve_auto_role) + self.set_field("autoRoleRule", self.resolve_auto_role_rule) + self.set_field("level", self.resolve_level) + self.set_field("user", self.resolve_user) + + def resolve_auto_role(self, *_): + return self._auto_role_mutation + + def resolve_auto_role_rule(self, *_): + return self._auto_role_rule_mutation + + def resolve_level(self, *_): + return self._level_mutation + + def resolve_user(self, *_): + return self._user_mutation diff --git a/kdb-bot/src/bot_graphql/mutations/__init__.py b/kdb-bot/src/bot_graphql/mutations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/kdb-bot/src/bot_graphql/mutations/auto_role_mutation.py b/kdb-bot/src/bot_graphql/mutations/auto_role_mutation.py new file mode 100644 index 00000000..283b6105 --- /dev/null +++ b/kdb-bot/src/bot_graphql/mutations/auto_role_mutation.py @@ -0,0 +1,55 @@ +from cpl_core.database.context import DatabaseContextABC + +from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC +from bot_data.abc.server_repository_abc import ServerRepositoryABC +from bot_data.model.auto_role import AutoRole +from bot_graphql.abc.query_abc import QueryABC + + +class AutoRoleMutation(QueryABC): + def __init__( + self, + servers: ServerRepositoryABC, + auto_roles: AutoRoleRepositoryABC, + db: DatabaseContextABC, + ): + QueryABC.__init__(self, "AutoRoleMutation") + + self._servers = servers + self._auto_roles = auto_roles + self._db = db + + self.set_field("createAutoRole", self.resolve_create_auto_role) + self.set_field("updateAutoRole", self.resolve_update_auto_role) + self.set_field("deleteAutoRole", self.resolve_delete_auto_role) + + def resolve_create_auto_role(self, *_, input: dict): + auto_role = AutoRole(self._servers.get_server_by_id(input["serverId"]), input["channelId"], input["messageId"]) + self._auto_roles.add_auto_role(auto_role) + self._db.save_changes() + + def get_new(x: AutoRole): + return ( + x.server.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() + + def resolve_update_auto_role(self, *_, input: dict): + auto_role = self._auto_roles.get_auto_role_by_id(input["id"]) + auto_role.discord_channel_id = input["channelId"] if "channelId" in input else auto_role.discord_channel_id + auto_role.discord_message_id = input["messageId"] if "messageId" in input else auto_role.discord_message_id + + self._auto_roles.update_auto_role(auto_role) + self._db.save_changes() + + auto_role = self._auto_roles.get_auto_role_by_id(input["id"]) + return auto_role + + def resolve_delete_auto_role(self, *_, id: int): + auto_role = self._auto_roles.get_auto_role_by_id(id) + self._auto_roles.delete_auto_role(auto_role) + self._db.save_changes() + return auto_role diff --git a/kdb-bot/src/bot_graphql/mutations/auto_role_rule_mutation.py b/kdb-bot/src/bot_graphql/mutations/auto_role_rule_mutation.py new file mode 100644 index 00000000..34935bbf --- /dev/null +++ b/kdb-bot/src/bot_graphql/mutations/auto_role_rule_mutation.py @@ -0,0 +1,61 @@ +from cpl_core.database.context import DatabaseContextABC + +from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC +from bot_data.abc.server_repository_abc import ServerRepositoryABC +from bot_data.model.auto_role_rule import AutoRoleRule +from bot_graphql.abc.query_abc import QueryABC + + +class AutoRoleRuleMutation(QueryABC): + def __init__( + self, + servers: ServerRepositoryABC, + auto_roles: AutoRoleRepositoryABC, + db: DatabaseContextABC, + ): + QueryABC.__init__(self, "AutoRoleRuleMutation") + + self._servers = servers + self._auto_roles = auto_roles + self._db = db + + self.set_field("createAutoRoleRule", self.resolve_create_auto_role_rule) + self.set_field("updateAutoRoleRule", self.resolve_update_auto_role_rule) + self.set_field("deleteAutoRoleRule", self.resolve_delete_auto_role_rule) + + def resolve_create_auto_role_rule(self, *_, input: dict): + auto_role_rule = AutoRoleRule( + self._auto_roles.get_auto_role_by_id(input["autoRoleId"]), input["emojiName"], input["roleId"] + ) + self._auto_roles.add_auto_role_rule(auto_role_rule) + self._db.save_changes() + + def get_new(x: AutoRoleRule): + return ( + x.auto_role.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() + ) + + def resolve_update_auto_role_rule(self, *_, input: dict): + auto_role_rule = self._auto_roles.get_auto_role_rule_by_id(input["id"]) + auto_role_rule.emoji_name = input["emojiName"] if "emojiName" in input else auto_role_rule.emoji_name + auto_role_rule.role_id = input["roleId"] if "roleId" in input else auto_role_rule.role_id + + self._auto_roles.update_auto_role_rule(auto_role_rule) + self._db.save_changes() + + auto_role_rule = self._auto_roles.get_auto_role_rule_by_id(input["id"]) + return auto_role_rule + + def resolve_delete_auto_role_rule(self, *_, id: int): + auto_role_rule = self._auto_roles.get_auto_role_rule_by_id(id) + self._auto_roles.delete_auto_role_rule(auto_role_rule) + self._db.save_changes() + return auto_role_rule diff --git a/kdb-bot/src/bot_graphql/mutations/level_mutation.py b/kdb-bot/src/bot_graphql/mutations/level_mutation.py new file mode 100644 index 00000000..0557c968 --- /dev/null +++ b/kdb-bot/src/bot_graphql/mutations/level_mutation.py @@ -0,0 +1,64 @@ +from cpl_core.database.context import DatabaseContextABC + +from bot_data.abc.level_repository_abc import LevelRepositoryABC +from bot_data.abc.server_repository_abc import ServerRepositoryABC +from bot_data.model.level import Level +from bot_graphql.abc.query_abc import QueryABC + + +class LevelMutation(QueryABC): + def __init__( + self, + servers: ServerRepositoryABC, + levels: LevelRepositoryABC, + db: DatabaseContextABC, + ): + QueryABC.__init__(self, "LevelMutation") + + self._servers = servers + self._levels = levels + self._db = db + + self.set_field("createLevel", self.resolve_create_level) + self.set_field("updateLevel", self.resolve_update_level) + self.set_field("deleteLevel", self.resolve_delete_level) + + def resolve_create_level(self, *_, input: dict): + level = Level( + input["name"], + input["color"], + int(input["minXp"]), + int(input["permissions"]), + self._servers.get_server_by_id(input["serverId"]), + ) + self._levels.add_level(level) + self._db.save_changes() + + def get_new_level(l: Level): + return ( + l.name == level.name + and l.color == level.color + and l.min_xp == level.min_xp + and l.permissions == level.permissions + ) + + return self._levels.get_levels_by_server_id(level.server.server_id).where(get_new_level).last() + + def resolve_update_level(self, *_, input: dict): + level = self._levels.get_level_by_id(input["id"]) + level.name = input["name"] if "name" in input else level.name + level.color = input["color"] if "color" in input else level.color + level.min_xp = input["minXp"] if "minXp" in input else level.min_xp + level.permissions = input["permissions"] if "permissions" in input else level.permissions + + self._levels.update_level(level) + self._db.save_changes() + + level = self._levels.get_level_by_id(input["id"]) + return level + + def resolve_delete_level(self, *_, id: int): + level = self._levels.get_level_by_id(id) + self._levels.delete_level(level) + self._db.save_changes() + return level diff --git a/kdb-bot/src/bot_graphql/mutations/user_mutation.py b/kdb-bot/src/bot_graphql/mutations/user_mutation.py new file mode 100644 index 00000000..1e90cd83 --- /dev/null +++ b/kdb-bot/src/bot_graphql/mutations/user_mutation.py @@ -0,0 +1,31 @@ +from cpl_core.database.context import DatabaseContextABC + +from bot_data.abc.server_repository_abc import ServerRepositoryABC +from bot_data.abc.user_repository_abc import UserRepositoryABC +from bot_graphql.abc.query_abc import QueryABC + + +class UserMutation(QueryABC): + def __init__( + self, + servers: ServerRepositoryABC, + users: UserRepositoryABC, + db: DatabaseContextABC, + ): + QueryABC.__init__(self, "UserMutation") + + self._servers = servers + self._users = users + self._db = db + + self.set_field("updateUser", self.resolve_update_user) + + def resolve_update_user(self, *_, input: dict): + user = self._users.get_user_by_id(input["id"]) + user.xp = input["xp"] if "xp" in input else user.xp + + self._users.update_user(user) + self._db.save_changes() + + user = self._users.get_user_by_id(input["id"]) + return user diff --git a/kdb-bot/src/bot_graphql/queries/__init__.py b/kdb-bot/src/bot_graphql/queries/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/kdb-bot/src/bot_graphql/queries/auto_role_query.py b/kdb-bot/src/bot_graphql/queries/auto_role_query.py new file mode 100644 index 00000000..53a2b97c --- /dev/null +++ b/kdb-bot/src/bot_graphql/queries/auto_role_query.py @@ -0,0 +1,52 @@ +from cpl_discord.service import DiscordBotServiceABC + +from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC +from bot_data.abc.server_repository_abc import ServerRepositoryABC +from bot_data.model.auto_role import AutoRole +from bot_graphql.abc.data_query_abc import DataQueryABC +from bot_graphql.filter.server_filter import ServerFilter + + +class AutoRoleQuery(DataQueryABC): + def __init__( + self, + bot: DiscordBotServiceABC, + auto_role_rules: AutoRoleRepositoryABC, + servers: ServerRepositoryABC, + ): + DataQueryABC.__init__(self, "AutoRole") + + self._bot = bot + self._auto_role_rules = auto_role_rules + self._servers = servers + + self.set_field("id", self.resolve_id) + self.set_field("channelId", self.resolve_channel_id) + self.set_field("channelName", self.resolve_channel_name) + self.set_field("messageId", self.resolve_message_id) + 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) + ) + + @staticmethod + def resolve_id(x: AutoRole, *_): + return x.auto_role_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_message_id(x: AutoRole, *_): + return x.discord_message_id + + 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 self._servers.get_server_by_id(x.server.server_id) 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 new file mode 100644 index 00000000..5103aec4 --- /dev/null +++ b/kdb-bot/src/bot_graphql/queries/auto_role_rule_query.py @@ -0,0 +1,42 @@ +from cpl_discord.service import DiscordBotServiceABC + +from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC +from bot_data.model.auto_role_rule import AutoRoleRule +from bot_graphql.abc.data_query_abc import DataQueryABC + + +class AutoRoleRuleQuery(DataQueryABC): + def __init__( + self, + bot: DiscordBotServiceABC, + auto_roles: AutoRoleRepositoryABC, + ): + DataQueryABC.__init__(self, "AutoRoleRule") + + self._bot = bot + self._auto_roles = auto_roles + + self.set_field("id", self.resolve_id) + self.set_field("emojiName", self.resolve_emoji_name) + self.set_field("roleId", self.resolve_role_id) + self.set_field("roleName", self.resolve_role_name) + self.set_field("autoRole", self.resolve_auto_role) + + @staticmethod + def resolve_id(x: AutoRoleRule, *_): + return x.auto_role_rule_id + + @staticmethod + def resolve_emoji_name(x: AutoRoleRule, *_): + return x.emoji_name + + @staticmethod + 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 + + def resolve_auto_role(self, x: AutoRoleRule, *_): + return self._auto_roles.get_auto_role_by_id(x.auto_role.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 new file mode 100644 index 00000000..824afa9b --- /dev/null +++ b/kdb-bot/src/bot_graphql/queries/client_query.py @@ -0,0 +1,59 @@ +from cpl_discord.service import DiscordBotServiceABC + +from bot_data.model.client import Client +from bot_graphql.abc.data_query_abc import DataQueryABC + + +class ClientQuery(DataQueryABC): + def __init__( + self, + bot: DiscordBotServiceABC, + ): + DataQueryABC.__init__(self, "Client") + + self._bot = bot + + self.set_field("id", self.resolve_id) + self.set_field("discordId", self.resolve_discord_id) + self.set_field("name", self.resolve_name) + self.set_field("sentMessageCount", self.resolve_sent_message_count) + self.set_field("receivedMessageCount", self.resolve_received_message_count) + self.set_field("deletedMessageCount", self.resolve_deleted_message_count) + self.set_field("receivedCommandCount", self.resolve_received_command_count) + self.set_field("movedUsersCount", self.resolve_moved_users_count) + self.set_field("server", self.resolve_server) + + @staticmethod + def resolve_id(client: Client, *_): + return client.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_sent_message_count(client: Client, *_): + return client.sent_message_count + + @staticmethod + def resolve_received_message_count(client: Client, *_): + return client.received_command_count + + @staticmethod + def resolve_deleted_message_count(client: Client, *_): + return client.deleted_message_count + + @staticmethod + def resolve_received_command_count(client: Client, *_): + return client.received_command_count + + @staticmethod + def resolve_moved_users_count(client: Client, *_): + return client.moved_users_count + + @staticmethod + def resolve_server(client: Client, *_): + return client.server diff --git a/kdb-bot/src/bot_graphql/queries/known_user_query.py b/kdb-bot/src/bot_graphql/queries/known_user_query.py new file mode 100644 index 00000000..243a6745 --- /dev/null +++ b/kdb-bot/src/bot_graphql/queries/known_user_query.py @@ -0,0 +1,18 @@ +from bot_data.model.known_user import KnownUser +from bot_graphql.abc.data_query_abc import DataQueryABC + + +class KnownUserQuery(DataQueryABC): + def __init__(self): + DataQueryABC.__init__(self, "KnownUser") + + self.set_field("id", self.resolve_id) + self.set_field("discordId", self.resolve_discord_id) + + @staticmethod + def resolve_id(x: KnownUser, *_): + return x.known_user_id + + @staticmethod + def resolve_discord_id(x: KnownUser, *_): + return x.discord_id diff --git a/kdb-bot/src/bot_graphql/queries/level_query.py b/kdb-bot/src/bot_graphql/queries/level_query.py new file mode 100644 index 00000000..a0f22453 --- /dev/null +++ b/kdb-bot/src/bot_graphql/queries/level_query.py @@ -0,0 +1,38 @@ +from bot_data.model.level import Level +from bot_graphql.abc.data_query_abc import DataQueryABC + + +class LevelQuery(DataQueryABC): + def __init__(self): + DataQueryABC.__init__(self, "Level") + + self.set_field("id", self.resolve_id) + self.set_field("name", self.resolve_name) + self.set_field("color", self.resolve_color) + self.set_field("minXp", self.resolve_min_xp) + self.set_field("permissions", self.resolve_permissions) + self.set_field("server", self.resolve_server) + + @staticmethod + def resolve_id(level: Level, *_): + return level.id + + @staticmethod + def resolve_name(level: Level, *_): + return level.name + + @staticmethod + def resolve_color(level: Level, *_): + return level.color + + @staticmethod + def resolve_min_xp(level: Level, *_): + return level.min_xp + + @staticmethod + def resolve_permissions(level: Level, *_): + return level.permissions + + @staticmethod + def resolve_server(level: Level, *_): + return level.server diff --git a/kdb-bot/src/bot_graphql/queries/server_query.py b/kdb-bot/src/bot_graphql/queries/server_query.py new file mode 100644 index 00000000..33fff047 --- /dev/null +++ b/kdb-bot/src/bot_graphql/queries/server_query.py @@ -0,0 +1,56 @@ +from cpl_discord.service import DiscordBotServiceABC + +from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC +from bot_data.abc.client_repository_abc import ClientRepositoryABC +from bot_data.abc.level_repository_abc import LevelRepositoryABC +from bot_data.abc.user_joined_server_repository_abc import UserJoinedServerRepositoryABC +from bot_data.abc.user_joined_voice_channel_repository_abc import UserJoinedVoiceChannelRepositoryABC +from bot_data.abc.user_repository_abc import UserRepositoryABC +from bot_data.model.server import Server +from bot_graphql.abc.data_query_abc import DataQueryABC +from bot_graphql.filter.user_filter import UserFilter + + +class ServerQuery(DataQueryABC): + def __init__( + self, + bot: DiscordBotServiceABC, + auto_roles: AutoRoleRepositoryABC, + clients: ClientRepositoryABC, + levels: LevelRepositoryABC, + users: UserRepositoryABC, + ujs: UserJoinedServerRepositoryABC, + ujvs: UserJoinedVoiceChannelRepositoryABC, + ): + DataQueryABC.__init__(self, "Server") + + self._bot = bot + self._auto_roles = auto_roles + self._clients = clients + self._levels = levels + self._users = users + self._ujs = ujs + self._ujvs = ujvs + + self.set_field("id", self.resolve_id) + self.set_field("discordId", self.resolve_discord_id) + self.set_field("name", self.resolve_name) + + self.add_collection( + "autoRole", lambda server, *_: self._auto_roles.get_auto_roles_by_server_id(server.server_id) + ) + self.add_collection("client", lambda server, *_: self._clients.get_clients_by_server_id(server.server_id)) + self.add_collection("level", lambda server, *_: self._levels.get_levels_by_server_id(server.server_id)) + self.add_collection("user", lambda server, *_: self._users.get_users_by_server_id(server.server_id), UserFilter) + + @staticmethod + def resolve_id(server: Server, *_): + return server.server_id + + @staticmethod + def resolve_discord_id(server: Server, *_): + return server.discord_server_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 diff --git a/kdb-bot/src/bot_graphql/queries/user_joined_server_query.py b/kdb-bot/src/bot_graphql/queries/user_joined_server_query.py new file mode 100644 index 00000000..db18781a --- /dev/null +++ b/kdb-bot/src/bot_graphql/queries/user_joined_server_query.py @@ -0,0 +1,28 @@ +from bot_data.model.user_joined_server import UserJoinedServer +from bot_graphql.abc.data_query_abc import DataQueryABC + + +class UserJoinedServerQuery(DataQueryABC): + def __init__(self): + DataQueryABC.__init__(self, "UserJoinedServer") + + self.set_field("id", self.resolve_id) + self.set_field("user", self.resolve_user) + self.set_field("joinedOn", self.resolve_joined_on) + self.set_field("leavedOn", self.resolve_leaved_on) + + @staticmethod + def resolve_id(x: UserJoinedServer, *_): + return x.join_id + + @staticmethod + def resolve_user(x: UserJoinedServer, *_): + return x.user + + @staticmethod + def resolve_joined_on(x: UserJoinedServer, *_): + return x.joined_on + + @staticmethod + def resolve_leaved_on(x: UserJoinedServer, *_): + return x.leaved_on 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 new file mode 100644 index 00000000..99bcc0c3 --- /dev/null +++ b/kdb-bot/src/bot_graphql/queries/user_joined_voice_channel_query.py @@ -0,0 +1,41 @@ +from cpl_discord.service import DiscordBotServiceABC + +from bot_data.model.user_joined_voice_channel import UserJoinedVoiceChannel +from bot_graphql.abc.data_query_abc import DataQueryABC + + +class UserJoinedVoiceChannelQuery(DataQueryABC): + def __init__(self, bot: DiscordBotServiceABC): + DataQueryABC.__init__(self, "UserJoinedVoiceChannel") + + self._bot = bot + + self.set_field("id", self.resolve_id) + 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("joinedOn", self.resolve_joined_on) + self.set_field("leavedOn", self.resolve_leaved_on) + + @staticmethod + def resolve_id(x: UserJoinedVoiceChannel, *_): + return x.join_id + + @staticmethod + def resolve_channel_id(x: UserJoinedVoiceChannel, *_): + return x.dc_channel_id + + def resolve_channel_name(self, x: UserJoinedVoiceChannel, *_): + return self._bot.get_channel(x.dc_channel_id).name + + @staticmethod + def resolve_user(x: UserJoinedVoiceChannel, *_): + return x.user + + @staticmethod + def resolve_joined_on(x: UserJoinedVoiceChannel, *_): + return x.joined_on + + @staticmethod + def resolve_leaved_on(x: UserJoinedVoiceChannel, *_): + return x.leaved_on diff --git a/kdb-bot/src/bot_graphql/queries/user_query.py b/kdb-bot/src/bot_graphql/queries/user_query.py new file mode 100644 index 00000000..7bca0379 --- /dev/null +++ b/kdb-bot/src/bot_graphql/queries/user_query.py @@ -0,0 +1,65 @@ +from cpl_discord.service import DiscordBotServiceABC + +from bot_core.abc.client_utils_abc import ClientUtilsABC +from bot_data.abc.user_joined_server_repository_abc import UserJoinedServerRepositoryABC +from bot_data.abc.user_joined_voice_channel_repository_abc import UserJoinedVoiceChannelRepositoryABC +from bot_data.model.user import User +from bot_graphql.abc.data_query_abc import DataQueryABC +from modules.level.service.level_service import LevelService + + +class UserQuery(DataQueryABC): + def __init__( + self, + bot: DiscordBotServiceABC, + levels: LevelService, + client_utils: ClientUtilsABC, + ujs: UserJoinedServerRepositoryABC, + ujvs: UserJoinedVoiceChannelRepositoryABC, + ): + DataQueryABC.__init__(self, "User") + + self._bot = bot + self._levels = levels + self._client_utils = client_utils + self._ujs = ujs + self._ujvs = ujvs + + self.set_field("id", self.resolve_id) + self.set_field("discordId", self.resolve_discord_id) + self.set_field("name", self.resolve_name) + self.set_field("xp", self.resolve_xp) + self.set_field("ontime", self.resolve_ontime) + 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)) + self.add_collection( + "joinedVoiceChannel", lambda user, *_: self._ujvs.get_user_joined_voice_channels_by_user_id(user.user_id) + ) + self.set_field("server", self.resolve_server) + + @staticmethod + def resolve_id(user: User, *_): + return user.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_xp(user: User, *_): + return user.xp + + def resolve_ontime(self, user: User, *_): + return self._client_utils.get_ontime_for_user(user) + + def resolve_level(self, user: User, *_): + return self._levels.get_level(user) + + @staticmethod + def resolve_server(user: User, *_): + return user.server diff --git a/kdb-bot/src/bot_graphql/query.py b/kdb-bot/src/bot_graphql/query.py new file mode 100644 index 00000000..9c574ebc --- /dev/null +++ b/kdb-bot/src/bot_graphql/query.py @@ -0,0 +1,49 @@ +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 +from bot_data.abc.level_repository_abc import LevelRepositoryABC +from bot_data.abc.server_repository_abc import ServerRepositoryABC +from bot_data.abc.user_joined_server_repository_abc import UserJoinedServerRepositoryABC +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.auto_role_filter import AutoRoleFilter +from bot_graphql.filter.auto_role_rule_filter import AutoRoleRuleFilter +from bot_graphql.filter.level_filter import LevelFilter +from bot_graphql.filter.server_filter import ServerFilter +from bot_graphql.filter.user_filter import UserFilter + + +class Query(QueryABC): + def __init__( + self, + auto_roles: AutoRoleRepositoryABC, + clients: ClientRepositoryABC, + known_users: KnownUserRepositoryABC, + levels: LevelRepositoryABC, + servers: ServerRepositoryABC, + user_joined_servers: UserJoinedServerRepositoryABC, + user_joined_voice_channel: UserJoinedVoiceChannelRepositoryABC, + users: UserRepositoryABC, + ): + QueryABC.__init__(self, "Query") + self._auto_roles = auto_roles + self._clients = clients + self._known_users = known_users + self._levels = levels + self._servers = servers + self._user_joined_servers = user_joined_servers + self._user_joined_voice_channels = user_joined_voice_channel + self._users = users + + self.add_collection("autoRole", lambda *_: self._auto_roles.get_auto_roles(), AutoRoleFilter) + self.add_collection("autoRoleRule", lambda *_: self._auto_roles.get_auto_role_rules(), AutoRoleRuleFilter) + self.add_collection("client", lambda *_: self._clients.get_clients()) + self.add_collection("knownUser", lambda *_: self._known_users.get_users()) + self.add_collection("level", lambda *_: self._levels.get_levels(), LevelFilter) + self.add_collection("server", lambda *_: self._servers.get_servers(), ServerFilter) + self.add_collection("userJoinedServer", lambda *_: self._user_joined_servers.get_user_joined_servers()) + self.add_collection( + "userJoinedVoiceChannel", lambda *_: self._user_joined_voice_channels.get_user_joined_voice_channels() + ) + self.add_collection("user", lambda *_: self._users.get_users(), UserFilter) diff --git a/kdb-bot/src/bot_graphql/schema.py b/kdb-bot/src/bot_graphql/schema.py new file mode 100644 index 00000000..d2972a78 --- /dev/null +++ b/kdb-bot/src/bot_graphql/schema.py @@ -0,0 +1,18 @@ +import os + +from ariadne import make_executable_schema, load_schema_from_path +from graphql import GraphQLSchema + +from bot_graphql.abc.query_abc import QueryABC +from bot_graphql.mutation import Mutation +from bot_graphql.query import Query + + +class Schema: + def __init__(self, query: Query, mutation: Mutation, queries: list[QueryABC]): + type_defs = load_schema_from_path(os.path.join(os.path.dirname(os.path.realpath(__file__)), "model/")) + self._schema = make_executable_schema(type_defs, query, mutation, *queries) + + @property + def schema(self) -> GraphQLSchema: + return self._schema diff --git a/kdb-bot/src/modules/auto_role/command/auto_role_group.py b/kdb-bot/src/modules/auto_role/command/auto_role_group.py index 947dc8bd..bde66962 100644 --- a/kdb-bot/src/modules/auto_role/command/auto_role_group.py +++ b/kdb-bot/src/modules/auto_role/command/auto_role_group.py @@ -1,9 +1,8 @@ -from typing import List as TList, Optional, Any +from typing import List as TList import discord from cpl_core.database.context import DatabaseContextABC from cpl_discord.command import DiscordCommandABC -from cpl_discord.container import TextChannel from cpl_discord.service import DiscordBotServiceABC from cpl_query.extension import List from cpl_translation import TranslatePipe @@ -138,10 +137,10 @@ class AutoRoleGroup(DiscordCommandABC): self._logger.trace(__name__, f"Finished command auto-role add") return - server_id = self._servers.get_server_by_discord_id(ctx.guild.id).server_id - self._auto_roles.add_auto_role(AutoRole(server_id, int(channel.id), int(message_id))) + server = self._servers.get_server_by_discord_id(ctx.guild.id) + self._auto_roles.add_auto_role(AutoRole(server, int(channel.id), int(message_id))) self._db_context.save_changes() - self._logger.info(__name__, f"Saved auto-role for message {message_id} at server {server_id}") + self._logger.info(__name__, f"Saved auto-role for message {message_id} at server {server}") await self._message_service.send_ctx_msg( ctx, self._t.transform("modules.auto_role.add.success").format(message_id) ) diff --git a/kdb-bot/src/modules/stats/ui/add_statistic_form.py b/kdb-bot/src/modules/stats/ui/add_statistic_form.py index 0688aef6..e07502e2 100644 --- a/kdb-bot/src/modules/stats/ui/add_statistic_form.py +++ b/kdb-bot/src/modules/stats/ui/add_statistic_form.py @@ -12,7 +12,6 @@ from bot_data.model.statistic import Statistic class AddStatisticForm(ui.Modal): - description = ui.TextInput(label="Beschreibung", required=True) code = ui.TextInput(label="Code", required=True, style=TextStyle.long) diff --git a/kdb-bot/tools/post_build/service/remove_config.py b/kdb-bot/tools/post_build/service/remove_config.py index ab8b9d47..60370937 100644 --- a/kdb-bot/tools/post_build/service/remove_config.py +++ b/kdb-bot/tools/post_build/service/remove_config.py @@ -16,7 +16,6 @@ class RemoveConfig: build: BuildSettings, post_build: PostBuildSettings, ): - self._env = env self._workspace = ws self._project = project